Skip to content

Commit dcb36ed

Browse files
authored
Merge pull request #79 from TSRBerry/feature/unsigned-range
CombinatorialRangeAttribute: Add uint support
2 parents 305a4d1 + 62361d8 commit dcb36ed

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

src/Xunit.Combinatorial/CombinatorialRangeAttribute.cs

+65
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,71 @@ public CombinatorialRangeAttribute(int from, int to, int step)
7878
this.Values = values;
7979
}
8080

81+
/// <summary>
82+
/// Initializes a new instance of the <see cref="CombinatorialRangeAttribute"/> class.
83+
/// </summary>
84+
/// <param name="from">The value at the beginning of the range.</param>
85+
/// <param name="count">
86+
/// The quantity of consecutive integer values to include.
87+
/// Cannot be less than 1, which would conceptually result in zero test cases.
88+
/// </param>
89+
public CombinatorialRangeAttribute(uint from, uint count)
90+
{
91+
if (count < 1)
92+
{
93+
throw new ArgumentOutOfRangeException(nameof(count));
94+
}
95+
96+
object[] values = new object[count];
97+
for (uint i = 0; i < count; i++)
98+
{
99+
values[i] = from + i;
100+
}
101+
102+
this.Values = values;
103+
}
104+
105+
/// <summary>
106+
/// Initializes a new instance of the <see cref="CombinatorialRangeAttribute"/> class.
107+
/// </summary>
108+
/// <param name="from">The value at the beginning of the range.</param>
109+
/// <param name="to">
110+
/// The value at the end of the range.
111+
/// Cannot be less than "from" parameter.
112+
/// When "to" and "from" are equal, CombinatorialValues is more appropriate.
113+
/// </param>
114+
/// <param name="step">
115+
/// The number of unsigned integers to step for each value in result.
116+
/// Cannot be less than one. Stepping zero is not useful.
117+
/// Stepping over "to" does not add another value to the range.
118+
/// </param>
119+
public CombinatorialRangeAttribute(uint from, uint to, uint step)
120+
{
121+
if (step == 0)
122+
{
123+
throw new ArgumentOutOfRangeException(nameof(step));
124+
}
125+
126+
var values = new List<uint>();
127+
128+
if (from < to)
129+
{
130+
for (uint i = from; i <= to; i += step)
131+
{
132+
values.Add(i);
133+
}
134+
}
135+
else
136+
{
137+
for (uint i = from; i >= to && i <= from; i -= step)
138+
{
139+
values.Add(i);
140+
}
141+
}
142+
143+
this.Values = values.Cast<object>().ToArray();
144+
}
145+
81146
/// <summary>
82147
/// Gets the values that should be passed to this parameter on the test method.
83148
/// </summary>

test/Xunit.Combinatorial.Tests/CombinatorialRangeAttributeTests.cs

+57
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,40 @@ public void IntegerStep_InvalidIntervalAndStep_ArgOutOfRange(int from, int to, i
4242
Assert.Throws<ArgumentOutOfRangeException>(() => new CombinatorialRangeAttribute(from, to, step));
4343
}
4444

45+
[Theory]
46+
[InlineData(0u, 5u)]
47+
public void CountOfUnsignedIntegers_HappyPath_SetsAttributeWithRange(uint from, uint count)
48+
{
49+
object[] values = UnsignedSequence(from, from + count - 1u, 1u).Cast<object>().ToArray();
50+
var attribute = new CombinatorialRangeAttribute(from, count);
51+
Assert.Equal(values, attribute.Values);
52+
}
53+
54+
[Theory]
55+
[InlineData(0u, 0u)]
56+
public void CountOfUnsignedIntegers_ZeroCount_ArgOutOfRange(uint from, uint count)
57+
{
58+
Assert.Throws<ArgumentOutOfRangeException>(() => new CombinatorialRangeAttribute(from, count));
59+
}
60+
61+
[Theory]
62+
[InlineData(0u, 7u, 2u)]
63+
[InlineData(0u, 8u, 2u)]
64+
[InlineData(7u, 0u, 2u)]
65+
public void UnsignedIntegerStep_HappyPath_SetsAttributeWithRange(uint from, uint to, uint step)
66+
{
67+
object[] expectedValues = UnsignedSequence(from, to, step).Cast<object>().ToArray();
68+
69+
var attribute = new CombinatorialRangeAttribute(from, to, step);
70+
Assert.Equal(expectedValues, attribute.Values);
71+
}
72+
4573
internal static IEnumerable<int> Sequence(int from, int to, int step)
4674
=> step >= 0 ? SequenceIterator(from, to, step) : SequenceReverseIterator(from, to, step);
4775

76+
internal static IEnumerable<uint> UnsignedSequence(uint from, uint to, uint step)
77+
=> from < to ? UnsignedSequenceIterator(from, to, step) : UnsignedSequenceReverseIterator(from, to, step);
78+
4879
private static IEnumerable<int> SequenceIterator(int from, int to, int step)
4980
{
5081
int value = from;
@@ -70,4 +101,30 @@ private static IEnumerable<int> SequenceReverseIterator(int from, int to, int st
70101
}
71102
}
72103
}
104+
105+
private static IEnumerable<uint> UnsignedSequenceIterator(uint from, uint to, uint step)
106+
{
107+
uint value = from;
108+
while (value <= to)
109+
{
110+
yield return value;
111+
unchecked
112+
{
113+
value += step;
114+
}
115+
}
116+
}
117+
118+
private static IEnumerable<uint> UnsignedSequenceReverseIterator(uint from, uint to, uint step)
119+
{
120+
uint value = from;
121+
while (value >= to && value <= from)
122+
{
123+
yield return value;
124+
unchecked
125+
{
126+
value -= step;
127+
}
128+
}
129+
}
73130
}

0 commit comments

Comments
 (0)