Skip to content

Commit eb04f62

Browse files
committed
docs
1 parent 264e346 commit eb04f62

8 files changed

+321
-18
lines changed

docs/combinations.md

Lines changed: 184 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ VerifyCombinations allows all combinations of the given input lists to be execut
1515
<!-- snippet: CombinationTargetMethod -->
1616
<a id='snippet-CombinationTargetMethod'></a>
1717
```cs
18-
public string BuildAddress(int streetNumber, string street, string city)
18+
public static string BuildAddress(int streetNumber, string street, string city)
1919
{
2020
ArgumentException.ThrowIfNullOrWhiteSpace(street);
2121
ArgumentException.ThrowIfNullOrWhiteSpace(city);
@@ -24,7 +24,7 @@ public string BuildAddress(int streetNumber, string street, string city)
2424
return $"{streetNumber} {street}, {city}";
2525
}
2626
```
27-
<sup><a href='/src/Verify.Tests/VerifyCombinationsSample.cs#L5-L16' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationTargetMethod' title='Start of snippet'>anchor</a></sup>
27+
<sup><a href='/src/Verify.Tests/VerifyCombinationsSample.cs#L6-L17' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationTargetMethod' title='Start of snippet'>anchor</a></sup>
2828
<!-- endSnippet -->
2929

3030

@@ -46,7 +46,7 @@ public Task BuildAddressTest()
4646
cities);
4747
}
4848
```
49-
<sup><a href='/src/Verify.Tests/VerifyCombinationsSample.cs#L18-L33' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample' title='Start of snippet'>anchor</a></sup>
49+
<sup><a href='/src/Verify.Tests/VerifyCombinationsSample.cs#L19-L34' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample' title='Start of snippet'>anchor</a></sup>
5050
<!-- endSnippet -->
5151

5252

@@ -70,11 +70,19 @@ public Task BuildAddressTest()
7070
<!-- endSnippet -->
7171

7272

73+
## Column Alignment
74+
75+
Key value are aligned based on type.
76+
77+
* Numbers (int, double, float etc) are aligned right
78+
* All other types are aligned left
79+
80+
7381
## CaptureExceptions
7482

7583
By default exceptions are not captured.
7684

77-
To enable exception capture use `captureExceptions = true`
85+
To enable exception capture use `captureExceptions = true`:
7886

7987
<!-- snippet: CombinationSample_CaptureExceptions -->
8088
<a id='snippet-CombinationSample_CaptureExceptions'></a>
@@ -93,7 +101,7 @@ public Task BuildAddressExceptionsTest()
93101
captureExceptions: true);
94102
}
95103
```
96-
<sup><a href='/src/Verify.Tests/VerifyCombinationsSample.cs#L35-L51' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CaptureExceptions' title='Start of snippet'>anchor</a></sup>
104+
<sup><a href='/src/Verify.Tests/VerifyCombinationsSample.cs#L53-L69' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CaptureExceptions' title='Start of snippet'>anchor</a></sup>
97105
<!-- endSnippet -->
98106

99107

@@ -194,5 +202,175 @@ public Task BuildAddressExceptionsDisabledTest()
194202
captureExceptions: false);
195203
}
196204
```
197-
<sup><a href='/src/StaticSettingsTests/VerifyCombinationsTests.cs#L68-L84' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CaptureExceptionsFalse' title='Start of snippet'>anchor</a></sup>
205+
<sup><a href='/src/StaticSettingsTests/VerifyCombinationsTests.cs#L69-L85' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CaptureExceptionsFalse' title='Start of snippet'>anchor</a></sup>
206+
<!-- endSnippet -->
207+
208+
209+
## Result serialization
210+
211+
Serialization of results is done using `CombinationResultsConverter`
212+
213+
<!-- snippet: CombinationResultsConverter.cs -->
214+
<a id='snippet-CombinationResultsConverter.cs'></a>
215+
```cs
216+
namespace VerifyTests;
217+
218+
public class CombinationResultsConverter :
219+
WriteOnlyJsonConverter<CombinationResults>
220+
{
221+
public override void Write(VerifyJsonWriter writer, CombinationResults results)
222+
{
223+
writer.WriteStartObject();
224+
225+
var items = results.Items;
226+
if (items.Count == 0)
227+
{
228+
return;
229+
}
230+
231+
var keysLength = items[0].Keys.Count;
232+
233+
var maxKeyLengths = new int[keysLength];
234+
var keyValues = new string[items.Count, keysLength];
235+
236+
for (var itemIndex = 0; itemIndex < items.Count; itemIndex++)
237+
{
238+
var item = items[itemIndex];
239+
for (var keyIndex = 0; keyIndex < keysLength; keyIndex++)
240+
{
241+
var key = item.Keys[keyIndex];
242+
var name = VerifierSettings.GetNameForParameter(key, pathFriendly: false);
243+
keyValues[itemIndex, keyIndex] = name;
244+
var currentKeyLength = maxKeyLengths[keyIndex];
245+
if (name.Length > currentKeyLength)
246+
{
247+
maxKeyLengths[keyIndex] = name.Length;
248+
}
249+
}
250+
}
251+
252+
var keys = new CombinationKey[keysLength];
253+
for (var itemIndex = 0; itemIndex < items.Count; itemIndex++)
254+
{
255+
for (var keyIndex = 0; keyIndex < keysLength; keyIndex++)
256+
{
257+
keys[keyIndex] = new(
258+
Value: keyValues[itemIndex, keyIndex],
259+
MaxLength: maxKeyLengths[keyIndex],
260+
Type: results.KeyTypes?[keyIndex]);
261+
}
262+
263+
var item = items[itemIndex];
264+
var name = BuildPropertyName(keys);
265+
writer.WritePropertyName(name);
266+
WriteValue(writer, item);
267+
}
268+
269+
writer.WriteEndObject();
270+
}
271+
272+
protected virtual string BuildPropertyName(IReadOnlyList<CombinationKey> keys)
273+
{
274+
var builder = new StringBuilder();
275+
foreach (var (value, maxLength, type) in keys)
276+
{
277+
var padding = maxLength - value.Length;
278+
if (type != null &&
279+
type.IsNumeric())
280+
{
281+
builder.Append(' ', padding);
282+
builder.Append(value);
283+
}
284+
else
285+
{
286+
builder.Append(value);
287+
builder.Append(' ', padding);
288+
}
289+
290+
builder.Append(", ");
291+
}
292+
293+
builder.Length -= 2;
294+
return builder.ToString();
295+
}
296+
297+
protected virtual void WriteValue(VerifyJsonWriter writer, CombinationResult result)
298+
{
299+
var exception = result.Exception;
300+
if (exception == null)
301+
{
302+
writer.WriteValue(result.Value);
303+
return;
304+
}
305+
306+
writer.WriteValue($"{exception.GetType().Name}: {exception.Message}");
307+
}
308+
}
309+
```
310+
<sup><a href='/src/Verify/Combinations/CombinationResultsConverter.cs#L1-L93' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationResultsConverter.cs' title='Start of snippet'>anchor</a></sup>
311+
<!-- endSnippet -->
312+
313+
314+
### Custom
315+
316+
Combination serialization can be customized using a Converter.
317+
318+
319+
#### Converter
320+
321+
Inherit from `CombinationResultsConverter` and override the desired members.
322+
323+
The below sample override `BuildPropertyName` to customize the property name. It bypasses the default implementation and hence does not pad columns or use VerifierSettings.GetNameForParameter for key conversion.
324+
325+
<!-- snippet: CombinationSample_CustomSerializationConverter -->
326+
<a id='snippet-CombinationSample_CustomSerializationConverter'></a>
327+
```cs
328+
class CustomCombinationConverter :
329+
CombinationResultsConverter
330+
{
331+
332+
protected override string BuildPropertyName(IReadOnlyList<CombinationKey> keys) =>
333+
string.Join(", ", keys.Select(_ => _.Value));
334+
}
335+
```
336+
<sup><a href='/src/StaticSettingsTests/VerifyCombinationsTests.cs#L114-L124' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CustomSerializationConverter' title='Start of snippet'>anchor</a></sup>
337+
<!-- endSnippet -->
338+
339+
Full control of serialization can be achieved by inheriting from `WriteOnlyJsonConverter<CombinationResults>`.
340+
341+
342+
#### Insert Converter
343+
344+
Insert the new converter at the top of the converter stack.
345+
346+
<!-- snippet: CombinationSample_CustomSerializationModuleInitializer -->
347+
<a id='snippet-CombinationSample_CustomSerializationModuleInitializer'></a>
348+
```cs
349+
static CustomCombinationConverter customConverter = new();
350+
351+
[ModuleInitializer]
352+
public static void Init() =>
353+
VerifierSettings.AddExtraSettings(_ => _.Converters.Insert(0, customConverter));
354+
```
355+
<sup><a href='/src/StaticSettingsTests/VerifyCombinationsTests.cs#L87-L95' title='Snippet source file'>snippet source</a> | <a href='#snippet-CombinationSample_CustomSerializationModuleInitializer' title='Start of snippet'>anchor</a></sup>
356+
<!-- endSnippet -->
357+
358+
359+
#### Result
360+
361+
<!-- snippet: VerifyCombinationsTests.Combination_CustomSerialization.verified.txt -->
362+
<a id='snippet-VerifyCombinationsTests.Combination_CustomSerialization.verified.txt'></a>
363+
```txt
364+
{
365+
1, Smith St, Sydney: 1 Smith St, Sydney,
366+
1, Smith St, Chicago: 1 Smith St, Chicago,
367+
1, Wallace St, Sydney: 1 Wallace St, Sydney,
368+
1, Wallace St, Chicago: 1 Wallace St, Chicago,
369+
10, Smith St, Sydney: 10 Smith St, Sydney,
370+
10, Smith St, Chicago: 10 Smith St, Chicago,
371+
10, Wallace St, Sydney: 10 Wallace St, Sydney,
372+
10, Wallace St, Chicago: 10 Wallace St, Chicago
373+
}
374+
```
375+
<sup><a href='/src/StaticSettingsTests/VerifyCombinationsTests.Combination_CustomSerialization.verified.txt#L1-L10' title='Snippet source file'>snippet source</a> | <a href='#snippet-VerifyCombinationsTests.Combination_CustomSerialization.verified.txt' title='Start of snippet'>anchor</a></sup>
198376
<!-- endSnippet -->

docs/mdsource/combinations.source.md

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,19 @@ snippet: CombinationSample
1818
snippet: VerifyCombinationsSample.BuildAddressTest.verified.txt
1919

2020

21+
## Column Alignment
22+
23+
Key value are aligned based on type.
24+
25+
* Numbers (int, double, float etc) are aligned right
26+
* All other types are aligned left
27+
28+
2129
## CaptureExceptions
2230

2331
By default exceptions are not captured.
2432

25-
To enable exception capture use `captureExceptions = true`
33+
To enable exception capture use `captureExceptions = true`:
2634

2735
snippet: CombinationSample_CaptureExceptions
2836

@@ -40,4 +48,39 @@ snippet: GlobalCaptureExceptions
4048

4149
If exception capture has been enabled globally, it can be disable at the method test level using `captureExceptions: false`.
4250

43-
snippet: CombinationSample_CaptureExceptionsFalse
51+
snippet: CombinationSample_CaptureExceptionsFalse
52+
53+
54+
## Result serialization
55+
56+
Serialization of results is done using `CombinationResultsConverter`
57+
58+
snippet: CombinationResultsConverter.cs
59+
60+
61+
### Custom
62+
63+
Combination serialization can be customized using a Converter.
64+
65+
66+
#### Converter
67+
68+
Inherit from `CombinationResultsConverter` and override the desired members.
69+
70+
The below sample override `BuildPropertyName` to customize the property name. It bypasses the default implementation and hence does not pad columns or use VerifierSettings.GetNameForParameter for key conversion.
71+
72+
snippet: CombinationSample_CustomSerializationConverter
73+
74+
Full control of serialization can be achieved by inheriting from `WriteOnlyJsonConverter<CombinationResults>`.
75+
76+
77+
#### Insert Converter
78+
79+
Insert the new converter at the top of the converter stack.
80+
81+
snippet: CombinationSample_CustomSerializationModuleInitializer
82+
83+
84+
#### Result
85+
86+
snippet: VerifyCombinationsTests.Combination_CustomSerialization.verified.txt
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
1, Smith St , Sydney : 1 Smith St, Sydney,
3-
1, Smith St , Chicago: 1 Smith St, Chicago,
4-
1, Wallace St, Sydney : 1 Wallace St, Sydney,
5-
1, Wallace St, Chicago: 1 Wallace St, Chicago,
6-
10, Smith St , Sydney : 10 Smith St, Sydney,
7-
10, Smith St , Chicago: 10 Smith St, Chicago,
8-
10, Wallace St, Sydney : 10 Wallace St, Sydney,
2+
1, Smith St, Sydney: 1 Smith St, Sydney,
3+
1, Smith St, Chicago: 1 Smith St, Chicago,
4+
1, Wallace St, Sydney: 1 Wallace St, Sydney,
5+
1, Wallace St, Chicago: 1 Wallace St, Chicago,
6+
10, Smith St, Sydney: 10 Smith St, Sydney,
7+
10, Smith St, Chicago: 10 Smith St, Chicago,
8+
10, Wallace St, Sydney: 10 Wallace St, Sydney,
99
10, Wallace St, Chicago: 10 Wallace St, Chicago
1010
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
1, Smith St, Sydney: 1 Smith St, Sydney,
3+
1, Smith St, Chicago: 1 Smith St, Chicago,
4+
1, Wallace St, Sydney: 1 Wallace St, Sydney,
5+
1, Wallace St, Chicago: 1 Wallace St, Chicago,
6+
10, Smith St, Sydney: 10 Smith St, Sydney,
7+
10, Smith St, Chicago: 10 Smith St, Chicago,
8+
10, Wallace St, Sydney: 10 Wallace St, Sydney,
9+
10, Wallace St, Chicago: 10 Wallace St, Chicago
10+
}

src/StaticSettingsTests/VerifyCombinationsTests.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public Task WithNoCaptureExceptions()
5656
captureExceptions: false);
5757
});
5858
}
59+
5960
public static string BuildAddress(int streetNumber, string street, string city)
6061
{
6162
ArgumentException.ThrowIfNullOrWhiteSpace(street);
@@ -82,4 +83,43 @@ public Task BuildAddressExceptionsDisabledTest()
8283
}
8384

8485
#endregion
86+
87+
#region CombinationSample_CustomSerializationModuleInitializer
88+
89+
static CustomCombinationConverter customConverter = new();
90+
91+
[ModuleInitializer]
92+
public static void Init() =>
93+
VerifierSettings.AddExtraSettings(_ => _.Converters.Insert(0, customConverter));
94+
95+
#endregion
96+
97+
#region CombinationSample_CustomSerialization
98+
99+
[Fact]
100+
public Task Combination_CustomSerialization()
101+
{
102+
int[] streetNumbers = [1, 10];
103+
string[] streets = ["Smith St", "Wallace St"];
104+
string[] cities = ["Sydney", "Chicago"];
105+
return VerifyCombinations(
106+
BuildAddress,
107+
streetNumbers,
108+
streets,
109+
cities);
110+
}
111+
112+
#endregion
113+
114+
#region CombinationSample_CustomSerializationConverter
115+
116+
class CustomCombinationConverter :
117+
CombinationResultsConverter
118+
{
119+
120+
protected override string BuildPropertyName(IReadOnlyList<CombinationKey> keys) =>
121+
string.Join(", ", keys.Select(_ => _.Value));
122+
}
123+
124+
#endregion
85125
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
1, a , 2020-10-01: 1 a 1/10/2020,
3+
1, a , null : 1 a ,
4+
1, a , 0001-01-01: 1 a 1/01/0001,
5+
1, bbbb, 2020-10-01: 1 bbbb 1/10/2020,
6+
1, bbbb, null : 1 bbbb ,
7+
1, bbbb, 0001-01-01: 1 bbbb 1/01/0001,
8+
100, a , 2020-10-01: 100 a 1/10/2020,
9+
100, a , null : 100 a ,
10+
100, a , 0001-01-01: 100 a 1/01/0001,
11+
100, bbbb, 2020-10-01: 100 bbbb 1/10/2020,
12+
100, bbbb, null : 100 bbbb ,
13+
100, bbbb, 0001-01-01: 100 bbbb 1/01/0001
14+
}

0 commit comments

Comments
 (0)