Skip to content

Commit 529b284

Browse files
committed
Reorganize tests following INCITS 4-1986 pattern
Apply systematic test organization with per-source-file tests plus cross-cutting test files, following the pattern established in swift-incits-4-1986. Structure: - One test file per source file (6 files) • Double+IEEE_754 Tests.swift • Float+IEEE_754 Tests.swift • [UInt8]+IEEE_754 Tests.swift - Cross-cutting test files (3 files) • SpecialValues Tests.swift (±0, ±∞, NaN, edge magnitudes) • RoundTrip Tests.swift (all conversion paths) • Endianness Tests.swift (byte order handling) Improvements: - Extensive parameterized testing with @test(arguments:) - 48 tests (up from 16) with better coverage - Clear suite-based organization - Tests for all special IEEE 754 values - Comprehensive endianness testing - All conversion path validation Pattern follows INCITS 4-1986 best practices: - Suite-based grouping with descriptive names - Parameterized tests for value ranges - Separate edge case and special value testing - Systematic coverage of all API surfaces Tests: All 48 tests passing (14 suites)
1 parent e0d2c86 commit 529b284

File tree

7 files changed

+616
-172
lines changed

7 files changed

+616
-172
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Double+IEEE_754 Tests.swift
2+
// swift-ieee-754
3+
//
4+
// Tests for Double IEEE 754 extensions
5+
6+
import Testing
7+
@testable import IEEE_754
8+
9+
@Suite("Double+IEEE_754 - Direct bytes() method")
10+
struct DoubleDirectBytesTests {
11+
@Test(arguments: [
12+
3.14159265358979323846,
13+
2.71828182845904523536,
14+
1.41421356237309504880,
15+
0.0,
16+
-0.0,
17+
1.0,
18+
-1.0,
19+
])
20+
func `direct bytes round-trip`(value: Double) {
21+
let bytes = value.bytes()
22+
let restored = Double(bytes: bytes)
23+
24+
if value.isNaN {
25+
#expect(restored?.isNaN == true, "NaN should round-trip")
26+
} else if value == 0 && value.sign == .minus {
27+
// Negative zero
28+
#expect(restored == value && restored!.sign == .minus, "Negative zero should preserve sign")
29+
} else {
30+
#expect(restored == value, "\(value) should round-trip through bytes()")
31+
}
32+
}
33+
34+
@Test(arguments: [3.14159, 2.71828, 1.41421])
35+
func `direct bytes big-endian round-trip`(value: Double) {
36+
let bytes = value.bytes(endianness: .big)
37+
let restored = Double(bytes: bytes, endianness: .big)
38+
39+
#expect(restored == value, "\(value) should round-trip through bytes(endianness: .big)")
40+
}
41+
}
42+
43+
@Suite("Double+IEEE_754 - Namespace API")
44+
struct DoubleNamespaceTests {
45+
@Test(arguments: [3.14159, 2.71828, 1.41421])
46+
func `namespace bytes round-trip`(value: Double) {
47+
let bytes = value.ieee754.bytes()
48+
let restored = Double(bytes: bytes)
49+
50+
#expect(restored == value, "\(value) should round-trip through ieee754.bytes()")
51+
}
52+
53+
@Test(arguments: [3.14159, 2.71828, 1.41421])
54+
func `namespace type method`(value: Double) {
55+
let bytes = value.ieee754.bytes()
56+
let restored = Double.ieee754(bytes)
57+
58+
#expect(restored == value, "\(value) should round-trip through Double.ieee754()")
59+
}
60+
61+
@Test func `bitPattern property`() {
62+
let value: Double = 3.14159265358979323846
63+
let pattern1 = value.bitPattern
64+
let pattern2 = value.ieee754.bitPattern
65+
66+
#expect(pattern1 == pattern2, "Direct and namespace bitPattern should match")
67+
}
68+
}
69+
70+
@Suite("Double+IEEE_754 - Canonical init")
71+
struct DoubleCanonicalInitTests {
72+
@Test(arguments: [3.14159265358979323846, 2.71828, 1.41421, 0.0, 1.0, -1.0])
73+
func `canonical init bytes parameter`(value: Double) {
74+
let bytes = value.bytes()
75+
let restored = Double(bytes: bytes)
76+
77+
#expect(restored == value, "\(value) should round-trip through Double(bytes:)")
78+
}
79+
80+
@Test(arguments: [3.14159, 2.71828, 1.41421])
81+
func `canonical init big-endian`(value: Double) {
82+
let bytes = value.bytes(endianness: .big)
83+
let restored = Double(bytes: bytes, endianness: .big)
84+
85+
#expect(restored == value, "\(value) should round-trip with big-endian")
86+
}
87+
88+
@Test func `invalid byte count returns nil`() {
89+
let tooFew = [UInt8](repeating: 0, count: 7)
90+
let tooMany = [UInt8](repeating: 0, count: 9)
91+
92+
#expect(Double(bytes: tooFew) == nil, "7 bytes should return nil")
93+
#expect(Double(bytes: tooMany) == nil, "9 bytes should return nil")
94+
}
95+
96+
@Test func `exactly 8 bytes succeeds`() {
97+
let exactlyEight = [UInt8](repeating: 0, count: 8)
98+
let result = Double(bytes: exactlyEight)
99+
100+
#expect(result != nil, "Exactly 8 bytes should succeed")
101+
#expect(result == 0.0, "All-zero bytes should decode to 0.0")
102+
}
103+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Endianness Tests.swift
2+
// swift-ieee-754
3+
//
4+
// Tests for little-endian and big-endian byte order handling
5+
6+
import Testing
7+
@testable import IEEE_754
8+
9+
@Suite("IEEE 754 - Double Endianness")
10+
struct DoubleEndiannessTests {
11+
@Test(arguments: [3.14159, 2.71828, 1.41421, 0.0, 1.0, -1.0, 42.0])
12+
func `little-endian round-trip`(value: Double) {
13+
let bytes = value.bytes(endianness: .little)
14+
let restored = Double(bytes: bytes, endianness: .little)
15+
16+
#expect(restored == value, "\(value) should round-trip with little-endian")
17+
}
18+
19+
@Test(arguments: [3.14159, 2.71828, 1.41421, 0.0, 1.0, -1.0, 42.0])
20+
func `big-endian round-trip`(value: Double) {
21+
let bytes = value.bytes(endianness: .big)
22+
let restored = Double(bytes: bytes, endianness: .big)
23+
24+
#expect(restored == value, "\(value) should round-trip with big-endian")
25+
}
26+
27+
@Test(arguments: [3.14159, 2.71828, 1.41421])
28+
func `endianness produces different byte order`(value: Double) {
29+
let littleBytes = value.bytes(endianness: .little)
30+
let bigBytes = value.bytes(endianness: .big)
31+
32+
#expect(littleBytes != bigBytes, "Little and big endian should produce different byte order")
33+
#expect(littleBytes.count == bigBytes.count, "Both should produce same byte count")
34+
#expect(littleBytes == bigBytes.reversed(), "Big endian should be reverse of little endian")
35+
}
36+
37+
@Test func `default is little-endian`() {
38+
let value: Double = 3.14159
39+
let defaultBytes = value.bytes()
40+
let littleBytes = value.bytes(endianness: .little)
41+
42+
#expect(defaultBytes == littleBytes, "Default should be little-endian")
43+
}
44+
45+
@Test(arguments: [3.14159, 2.71828, 1.41421])
46+
func `mismatched endianness fails round-trip`(value: Double) {
47+
let littleBytes = value.bytes(endianness: .little)
48+
let wrongRestore = Double(bytes: littleBytes, endianness: .big)
49+
50+
// Intentionally wrong endianness should NOT equal original
51+
#expect(wrongRestore != value, "Mismatched endianness should fail round-trip")
52+
}
53+
}
54+
55+
@Suite("IEEE 754 - Float Endianness")
56+
struct FloatEndiannessTests {
57+
@Test(arguments: [Float(3.14159), Float(2.71828), Float(1.41421), Float(0.0), Float(1.0), Float(-1.0), Float(42.0)])
58+
func `little-endian round-trip`(value: Float) {
59+
let bytes = value.bytes(endianness: .little)
60+
let restored = Float(bytes: bytes, endianness: .little)
61+
62+
#expect(restored == value, "\(value) should round-trip with little-endian")
63+
}
64+
65+
@Test(arguments: [Float(3.14159), Float(2.71828), Float(1.41421), Float(0.0), Float(1.0), Float(-1.0), Float(42.0)])
66+
func `big-endian round-trip`(value: Float) {
67+
let bytes = value.bytes(endianness: .big)
68+
let restored = Float(bytes: bytes, endianness: .big)
69+
70+
#expect(restored == value, "\(value) should round-trip with big-endian")
71+
}
72+
73+
@Test(arguments: [Float(3.14159), Float(2.71828), Float(1.41421)])
74+
func `endianness produces different byte order`(value: Float) {
75+
let littleBytes = value.bytes(endianness: .little)
76+
let bigBytes = value.bytes(endianness: .big)
77+
78+
#expect(littleBytes != bigBytes, "Little and big endian should produce different byte order")
79+
#expect(littleBytes.count == bigBytes.count, "Both should produce same byte count")
80+
#expect(littleBytes == bigBytes.reversed(), "Big endian should be reverse of little endian")
81+
}
82+
83+
@Test func `default is little-endian`() {
84+
let value: Float = 3.14159
85+
let defaultBytes = value.bytes()
86+
let littleBytes = value.bytes(endianness: .little)
87+
88+
#expect(defaultBytes == littleBytes, "Default should be little-endian")
89+
}
90+
91+
@Test(arguments: [Float(3.14), Float(2.718), Float(1.414)])
92+
func `mismatched endianness fails round-trip`(value: Float) {
93+
let littleBytes = value.bytes(endianness: .little)
94+
let wrongRestore = Float(bytes: littleBytes, endianness: .big)
95+
96+
// Intentionally wrong endianness should NOT equal original
97+
#expect(wrongRestore != value, "Mismatched endianness should fail round-trip")
98+
}
99+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Float+IEEE_754 Tests.swift
2+
// swift-ieee-754
3+
//
4+
// Tests for Float IEEE 754 extensions
5+
6+
import Testing
7+
@testable import IEEE_754
8+
9+
@Suite("Float+IEEE_754 - Direct bytes() method")
10+
struct FloatDirectBytesTests {
11+
@Test(arguments: [
12+
Float(3.14159),
13+
Float(2.71828),
14+
Float(1.41421),
15+
Float(0.0),
16+
Float(-0.0),
17+
Float(1.0),
18+
Float(-1.0),
19+
])
20+
func `direct bytes round-trip`(value: Float) {
21+
let bytes = value.bytes()
22+
let restored = Float(bytes: bytes)
23+
24+
if value.isNaN {
25+
#expect(restored?.isNaN == true, "NaN should round-trip")
26+
} else if value == 0 && value.sign == .minus {
27+
// Negative zero
28+
#expect(restored == value && restored!.sign == .minus, "Negative zero should preserve sign")
29+
} else {
30+
#expect(restored == value, "\(value) should round-trip through bytes()")
31+
}
32+
}
33+
34+
@Test(arguments: [Float(3.14159), Float(2.71828), Float(1.41421)])
35+
func `direct bytes big-endian round-trip`(value: Float) {
36+
let bytes = value.bytes(endianness: .big)
37+
let restored = Float(bytes: bytes, endianness: .big)
38+
39+
#expect(restored == value, "\(value) should round-trip through bytes(endianness: .big)")
40+
}
41+
}
42+
43+
@Suite("Float+IEEE_754 - Namespace API")
44+
struct FloatNamespaceTests {
45+
@Test(arguments: [Float(3.14159), Float(2.71828), Float(1.41421)])
46+
func `namespace bytes round-trip`(value: Float) {
47+
let bytes = value.ieee754.bytes()
48+
let restored = Float(bytes: bytes)
49+
50+
#expect(restored == value, "\(value) should round-trip through ieee754.bytes()")
51+
}
52+
53+
@Test(arguments: [Float(3.14), Float(1.414), Float(2.718)])
54+
func `namespace type method`(value: Float) {
55+
let bytes = value.ieee754.bytes()
56+
let restored = Float.ieee754(bytes)
57+
58+
#expect(restored == value, "\(value) should round-trip through Float.ieee754()")
59+
}
60+
61+
@Test func `bitPattern property`() {
62+
let value: Float = 3.14159
63+
let pattern1 = value.bitPattern
64+
let pattern2 = value.ieee754.bitPattern
65+
66+
#expect(pattern1 == pattern2, "Direct and namespace bitPattern should match")
67+
}
68+
}
69+
70+
@Suite("Float+IEEE_754 - Canonical init")
71+
struct FloatCanonicalInitTests {
72+
@Test(arguments: [Float(3.14159), Float(2.71828), Float(1.41421), Float(0.0), Float(1.0), Float(-1.0)])
73+
func `canonical init bytes parameter`(value: Float) {
74+
let bytes = value.bytes()
75+
let restored = Float(bytes: bytes)
76+
77+
#expect(restored == value, "\(value) should round-trip through Float(bytes:)")
78+
}
79+
80+
@Test(arguments: [Float(3.14), Float(2.718), Float(1.414)])
81+
func `canonical init big-endian`(value: Float) {
82+
let bytes = value.bytes(endianness: .big)
83+
let restored = Float(bytes: bytes, endianness: .big)
84+
85+
#expect(restored == value, "\(value) should round-trip with big-endian")
86+
}
87+
88+
@Test func `invalid byte count returns nil`() {
89+
let tooFew = [UInt8](repeating: 0, count: 3)
90+
let tooMany = [UInt8](repeating: 0, count: 5)
91+
92+
#expect(Float(bytes: tooFew) == nil, "3 bytes should return nil")
93+
#expect(Float(bytes: tooMany) == nil, "5 bytes should return nil")
94+
}
95+
96+
@Test func `exactly 4 bytes succeeds`() {
97+
let exactlyFour = [UInt8](repeating: 0, count: 4)
98+
let result = Float(bytes: exactlyFour)
99+
100+
#expect(result != nil, "Exactly 4 bytes should succeed")
101+
#expect(result == 0.0, "All-zero bytes should decode to 0.0")
102+
}
103+
}

0 commit comments

Comments
 (0)