Skip to content

Commit 85e0615

Browse files
committed
[stdlib] Update the FixedPointConversion tests
1 parent 42a6782 commit 85e0615

File tree

3 files changed

+171
-198
lines changed

3 files changed

+171
-198
lines changed
Lines changed: 147 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -1,233 +1,194 @@
1-
// FIXME(integers): add tests that perform the same checks in generic code
2-
3-
%{
4-
from SwiftIntTypes import all_integer_types, int_max, int_min
5-
from SwiftFloatingPointTypes import all_floating_point_types, getFtoIBounds
6-
7-
from decimal import Decimal
8-
}%
9-
10-
import StdlibUnittest
11-
12-
var FixedPointConversionTraps = TestSuite("FixedPointToFixedPointConversionTraps")
13-
var FixedPointConversionFailure = TestSuite("FixedPointToFixedPointConversionFailures")
14-
15-
var FloatingPointConversionTruncations = TestSuite("FloatingPointToFixedPointConversionTruncations")
16-
var FloatingPointConversionTraps = TestSuite("FloatingPointConversionTraps")
17-
var FloatingPointConversionFailures = TestSuite("FloatingPointToFixedPointConversionFailures")
18-
19-
func getInfiniteOrNaNMessage() -> String {
20-
if _isDebugAssertConfiguration() {
21-
return "either infinite or NaN"
22-
}
23-
return ""
24-
}
25-
26-
func getTooSmallMessage() -> String {
27-
if _isDebugAssertConfiguration() {
28-
return "would be less than"
29-
}
30-
return ""
31-
}
32-
33-
func getTooLargeMessage() -> String {
34-
if _isDebugAssertConfiguration() {
35-
return "would be greater than"
36-
}
37-
return ""
38-
}
39-
1+
% # FIXME(integers): add tests that perform the same checks in generic code.
2+
%
3+
% from SwiftIntTypes import all_integer_types, int_max
4+
% from SwiftFloatingPointTypes import all_floating_point_types
5+
% from decimal import Decimal
6+
%
7+
% test_suites = []
8+
%
409
% word_bits = int(target_ptrsize)
4110
% for self_ty in all_integer_types(word_bits):
42-
% selfBits = self_ty.bits
43-
% selfSigned = self_ty.is_signed
44-
% selfMin = self_ty.min
45-
% selfMax = self_ty.max
4611
% Self = self_ty.stdlib_name
12+
% selfMax = self_ty.max
13+
% selfMin = self_ty.min
14+
%
15+
% test_suite = 'FixedPointConversion_' + configuration + '_To' + Self
16+
% test_suites.append(test_suite)
17+
%
18+
//===----------------------------------------------------------------------===//
19+
// BEGIN ${test_suite}.swift
20+
//===----------------------------------------------------------------------===//
4721

48-
% # Test conversion behaviors for all integer types
49-
% for other_ty in all_integer_types(word_bits):
50-
% otherBits = other_ty.bits
51-
% otherSigned = other_ty.is_signed
52-
% otherMin = other_ty.min
53-
% otherMax = other_ty.max
54-
% Other = other_ty.stdlib_name
55-
56-
% for testValue in [selfMin, selfMax, selfMin - 1, selfMax + 1, otherMin, otherMax]:
22+
import StdlibUnittest
5723

58-
% if testValue < otherMin or testValue > otherMax:
59-
% # Can't construct `other` value, do nothing and continue.
60-
% pass
61-
% elif testValue >= selfMin and testValue <= selfMax:
62-
% # Test value can be represented by Self, test conversion succeeds
24+
func register${test_suite}() {
6325

64-
/// Always-safe conversion from ${Other}(${testValue}) to ${Self}.
65-
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
66-
// Test that nothing interesting happens and we end up with the same result after converting.
67-
let input = get${Other}(${testValue})
68-
expectEqual(${testValue}, ${Self}(input))
69-
}
26+
let ${test_suite} = TestSuite("${test_suite}")
7027

71-
/// Never-nil failable conversion from ${Other}(${testValue}) to ${Self}.
72-
FixedPointConversionFailure.test("${Other}To${Self}FailableConversion/dest=${testValue}") {
73-
// Test that nothing interesting happens and we end up with a non-nil, identical result.
74-
let input = get${Other}(${testValue})
75-
let result = ${Self}(exactly: input)
76-
expectEqual(${testValue}, result)
77-
}
28+
% # Test conversion behaviors for all integer types.
29+
% for other_ty in all_integer_types(word_bits):
30+
% Other = other_ty.stdlib_name
31+
% otherMax = other_ty.max
32+
% otherMin = other_ty.min
33+
%
34+
//===--------------------------------------------------------------------===//
35+
// ${Other}
36+
//===--------------------------------------------------------------------===//
7837

79-
% else:
80-
% # Test value is out of range of Self, test conversion fails
38+
% testValues = [
39+
% selfMin,
40+
% selfMax,
41+
% selfMin - 1,
42+
% selfMax + 1,
43+
% otherMin,
44+
% otherMax
45+
% ]
46+
% for testValue in testValues:
47+
% testLiteralValue = str(testValue)
48+
% if otherMin <= testValue <= otherMax:
49+
% if selfMin <= testValue <= selfMax:
50+
${test_suite}.test("From${Other}(${testLiteralValue})_NeverTraps") {
51+
let input = get${Other}(${testLiteralValue})
52+
let actual = ${Self}(input)
53+
expectEqual(${testLiteralValue}, actual)
54+
}
8155

82-
/// Always-failing conversion from ${Other}(${testValue}) to ${Self}.
83-
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
84-
// Test that we check if we fail and crash when an integer would be truncated in conversion.
85-
let input = get${Other}(${testValue})
86-
expectCrashLater()
87-
let result = ${Self}(input)
88-
_blackHole(result)
89-
}
56+
${test_suite}.test("From${Other}(${testLiteralValue})_NeverFails") {
57+
let input = get${Other}(${testLiteralValue})
58+
let actual = ${Self}(exactly: input)
59+
expectEqual(${testLiteralValue}, actual)
60+
}
9061

91-
/// Always-nil failable conversion from ${Other}(${testValue}) to ${Self}.
92-
FixedPointConversionFailure.test("${Other}To${Self}Conversion/dest=${testValue}") {
93-
// Test that we check if we return nil when an integer would be truncated in conversion.
94-
let input = get${Other}(${testValue})
95-
expectNil(${Self}(exactly: input))
96-
}
62+
% else:
63+
${test_suite}.test("From${Other}(${testLiteralValue})_AlwaysTraps") {
64+
let input = get${Other}(${testLiteralValue})
65+
expectCrash {
66+
let actual = ${Self}(input)
67+
_blackHole(actual)
68+
}
69+
}
9770

98-
% end
99-
% end # for testValue in ...
100-
% end # for in all_integer_types (Other)
71+
${test_suite}.test("From${Other}(${testLiteralValue})_AlwaysFails") {
72+
let input = get${Other}(${testLiteralValue})
73+
let actual = ${Self}(exactly: input)
74+
expectNil(actual)
75+
}
10176

102-
% # Test conversion behaviors for all floating-point types
77+
% end # if
78+
% end # if
79+
% end # for
80+
% end # for
81+
%
82+
% # Test conversion behaviors for all floating-point types.
10383
% for other_type in all_floating_point_types():
10484
% Other = "Float" + str(other_type.bits)
105-
% otherMin = -int_max(bits=other_type.explicit_significand_bits, signed=False)
10685
% otherMax = int_max(bits=other_type.explicit_significand_bits, signed=False)
107-
% (selfFtoIMin, selfFtoIMax) = getFtoIBounds(other_type.bits, selfBits, selfSigned)
86+
% otherMin = -otherMax
87+
%
88+
//===--------------------------------------------------------------------===//
89+
// ${Other}
90+
//===--------------------------------------------------------------------===//
10891

10992
% if Other == 'Float16':
11093
#if !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
11194
if #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) {
95+
11296
% elif Other == 'Float80':
11397
#if !(os(Windows) || os(Android)) && (arch(i386) || arch(x86_64))
114-
% end
11598

99+
% end # if
100+
%
116101
% testValues = [
117102
% Decimal(selfMin),
118103
% Decimal(selfMax),
119-
% Decimal(selfFtoIMin) - Decimal('0.1'),
120-
% Decimal(selfFtoIMax) + Decimal('0.1'),
104+
% Decimal(selfMin - 1),
105+
% Decimal(selfMax + 1),
121106
% Decimal(otherMin),
122107
% Decimal(otherMax),
123108
% Decimal('0.0'),
124109
% Decimal('-0.0'),
125110
% Decimal('0.1'),
126-
% Decimal('-0.1')
111+
% Decimal('-0.1'),
112+
% Decimal('-123.45')
127113
% ]
128114
% for testValue in testValues:
129-
% testValueStr = str(testValue)
130-
131-
% if testValue < otherMin or testValue > otherMax:
132-
% # Can't construct `other` value to test from, do nothing and continue.
133-
% pass
134-
% elif testValue >= selfFtoIMin and testValue <= selfFtoIMax and (testValue % 1).is_zero():
135-
% # Test value can be represented exactly by Self, test two-way conversion
136-
137-
FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValueStr}") {
138-
let input = get${Other}(${testValueStr})
139-
let result = ${Self}(input)
140-
let resultConvertedBack = ${Other}(result)
141-
expectEqual(${testValueStr}, resultConvertedBack)
142-
}
143-
144-
FloatingPointConversionFailures.test("${Other}To${Self}FailableConversion/dest=${testValueStr}") {
145-
let input = get${Other}(${testValueStr})
146-
expectNotNil(${Self}(exactly: input))
147-
}
115+
% testLiteralValue = str(testValue)
116+
% if otherMin <= testValue <= otherMax:
117+
% if (selfMin - 1) < testValue < (selfMax + 1):
118+
${test_suite}.test("From${Other}(${testLiteralValue})_NeverTraps") {
119+
let input = get${Other}(${testLiteralValue})
120+
let actual = ${Self}(input)
121+
expectEqual(${str(int(testValue))}, actual)
122+
}
148123

149-
% else:
150-
% if testValue > selfFtoIMax:
151-
% # Test value exceeds maximum value of Self, test for too large message
152-
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValueStr}")
153-
.crashOutputMatches(getTooLargeMessage()).code {
154-
expectCrashLater()
155-
% elif testValue < selfFtoIMin:
156-
% # Test value doesn't reach minimum value of Self, test for too small message
157-
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValueStr}")
158-
.crashOutputMatches(getTooSmallMessage()).code {
159-
expectCrashLater()
160124
% else:
161-
% # Test value can be represented inexactly by Self, test for truncation
162-
FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValueStr}") {
163-
% end
164-
let input = get${Other}(${testValueStr})
165-
let result = ${Self}(input)
166-
let resultConvertedBack = ${Other}(result)
167-
expectNotEqual(input, resultConvertedBack)
168-
}
169-
170-
FloatingPointConversionFailures.test("${Other}To${Self}Conversion/dest=${testValueStr}") {
171-
let input = get${Other}(${testValueStr})
172-
expectNil(${Self}(exactly: input))
173-
}
174-
% end
175-
% end # for in testValues
176-
177-
// Test Always-Trapping conversions.
178-
179-
% if not selfSigned:
180-
181-
FloatingPointConversionTraps.test("${Self}/${Other}/negative")
182-
.crashOutputMatches(getTooSmallMessage()).code {
183-
expectCrashLater()
184-
_blackHole(${Self}(get${Other}(-123.0)))
185-
}
125+
${test_suite}.test("From${Other}(${testLiteralValue})_AlwaysTraps") {
126+
let input = get${Other}(${testLiteralValue})
127+
expectCrash {
128+
let actual = ${Self}(input)
129+
_blackHole(actual)
130+
}
131+
}
186132

187-
FloatingPointConversionFailures.test("${Self}/${Other}/negative") {
188-
expectNil(${Self}(exactly: get${Other}(-123.0)))
189-
}
133+
% end # if
134+
%
135+
% if (selfMin <= testValue <= selfMax) and (testValue % 1).is_zero():
136+
${test_suite}.test("From${Other}(${testLiteralValue})_NeverFails") {
137+
let input = get${Other}(${testLiteralValue})
138+
let actual = ${Self}(exactly: input)
139+
expectEqual(${str(int(testValue))}, actual)
140+
}
190141

191-
% end
142+
% else:
143+
${test_suite}.test("From${Other}(${testLiteralValue})_AlwaysFails") {
144+
let input = get${Other}(${testLiteralValue})
145+
let actual = ${Self}(exactly: input)
146+
expectNil(actual)
147+
}
192148

193-
FloatingPointConversionTraps.test("${Self}/${Other}/+inf")
194-
.crashOutputMatches(getInfiniteOrNaNMessage()).code {
195-
expectCrashLater()
196-
_blackHole(${Self}(get${Other}(${Other}.infinity)))
197-
}
149+
% end # if
150+
% end # if
151+
% end # for
152+
%
153+
% for testExpression in ['-.infinity', '.infinity', '-.nan', '.nan']:
154+
${test_suite}.test("From${Other}(${testExpression})_AlwaysTraps") {
155+
let input = get${Other}(${testExpression})
156+
expectCrash {
157+
let actual = ${Self}(input)
158+
_blackHole(actual)
159+
}
160+
}
198161

199-
FloatingPointConversionFailures.test("${Self}/${Other}/+inf") {
200-
expectNil(${Self}(exactly: get${Other}(${Other}.infinity)))
201-
}
162+
${test_suite}.test("From${Other}(${testExpression})_AlwaysFails") {
163+
let input = get${Other}(${testExpression})
164+
let actual = ${Self}(exactly: input)
165+
expectNil(actual)
166+
}
202167

203-
FloatingPointConversionTraps.test("${Self}/${Other}/-inf")
204-
.crashOutputMatches(getInfiniteOrNaNMessage()).code {
205-
expectCrashLater()
206-
_blackHole(${Self}(get${Other}(-${Other}.infinity)))
168+
% end # for
169+
%
170+
% if Other == 'Float16':
207171
}
172+
#endif // Float16
208173

209-
FloatingPointConversionFailures.test("${Self}/${Other}/-inf") {
210-
expectNil(${Self}(exactly: get${Other}(-${Other}.infinity)))
211-
}
174+
% elif Other == 'Float80':
175+
#endif // Float80
212176

213-
FloatingPointConversionTraps.test("${Self}/${Other}/NaN")
214-
.crashOutputMatches(getInfiniteOrNaNMessage()).code {
215-
expectCrashLater()
216-
_blackHole(${Self}(get${Other}(${Other}.nan)))
217-
}
177+
% end # if
178+
%
179+
% end # for
180+
} // func
218181

219-
FloatingPointConversionFailures.test("${Self}/${Other}/NaN") {
220-
expectNil(${Self}(exactly: get${Other}(${Other}.nan)))
221-
}
182+
% end # for
183+
%
184+
//===----------------------------------------------------------------------===//
185+
// BEGIN main.swift
186+
//===----------------------------------------------------------------------===//
222187

223-
% if Other == 'Float16':
224-
}
225-
#endif
226-
% elif Other == 'Float80':
227-
#endif
228-
% end
188+
import StdlibUnittest
229189

230-
% end # for in all_floating_point_types (Other)
231-
% end # for in all_integer_types (Self)
190+
% for test_suite in test_suites:
191+
register${test_suite}()
192+
% end # for
232193

233194
runAllTests()

0 commit comments

Comments
 (0)