// RUN: %target-run-simple-swiftgyb // REQUIRES: executable_test import StdlibUnittest import StdlibCollectionUnittest import SwiftPrivate // FIXME(prext): fold this test into Algorithm.swift.gyb. var Algorithm = TestSuite("Algorithm") // Check if one array is a correctly sorted version of another array. // We can't simply sort both arrays and compare them, because it is needed to // check correctness of sorting itself. func expectSortedCollection(_ sortedAry: [Int], _ originalAry: [Int]) { expectEqual(sortedAry.count, originalAry.count) var sortedVals = [Int: Int]() var originalVals = [Int: Int]() // Keep track of what values we have in sortedAry. for e in sortedAry { if let v = sortedVals[e] { sortedVals[e] = v + 1 } else { sortedVals[e] = 0 } } // And do the same for originalAry. for e in originalAry { if let v = originalVals[e] { originalVals[e] = v + 1 } else { originalVals[e] = 0 } } // Now check if sets of elements are the same in both arrays. for (key, value) in sortedVals { expectNotNil(originalVals[key]) expectEqual(originalVals[key]!, value) } // Check if values in sortedAry are actually sorted. for i in 1.. ) { expectSortedCollection(sortedAry, Array(originalAry)) } func expectSortedCollection(_ sortedAry: ArraySlice, _ originalAry: ArraySlice) { expectSortedCollection([Int](sortedAry), [Int](originalAry)) } func expectSortedCollection(_ a: C, by areInIncreasingOrder: (C.Element, C.Element) -> Bool ) { expectFalse(zip(a.dropFirst(), a).contains(where: areInIncreasingOrder)) } class OffsetCollection : MutableCollection, RandomAccessCollection { typealias Indices = Range let offset: Int var data: [Int] = [] let forward: Bool var startIndex: Int { return forward ? offset : offset - data.count } var endIndex: Int { return forward ? offset + data.count : offset } subscript (i: Int) -> Int { get { return data[i - startIndex] } set { data[i - startIndex] = newValue } } func toArray() -> [Int] { return data } var count: Int { return data.count } init(_ ary: [Int], offset: Int, forward: Bool) { data = ary self.offset = offset self.forward = forward } typealias Index = Int subscript(bounds: Range) -> Slice { get { return Slice(base: self, bounds: bounds) } set { for i in bounds { self[i] = newValue[i] } } } } // Generate two versions of tests: one for sort with explicitly passed // predicate and the other using default comparison operator. % withArrayTypeNames = ["Array", "ContiguousArray"] % withPredicateValues = [True, False] % for t in withArrayTypeNames: // workaround for gyb miscompiles nested loops % for p in withPredicateValues: // workaround for gyb miscompiles nested loops % comparePredicate = "<" if p else "" % commaComparePredicate = ", by: <" if p else "" % name = "lessPredicate" if p else "noPredicate" Algorithm.test("${t}/sorted/${name}") { let count = 1000 let ary = ${t}((0 ..< count).map { _ in Int.random(in: .min ... .max) }) // Similar test for sorting with predicate % if comparePredicate: let sortedAry1 = ary.sorted(by: ${comparePredicate}) % else: let sortedAry1 = ary.sorted() % end expectSortedCollection(sortedAry1, ary) // Check that sorting works well on intervals let i1 = 400 let i2 = 700 var sortedAry2 = ary sortedAry2[i1..= first})) } runAllTests()