|
| 1 | +// RUN: rm -f %t.swift %t.out |
| 2 | + |
| 3 | +// RUN: %S/../../utils/gyb %s -o %t.swift |
| 4 | +// RUN: %S/../../utils/line-directive %t.swift -- %target-build-swift %t.swift -o %t.out |
| 5 | +// RUN: %S/../../utils/line-directive %t.swift -- %target-run %t.out |
| 6 | +// REQUIRES: executable_test |
| 7 | + |
| 8 | +import StdlibUnittest |
| 9 | + |
| 10 | +var TupleTestSuite = TestSuite("Tuple") |
| 11 | + |
| 12 | +// Test tuple comparison operators |
| 13 | +// all the tuple types use the same basic implementation for the operators |
| 14 | +// so testing any arity tests the logic for them all. |
| 15 | +// Include at least one invocation for all arities as a sanity check. |
| 16 | + |
| 17 | +% maxArity = 6 # the highest arity the operators are defined for |
| 18 | + |
| 19 | +func testEquality<A : Equatable, B : Equatable, C : Equatable>( |
| 20 | + lhs: (A,B,C), equal: Bool, to rhs: (A,B,C), |
| 21 | + //===--- TRACE boilerplate ----------------------------------------------===// |
| 22 | + @autoclosure _ message: ()->String = "", |
| 23 | + showFrame: Bool = true, |
| 24 | + stackTrace: SourceLocStack = SourceLocStack(), |
| 25 | + file: String = __FILE__, line: UInt = __LINE__ |
| 26 | +) { |
| 27 | + let trace = stackTrace.pushIf(showFrame, file: file, line: line) |
| 28 | + expectEqual(equal, lhs == rhs, stackTrace: trace) |
| 29 | + expectEqual(equal, rhs == lhs, stackTrace: trace) |
| 30 | + expectEqual(!equal, lhs != rhs, stackTrace: trace) |
| 31 | + expectEqual(!equal, rhs != lhs, stackTrace: trace) |
| 32 | +} |
| 33 | + |
| 34 | +TupleTestSuite.test("Tuple/equality") { |
| 35 | + testEquality((1,2,3), equal: true, to: (1,2,3)) |
| 36 | + testEquality((1,2,3), equal: false, to: (1,2,4)) |
| 37 | + testEquality((1,2,3), equal: false, to: (1,3,3)) |
| 38 | + testEquality((1,2,3), equal: false, to: (2,2,3)) |
| 39 | + testEquality((1,"2",3), equal: true, to: (1,"2",3)) |
| 40 | + testEquality((1,"2",3), equal: false, to: (1,"3",3)) |
| 41 | + testEquality(("one", 2.2, 3..<5), equal: true, to: ("one", 2.2, 3..<5)) |
| 42 | + |
| 43 | + testEquality((1.0, 2.0, 3.0), equal: false, to: (1.0, 2.0, .NaN)) |
| 44 | + testEquality((1.0, 2.0, 3.0), equal: false, to: (1.0, .NaN, 3.0)) |
| 45 | + testEquality((1.0, 2.0, 3.0), equal: false, to: (.NaN, 2.0, 3.0)) |
| 46 | + testEquality((1.0, 2.0, 3.0), equal: false, to: (.NaN, .NaN, .NaN)) |
| 47 | + testEquality((1.0, 2.0, Float.NaN), equal: false, to: (1.0, 2.0, 3.0)) |
| 48 | + testEquality((1.0, 2.0, Float.NaN), equal: false, to: (1.0, 2.0, Float.NaN)) |
| 49 | + testEquality((Float.NaN, Float.NaN, Float.NaN), equal: false, to: (.NaN, .NaN, .NaN)) |
| 50 | + testEquality((Float.NaN, Float.NaN, Float.NaN), equal: false, to: (1.0, 2.0, 3.0)) |
| 51 | + |
| 52 | + expectTrue((1,2) == (1,2)) |
| 53 | + expectTrue((1,2) != (1,3)) |
| 54 | + expectTrue((1,2,3,4) == (1,2,3,4)) |
| 55 | + expectTrue((1,2,3,4) != (1,2,3,3)) |
| 56 | + expectTrue((1,2,3,4,5) == (1,2,3,4,5)) |
| 57 | + expectTrue((1,2,3,4,5) != (1,2,3,4,4)) |
| 58 | + expectTrue((1,2,3,4,5,6) == (1,2,3,4,5,6)) |
| 59 | + expectTrue((1,2,3,4,5,6) != (1,2,3,4,5,5)) |
| 60 | +} |
| 61 | + |
| 62 | +TupleTestSuite.test("Tuple/equality/sanity-check") { |
| 63 | + // sanity check all arities |
| 64 | +% for arity in range(2,maxArity+1): |
| 65 | +% a = str(tuple(range(1, arity+1))) |
| 66 | +% b = "({}, 0)".format(", ".join([str(i) for i in range(1,arity)])) |
| 67 | +% c = "(0, {})".format(", ".join([str(i) for i in range(2,arity+1)])) |
| 68 | + expectTrue(${a} == ${a}) |
| 69 | + expectTrue(${a} != ${b}) |
| 70 | + expectTrue(${b} != ${a}) |
| 71 | + expectTrue(${a} != ${c}) |
| 72 | + expectTrue(${c} != ${a}) |
| 73 | +% end |
| 74 | +} |
| 75 | + |
| 76 | +enum Ordering : Equatable { |
| 77 | + case LessThan |
| 78 | + case EqualTo |
| 79 | + case GreaterThan |
| 80 | + case UnorderedWith // Comparable defines strict total order, but Float disobeys that with NaN |
| 81 | + |
| 82 | + var isLT: Bool { |
| 83 | + return self == .LessThan |
| 84 | + } |
| 85 | + var isEQ: Bool { |
| 86 | + return self == .EqualTo |
| 87 | + } |
| 88 | + var isGT: Bool { |
| 89 | + return self == .GreaterThan |
| 90 | + } |
| 91 | +} |
| 92 | + |
| 93 | +func testOrdering<A : Comparable, B : Comparable, C : Comparable>( |
| 94 | + lhs: (A,B,C), _ ordering: Ordering, _ rhs: (A, B, C), |
| 95 | + //===--- TRACE boilerplate ----------------------------------------------===// |
| 96 | + @autoclosure _ message: ()->String = "", |
| 97 | + showFrame: Bool = true, |
| 98 | + stackTrace: SourceLocStack = SourceLocStack(), |
| 99 | + file: String = __FILE__, line: UInt = __LINE__ |
| 100 | +) { |
| 101 | + let trace = stackTrace.pushIf(showFrame, file: file, line: line) |
| 102 | + expectEqual(ordering.isLT, lhs < rhs, stackTrace: trace) |
| 103 | + expectEqual(ordering.isLT, rhs > lhs, stackTrace: trace) |
| 104 | + expectEqual(ordering.isLT || ordering.isEQ, lhs <= rhs, stackTrace: trace) |
| 105 | + expectEqual(ordering.isLT || ordering.isEQ, rhs >= lhs, stackTrace: trace) |
| 106 | + expectEqual(ordering.isGT, lhs > rhs, stackTrace: trace) |
| 107 | + expectEqual(ordering.isGT, rhs < lhs, stackTrace: trace) |
| 108 | + expectEqual(ordering.isGT || ordering.isEQ, lhs >= rhs, stackTrace: trace) |
| 109 | + expectEqual(ordering.isGT || ordering.isEQ, rhs <= lhs, stackTrace: trace) |
| 110 | +} |
| 111 | + |
| 112 | +TupleTestSuite.test("Tuple/comparison") { |
| 113 | + testOrdering((1,2,3), .EqualTo, (1,2,3)) |
| 114 | + testOrdering((1,2,3), .LessThan, (1,2,4)) |
| 115 | + testOrdering((1,2,3), .GreaterThan, (1,2,2)) |
| 116 | + testOrdering((1,3,2), .GreaterThan, (1,2,3)) |
| 117 | + testOrdering((0,2,3), .LessThan, (1,2,3)) |
| 118 | + testOrdering((3,2,1), .GreaterThan, (1,2,3)) |
| 119 | + |
| 120 | + testOrdering(("one", 2, 3.3), .EqualTo, ("one", 2, 3.3)) |
| 121 | + testOrdering(("one", 2, 3.3), .LessThan, ("one", 2, 3.4)) |
| 122 | + testOrdering(("on", 2, 3.3), .LessThan, ("one", 1, 3.2)) |
| 123 | + |
| 124 | + testOrdering((1, 2, Float.NaN), .UnorderedWith, (1, 2, .NaN)) |
| 125 | + testOrdering((1, Float.NaN, 3), .UnorderedWith, (1, 2, 3)) |
| 126 | + testOrdering((Double.NaN, 2, 3), .UnorderedWith, (.NaN, 2, 3)) |
| 127 | + testOrdering((Float.NaN, Float.NaN, Float.NaN), .UnorderedWith, (1, 2, 3)) |
| 128 | + testOrdering((1, 2, 3.0), .UnorderedWith, (1, 2, .NaN)) |
| 129 | + testOrdering((1, 2, 3.0), .LessThan, (1, 3, .NaN)) |
| 130 | + testOrdering((1, 2, 3.0), .GreaterThan, (1, 1, .NaN)) |
| 131 | + testOrdering((1, 2.0, 3), .LessThan, (2, .NaN, 3)) |
| 132 | + testOrdering((1, 2.0, 3), .GreaterThan, (0, .NaN, 3)) |
| 133 | + testOrdering((1, 2, Float.NaN), .LessThan, (1, 3, 3.0)) |
| 134 | + testOrdering((1, Float.NaN, 3), .GreaterThan, (0, 2.0, 3)) |
| 135 | + testOrdering(("one", "two", 3.0), .GreaterThan, ("a", "b", .NaN)) |
| 136 | + testOrdering(("one", "two", .NaN), .GreaterThan, ("a", "b", 3.0)) |
| 137 | + testOrdering((1.0, "two", "three"), .UnorderedWith, (.NaN, "two", "four")) |
| 138 | + testOrdering((.NaN, "two", "three"), .UnorderedWith, (1.0, "two", "four")) |
| 139 | +} |
| 140 | + |
| 141 | +TupleTestSuite.test("Tuple/comparison/sanity-check") { |
| 142 | + // sanity check all arities |
| 143 | +% for arity in range(2,maxArity+1): |
| 144 | +% a = str(tuple(range(1, arity+1))) |
| 145 | +% b = "({}, 0)".format(", ".join([str(i) for i in range(1,arity)])) |
| 146 | +% c = "(0, {})".format(", ".join([str(i) for i in range(2,arity+1)])) |
| 147 | + expectTrue(${b} < ${a}) |
| 148 | + expectTrue(${b} <= ${a}) |
| 149 | + expectTrue(${a} > ${c}) |
| 150 | + expectTrue(${a} >= ${c}) |
| 151 | +% end |
| 152 | +} |
| 153 | + |
| 154 | +runAllTests() |
0 commit comments