1
1
// FIXME(integers): add tests that perform the same checks in generic code
2
2
3
3
%{
4
- import gyb
4
+ from SwiftIntTypes import all_integer_types, int_max, int_min
5
+ from SwiftFloatingPointTypes import all_floating_point_types
5
6
}%
6
7
7
8
import StdlibUnittest
@@ -34,22 +35,15 @@ func getTooLargeMessage() -> String {
34
35
return ""
35
36
}
36
37
37
- %{
38
-
39
- int_to_int_conversion_template = gyb.parse_template("int_to_int_conversion",
40
- """
41
- %{
42
- from SwiftIntTypes import all_integer_types, int_max, int_min
43
- from SwiftFloatingPointTypes import all_floating_point_types
44
-
45
- }%
38
+ % word_bits = int(target_ptrsize)
46
39
% for self_ty in all_integer_types(word_bits):
47
40
% selfBits = self_ty.bits
48
41
% selfSigned = self_ty.is_signed
49
42
% selfMin = self_ty.min
50
43
% selfMax = self_ty.max
51
44
% Self = self_ty.stdlib_name
52
45
46
+ % # Test conversion behaviors for all integer types
53
47
% for other_ty in all_integer_types(word_bits):
54
48
% otherBits = other_ty.bits
55
49
% otherSigned = other_ty.is_signed
@@ -58,11 +52,11 @@ from SwiftFloatingPointTypes import all_floating_point_types
58
52
% Other = other_ty.stdlib_name
59
53
60
54
% for testValue in [selfMin, selfMax, selfMin - 1, selfMax + 1, otherMin, otherMax]:
61
-
62
55
% if testValue < otherMin or testValue > otherMax:
63
56
% # Can't construct `other` value, do nothing and continue.
64
-
57
+ % pass
65
58
% elif testValue >= selfMin and testValue <= selfMax:
59
+ % # Test value can be represented by Self, test conversion succeeds
66
60
67
61
/// Always-safe conversion from ${Other}(${testValue}) to ${Self}.
68
62
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
@@ -80,6 +74,7 @@ FixedPointConversionFailure.test("${Other}To${Self}FailableConversion/dest=${tes
80
74
}
81
75
82
76
% else:
77
+ % # Test value is out of range of Self, test conversion fails
83
78
84
79
/// Always-failing conversion from ${Other}(${testValue}) to ${Self}.
85
80
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
@@ -96,11 +91,12 @@ FixedPointConversionFailure.test("${Other}To${Self}Conversion/dest=${testValue}"
96
91
let input = get${Other}(${testValue})
97
92
expectNil(${Self}(exactly: input))
98
93
}
99
- % end
100
94
95
+ % end
101
96
% end # for testValue in ...
102
97
% end # for in all_integer_types (Other)
103
98
99
+ % # Test conversion behaviors for all floating-point types
104
100
% for other_type in all_floating_point_types():
105
101
% Other = "Float" + str(other_type.bits)
106
102
% otherMin = -int_max(bits=other_type.explicit_significand_bits, signed=False)
@@ -110,12 +106,22 @@ FixedPointConversionFailure.test("${Other}To${Self}Conversion/dest=${testValue}"
110
106
#if !os(Windows) && (arch(i386) || arch(x86_64))
111
107
% end
112
108
113
- % for testValue in [repr(value) for value in [selfMin, selfMax, selfMin - 0.1, selfMax + 0.1, otherMin, otherMax, 0.0, -0.0, 0.1, -0.1]]:
109
+ % # Int64.min - 0.1 can not be fully represented by a double-precision
110
+ % # value. Python can not leverage extended precision, so the resulting
111
+ % # value incorrectly rounds to an integer which compares as less than
112
+ % # Int64.min, even though in Swift a Float80 literal will have the correct
113
+ % # value since Swift 5. Skip the bad case for now.
114
+ % testValues = [selfMin, selfMax, selfMin - 0.1, selfMax + 0.1, otherMin, otherMax, 0.0, -0.0, 0.1, -0.1]
115
+ % if Other == 'Float80' and selfBits > 63 and selfSigned:
116
+ % del testValues[2]
117
+ % end
114
118
119
+ % for testValue in testValues:
115
120
% if testValue < otherMin or testValue > otherMax:
116
121
% # Can't construct `other` value to test from, do nothing and continue.
117
-
118
- % elif testValue >= selfMin and testValue <= selfMax and testValue % 1 == 0 and testValue != -0.0:
122
+ % pass
123
+ % elif testValue >= selfMin and testValue <= selfMax and testValue % 1.0 == 0:
124
+ % # Test value can be represented exactly by Self, test two-way conversion
119
125
120
126
FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValue}") {
121
127
let input = get${Other}(${testValue})
@@ -126,20 +132,22 @@ FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${test
126
132
127
133
FloatingPointConversionFailures.test("${Other}To${Self}FailableConversion/dest=${testValue}") {
128
134
let input = get${Other}(${testValue})
129
- expectNil (${Self}(exactly: input))
135
+ expectNotNil (${Self}(exactly: input))
130
136
}
131
137
132
138
% else:
133
-
134
- % if testValue > selfMax:
139
+ % if int(testValue) > selfMax:
140
+ % # Test value exceeds maximum value of Self, test for too large message
135
141
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}")
136
142
.crashOutputMatches(getTooLargeMessage()).code {
137
143
expectCrashLater()
138
- % elif testValue < selfMin:
144
+ % elif int(testValue) < selfMin:
145
+ % # Test value doesn't reach minimum value of Self, test for too small message
139
146
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}")
140
147
.crashOutputMatches(getTooSmallMessage()).code {
141
148
expectCrashLater()
142
149
% else:
150
+ % # Test value can be represented inexactly by Self, test for truncation
143
151
FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValue}") {
144
152
% end
145
153
let input = get${Other}(${testValue})
@@ -208,26 +216,4 @@ FloatingPointConversionFailures.test("${Self}/${Other}/NaN") {
208
216
% end # for in all_floating_point_types (Other)
209
217
% end # for in all_integer_types (Self)
210
218
211
- """)
212
-
213
- }%
214
-
215
- #if arch(i386) || arch(arm)
216
-
217
- ${gyb.execute_template(
218
- int_to_int_conversion_template,
219
- word_bits=32)}
220
-
221
- #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
222
-
223
- ${gyb.execute_template(
224
- int_to_int_conversion_template,
225
- word_bits=64)}
226
-
227
- #else
228
-
229
- _UnimplementedError()
230
-
231
- #endif
232
-
233
219
runAllTests()
0 commit comments