PrimitiveListTests.swift 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2017 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. // swiftlint:disable type_name identifier_name statement_position cyclomatic_complexity
  19. import XCTest
  20. import RealmSwift
  21. protocol ObjectFactory {
  22. static func isManaged() -> Bool
  23. }
  24. final class ManagedObjectFactory: ObjectFactory {
  25. static func isManaged() -> Bool { return true }
  26. }
  27. final class UnmanagedObjectFactory: ObjectFactory {
  28. static func isManaged() -> Bool { return false }
  29. }
  30. protocol ValueFactory {
  31. associatedtype T: RealmCollectionValue
  32. associatedtype W: RealmCollectionValue = T
  33. static func array(_ obj: SwiftListObject) -> List<T>
  34. static func values() -> [T]
  35. }
  36. final class IntFactory: ValueFactory {
  37. static func array(_ obj: SwiftListObject) -> List<Int> {
  38. return obj.int
  39. }
  40. static func values() -> [Int] {
  41. return [1, 2, 3]
  42. }
  43. }
  44. final class Int8Factory: ValueFactory {
  45. static func array(_ obj: SwiftListObject) -> List<Int8> {
  46. return obj.int8
  47. }
  48. static func values() -> [Int8] {
  49. return [1, 2, 3]
  50. }
  51. }
  52. final class Int16Factory: ValueFactory {
  53. static func array(_ obj: SwiftListObject) -> List<Int16> {
  54. return obj.int16
  55. }
  56. static func values() -> [Int16] {
  57. return [1, 2, 3]
  58. }
  59. }
  60. final class Int32Factory: ValueFactory {
  61. static func array(_ obj: SwiftListObject) -> List<Int32> {
  62. return obj.int32
  63. }
  64. static func values() -> [Int32] {
  65. return [1, 2, 3]
  66. }
  67. }
  68. final class Int64Factory: ValueFactory {
  69. static func array(_ obj: SwiftListObject) -> List<Int64> {
  70. return obj.int64
  71. }
  72. static func values() -> [Int64] {
  73. return [1, 2, 3]
  74. }
  75. }
  76. final class FloatFactory: ValueFactory {
  77. static func array(_ obj: SwiftListObject) -> List<Float> {
  78. return obj.float
  79. }
  80. static func values() -> [Float] {
  81. return [1.1, 2.2, 3.3]
  82. }
  83. }
  84. final class DoubleFactory: ValueFactory {
  85. static func array(_ obj: SwiftListObject) -> List<Double> {
  86. return obj.double
  87. }
  88. static func values() -> [Double] {
  89. return [1.1, 2.2, 3.3]
  90. }
  91. }
  92. final class StringFactory: ValueFactory {
  93. static func array(_ obj: SwiftListObject) -> List<String> {
  94. return obj.string
  95. }
  96. static func values() -> [String] {
  97. return ["a", "b", "c"]
  98. }
  99. }
  100. final class DataFactory: ValueFactory {
  101. static func array(_ obj: SwiftListObject) -> List<Data> {
  102. return obj.data
  103. }
  104. static func values() -> [Data] {
  105. return ["a".data(using: .utf8)!, "b".data(using: .utf8)!, "c".data(using: .utf8)!]
  106. }
  107. }
  108. final class DateFactory: ValueFactory {
  109. static func array(_ obj: SwiftListObject) -> List<Date> {
  110. return obj.date
  111. }
  112. static func values() -> [Date] {
  113. return [Date(), Date().addingTimeInterval(10), Date().addingTimeInterval(20)]
  114. }
  115. }
  116. final class OptionalIntFactory: ValueFactory {
  117. typealias W = Int
  118. static func array(_ obj: SwiftListObject) -> List<Int?> {
  119. return obj.intOpt
  120. }
  121. static func values() -> [Int?] {
  122. return [nil, 1, 3]
  123. }
  124. }
  125. final class OptionalInt8Factory: ValueFactory {
  126. typealias W = Int8
  127. static func array(_ obj: SwiftListObject) -> List<Int8?> {
  128. return obj.int8Opt
  129. }
  130. static func values() -> [Int8?] {
  131. return [nil, 1, 3]
  132. }
  133. }
  134. final class OptionalInt16Factory: ValueFactory {
  135. typealias W = Int16
  136. static func array(_ obj: SwiftListObject) -> List<Int16?> {
  137. return obj.int16Opt
  138. }
  139. static func values() -> [Int16?] {
  140. return [nil, 1, 3]
  141. }
  142. }
  143. final class OptionalInt32Factory: ValueFactory {
  144. typealias W = Int32
  145. static func array(_ obj: SwiftListObject) -> List<Int32?> {
  146. return obj.int32Opt
  147. }
  148. static func values() -> [Int32?] {
  149. return [nil, 1, 3]
  150. }
  151. }
  152. final class OptionalInt64Factory: ValueFactory {
  153. typealias W = Int64
  154. static func array(_ obj: SwiftListObject) -> List<Int64?> {
  155. return obj.int64Opt
  156. }
  157. static func values() -> [Int64?] {
  158. return [nil, 1, 3]
  159. }
  160. }
  161. final class OptionalFloatFactory: ValueFactory {
  162. typealias W = Float
  163. static func array(_ obj: SwiftListObject) -> List<Float?> {
  164. return obj.floatOpt
  165. }
  166. static func values() -> [Float?] {
  167. return [nil, 1.1, 3.3]
  168. }
  169. }
  170. final class OptionalDoubleFactory: ValueFactory {
  171. typealias W = Double
  172. static func array(_ obj: SwiftListObject) -> List<Double?> {
  173. return obj.doubleOpt
  174. }
  175. static func values() -> [Double?] {
  176. return [nil, 1.1, 3.3]
  177. }
  178. }
  179. final class OptionalStringFactory: ValueFactory {
  180. typealias W = String
  181. static func array(_ obj: SwiftListObject) -> List<String?> {
  182. return obj.stringOpt
  183. }
  184. static func values() -> [String?] {
  185. return [nil, "a", "c"]
  186. }
  187. }
  188. final class OptionalDataFactory: ValueFactory {
  189. typealias W = Data
  190. static func array(_ obj: SwiftListObject) -> List<Data?> {
  191. return obj.dataOpt
  192. }
  193. static func values() -> [Data?] {
  194. return [nil, "a".data(using: .utf8), "c".data(using: .utf8)]
  195. }
  196. }
  197. final class OptionalDateFactory: ValueFactory {
  198. typealias W = Date
  199. static func array(_ obj: SwiftListObject) -> List<Date?> {
  200. return obj.dateOpt
  201. }
  202. static func values() -> [Date?] {
  203. return [nil, Date(), Date().addingTimeInterval(20)]
  204. }
  205. }
  206. // Older versions of swift only support three version components in top-level
  207. // #if, so this check to be done outside the class...
  208. #if swift(>=3.4) && (swift(>=4.1.50) || !swift(>=4))
  209. class EquatableTestCase: TestCase {
  210. func assertEqualTo<T: Equatable>(_ expected: T, _ actual: T, fileName: StaticString = #file, lineNumber: UInt = #line) {
  211. XCTAssertEqual(expected, actual, file: fileName, line: lineNumber)
  212. }
  213. }
  214. #else
  215. class EquatableTestCase: TestCase {
  216. // writing value as! Int? gives "cannot downcast from 'T' to a more optional type 'Optional<Int>'"
  217. // but doing this nonsense works
  218. func cast<T, U>(_ value: T) -> U {
  219. return value as! U
  220. }
  221. // No conditional conformance means that Optional<T: Equatable> can't
  222. // itself conform to Equatable
  223. func assertEqualTo<T>(_ expected: T, _ actual: T, fileName: StaticString = #file, lineNumber: UInt = #line) {
  224. if T.self is Int.Type {
  225. XCTAssertEqual(expected as! Int, actual as! Int, file: fileName, line: lineNumber)
  226. }
  227. else if T.self is Float.Type {
  228. XCTAssertEqual(expected as! Float, actual as! Float, file: fileName, line: lineNumber)
  229. }
  230. else if T.self is Double.Type {
  231. XCTAssertEqual(expected as! Double, actual as! Double, file: fileName, line: lineNumber)
  232. }
  233. else if T.self is Bool.Type {
  234. XCTAssertEqual(expected as! Bool, actual as! Bool, file: fileName, line: lineNumber)
  235. }
  236. else if T.self is Int8.Type {
  237. XCTAssertEqual(expected as! Int8, actual as! Int8, file: fileName, line: lineNumber)
  238. }
  239. else if T.self is Int16.Type {
  240. XCTAssertEqual(expected as! Int16, actual as! Int16, file: fileName, line: lineNumber)
  241. }
  242. else if T.self is Int32.Type {
  243. XCTAssertEqual(expected as! Int32, actual as! Int32, file: fileName, line: lineNumber)
  244. }
  245. else if T.self is Int64.Type {
  246. XCTAssertEqual(expected as! Int64, actual as! Int64, file: fileName, line: lineNumber)
  247. }
  248. else if T.self is String.Type {
  249. XCTAssertEqual(expected as! String, actual as! String, file: fileName, line: lineNumber)
  250. }
  251. else if T.self is Data.Type {
  252. XCTAssertEqual(expected as! Data, actual as! Data, file: fileName, line: lineNumber)
  253. }
  254. else if T.self is Date.Type {
  255. XCTAssertEqual(expected as! Date, actual as! Date, file: fileName, line: lineNumber)
  256. }
  257. else if T.self is [Int].Type {
  258. XCTAssertEqual(expected as! [Int], actual as! [Int], file: fileName, line: lineNumber)
  259. }
  260. else if T.self is [Float].Type {
  261. XCTAssertEqual(expected as! [Float], actual as! [Float], file: fileName, line: lineNumber)
  262. }
  263. else if T.self is [Double].Type {
  264. XCTAssertEqual(expected as! [Double], actual as! [Double], file: fileName, line: lineNumber)
  265. }
  266. else if T.self is [Bool].Type {
  267. XCTAssertEqual(expected as! [Bool], actual as! [Bool], file: fileName, line: lineNumber)
  268. }
  269. else if T.self is [Int8].Type {
  270. XCTAssertEqual(expected as! [Int8], actual as! [Int8], file: fileName, line: lineNumber)
  271. }
  272. else if T.self is [Int16].Type {
  273. XCTAssertEqual(expected as! [Int16], actual as! [Int16], file: fileName, line: lineNumber)
  274. }
  275. else if T.self is [Int32].Type {
  276. XCTAssertEqual(expected as! [Int32], actual as! [Int32], file: fileName, line: lineNumber)
  277. }
  278. else if T.self is [Int64].Type {
  279. XCTAssertEqual(expected as! [Int64], actual as! [Int64], file: fileName, line: lineNumber)
  280. }
  281. else if T.self is [String].Type {
  282. XCTAssertEqual(expected as! [String], actual as! [String], file: fileName, line: lineNumber)
  283. }
  284. else if T.self is [Data].Type {
  285. XCTAssertEqual(expected as! [Data], actual as! [Data], file: fileName, line: lineNumber)
  286. }
  287. else if T.self is [Date].Type {
  288. XCTAssertEqual(expected as! [Date], actual as! [Date], file: fileName, line: lineNumber)
  289. }
  290. else if T.self is Int?.Type {
  291. XCTAssertEqual(cast(expected) as Int?, cast(actual) as Int?, file: fileName, line: lineNumber)
  292. }
  293. else if T.self is Float?.Type {
  294. XCTAssertEqual(cast(expected) as Float?, cast(actual) as Float?, file: fileName, line: lineNumber)
  295. }
  296. else if T.self is Double?.Type {
  297. XCTAssertEqual(cast(expected) as Double?, cast(actual) as Double?, file: fileName, line: lineNumber)
  298. }
  299. else if T.self is Bool?.Type {
  300. XCTAssertEqual(cast(expected) as Bool?, cast(actual) as Bool?, file: fileName, line: lineNumber)
  301. }
  302. else if T.self is Int8?.Type {
  303. XCTAssertEqual(cast(expected) as Int8?, cast(actual) as Int8?, file: fileName, line: lineNumber)
  304. }
  305. else if T.self is Int16?.Type {
  306. XCTAssertEqual(cast(expected) as Int16?, cast(actual) as Int16?, file: fileName, line: lineNumber)
  307. }
  308. else if T.self is Int32?.Type {
  309. XCTAssertEqual(cast(expected) as Int32?, cast(actual) as Int32?, file: fileName, line: lineNumber)
  310. }
  311. else if T.self is Int64?.Type {
  312. XCTAssertEqual(cast(expected) as Int64?, cast(actual) as Int64?, file: fileName, line: lineNumber)
  313. }
  314. else if T.self is String?.Type {
  315. XCTAssertEqual(cast(expected) as String?, cast(actual) as String?, file: fileName, line: lineNumber)
  316. }
  317. else if T.self is Data?.Type {
  318. XCTAssertEqual(cast(expected) as Data?, cast(actual) as Data?, file: fileName, line: lineNumber)
  319. }
  320. else if T.self is Date?.Type {
  321. XCTAssertEqual(cast(expected) as Date?, cast(actual) as Date?, file: fileName, line: lineNumber)
  322. }
  323. else if T.self is [Int?].Type {
  324. assertEqual(cast(expected) as [Int?], cast(actual) as [Int?], file: fileName, line: lineNumber)
  325. }
  326. else if T.self is [Float?].Type {
  327. assertEqual(cast(expected) as [Float?], cast(actual) as [Float?], file: fileName, line: lineNumber)
  328. }
  329. else if T.self is [Double?].Type {
  330. assertEqual(cast(expected) as [Double?], cast(actual) as [Double?], file: fileName, line: lineNumber)
  331. }
  332. else if T.self is [Bool?].Type {
  333. assertEqual(cast(expected) as [Bool?], cast(actual) as [Bool?], file: fileName, line: lineNumber)
  334. }
  335. else if T.self is [Int8?].Type {
  336. assertEqual(cast(expected) as [Int8?], cast(actual) as [Int8?], file: fileName, line: lineNumber)
  337. }
  338. else if T.self is [Int16?].Type {
  339. assertEqual(cast(expected) as [Int16?], cast(actual) as [Int16?], file: fileName, line: lineNumber)
  340. }
  341. else if T.self is [Int32?].Type {
  342. assertEqual(cast(expected) as [Int32?], cast(actual) as [Int32?], file: fileName, line: lineNumber)
  343. }
  344. else if T.self is [Int64?].Type {
  345. assertEqual(cast(expected) as [Int64?], cast(actual) as [Int64?], file: fileName, line: lineNumber)
  346. }
  347. else if T.self is [String?].Type {
  348. assertEqual(cast(expected) as [String?], cast(actual) as [String?], file: fileName, line: lineNumber)
  349. }
  350. else if T.self is [Data?].Type {
  351. assertEqual(cast(expected) as [Data?], cast(actual) as [Data?], file: fileName, line: lineNumber)
  352. }
  353. else if T.self is [Date?].Type {
  354. assertEqual(cast(expected) as [Date?], cast(actual) as [Date?], file: fileName, line: lineNumber)
  355. }
  356. else {
  357. XCTFail("unsupported type \(T.self)", file: fileName, line: lineNumber)
  358. fatalError("unsupported type \(T.self)")
  359. }
  360. }
  361. func assertEqualTo<T>(_ expected: T?, _ actual: T?, fileName: StaticString = #file, lineNumber: UInt = #line) {
  362. if expected == nil {
  363. XCTAssertNil(actual, file: fileName, line: lineNumber)
  364. }
  365. else if actual == nil {
  366. XCTFail("nil")
  367. }
  368. else {
  369. assertEqualTo(expected!, actual!, fileName: fileName, lineNumber: lineNumber)
  370. }
  371. }
  372. func assertEqualTo<T>(_ expected: T, _ actual: T?) {
  373. guard let actual = actual else {
  374. XCTFail("nil")
  375. return
  376. }
  377. assertEqualTo(expected, actual)
  378. }
  379. }
  380. #endif
  381. class PrimitiveListTestsBase<O: ObjectFactory, V: ValueFactory>: EquatableTestCase {
  382. var realm: Realm?
  383. var obj: SwiftListObject!
  384. var array: List<V.T>!
  385. var values: [V.T]!
  386. #if swift(>=4)
  387. class func _defaultTestSuite() -> XCTestSuite {
  388. return defaultTestSuite
  389. }
  390. #else
  391. class func _defaultTestSuite() -> XCTestSuite {
  392. return defaultTestSuite()
  393. }
  394. #endif
  395. override func setUp() {
  396. obj = SwiftListObject()
  397. if O.isManaged() {
  398. let config = Realm.Configuration(inMemoryIdentifier: "test", objectTypes: [SwiftListObject.self])
  399. realm = try! Realm(configuration: config)
  400. realm!.beginWrite()
  401. realm!.add(obj)
  402. }
  403. array = V.array(obj)
  404. values = V.values()
  405. }
  406. override func tearDown() {
  407. realm?.cancelWrite()
  408. realm = nil
  409. array = nil
  410. obj = nil
  411. }
  412. }
  413. class PrimitiveListTests<O: ObjectFactory, V: ValueFactory>: PrimitiveListTestsBase<O, V> {
  414. func testInvalidated() {
  415. XCTAssertFalse(array.isInvalidated)
  416. if let realm = obj.realm {
  417. realm.delete(obj)
  418. XCTAssertTrue(array.isInvalidated)
  419. }
  420. }
  421. func testIndexOf() {
  422. XCTAssertNil(array.index(of: values[0]))
  423. array.append(values[0])
  424. assertEqualTo(0, array.index(of: values[0]))
  425. array.append(values[1])
  426. assertEqualTo(0, array.index(of: values[0]))
  427. assertEqualTo(1, array.index(of: values[1]))
  428. }
  429. // FIXME: Not yet implemented
  430. func disabled_testIndexMatching() {
  431. XCTAssertNil(array.index(matching: "self = %@", values[0]))
  432. array.append(values[0])
  433. assertEqualTo(0, array.index(matching: "self = %@", values[0]))
  434. array.append(values[1])
  435. assertEqualTo(0, array.index(matching: "self = %@", values[0]))
  436. assertEqualTo(1, array.index(matching: "self = %@", values[1]))
  437. }
  438. func testSubscript() {
  439. array.append(objectsIn: values)
  440. for i in 0..<values.count {
  441. assertEqualTo(array[i], values[i])
  442. }
  443. assertThrows(array[values.count], reason: "Index 3 is out of bounds")
  444. assertThrows(array[-1], reason: "negative value")
  445. }
  446. func testFirst() {
  447. array.append(objectsIn: values)
  448. assertEqualTo(array.first, values.first)
  449. array.removeAll()
  450. XCTAssertNil(array.first)
  451. }
  452. func testLast() {
  453. array.append(objectsIn: values)
  454. assertEqualTo(array.last, values.last)
  455. array.removeAll()
  456. XCTAssertNil(array.last)
  457. }
  458. func testValueForKey() {
  459. assertEqualTo(array.value(forKey: "self").count, 0)
  460. array.append(objectsIn: values)
  461. assertEqualTo(values!, array.value(forKey: "self").map { dynamicBridgeCast(fromObjectiveC: $0) as V.T })
  462. assertThrows(array.value(forKey: "not self"), named: "NSUnknownKeyException")
  463. }
  464. func testSetValueForKey() {
  465. // does this even make any sense?
  466. }
  467. func testFilter() {
  468. // not implemented
  469. }
  470. func testInsert() {
  471. assertEqualTo(Int(0), array.count)
  472. array.insert(values[0], at: 0)
  473. assertEqualTo(Int(1), array.count)
  474. assertEqualTo(values[0], array[0])
  475. array.insert(values[1], at: 0)
  476. assertEqualTo(Int(2), array.count)
  477. assertEqualTo(values[1], array[0])
  478. assertEqualTo(values[0], array[1])
  479. array.insert(values[2], at: 2)
  480. assertEqualTo(Int(3), array.count)
  481. assertEqualTo(values[1], array[0])
  482. assertEqualTo(values[0], array[1])
  483. assertEqualTo(values[2], array[2])
  484. assertThrows(_ = array.insert(values[0], at: 4))
  485. assertThrows(_ = array.insert(values[0], at: -1))
  486. }
  487. func testRemove() {
  488. assertThrows(array.remove(at: 0))
  489. assertThrows(array.remove(at: -1))
  490. array.append(objectsIn: values)
  491. assertThrows(array.remove(at: -1))
  492. assertEqualTo(values[0], array[0])
  493. assertEqualTo(values[1], array[1])
  494. assertEqualTo(values[2], array[2])
  495. assertThrows(array[3])
  496. array.remove(at: 0)
  497. assertEqualTo(values[1], array[0])
  498. assertEqualTo(values[2], array[1])
  499. assertThrows(array[2])
  500. assertThrows(array.remove(at: 2))
  501. array.remove(at: 1)
  502. assertEqualTo(values[1], array[0])
  503. assertThrows(array[1])
  504. }
  505. func testRemoveLast() {
  506. assertThrows(array.removeLast())
  507. array.append(objectsIn: values)
  508. array.removeLast()
  509. assertEqualTo(array.count, 2)
  510. assertEqualTo(values[0], array[0])
  511. assertEqualTo(values[1], array[1])
  512. array.removeLast(2)
  513. assertEqualTo(array.count, 0)
  514. }
  515. func testRemoveAll() {
  516. array.removeAll()
  517. array.append(objectsIn: values)
  518. array.removeAll()
  519. assertEqualTo(array.count, 0)
  520. }
  521. func testReplace() {
  522. assertThrows(array.replace(index: 0, object: values[0]),
  523. reason: "Index 0 is out of bounds")
  524. array.append(objectsIn: values)
  525. array.replace(index: 1, object: values[0])
  526. assertEqualTo(array[0], values[0])
  527. assertEqualTo(array[1], values[0])
  528. assertEqualTo(array[2], values[2])
  529. assertThrows(array.replace(index: 3, object: values[0]),
  530. reason: "Index 3 is out of bounds")
  531. assertThrows(array.replace(index: -1, object: values[0]),
  532. reason: "Cannot pass a negative value")
  533. }
  534. func testReplaceRange() {
  535. assertSucceeds { array.replaceSubrange(0..<0, with: []) }
  536. #if false
  537. // FIXME: The exception thrown here runs afoul of Swift's exclusive access checking.
  538. assertThrows(array.replaceSubrange(0..<1, with: []),
  539. reason: "Index 0 is out of bounds")
  540. #endif
  541. array.replaceSubrange(0..<0, with: [values[0]])
  542. XCTAssertEqual(array.count, 1)
  543. assertEqualTo(array[0], values[0])
  544. array.replaceSubrange(0..<1, with: values)
  545. XCTAssertEqual(array.count, 3)
  546. array.replaceSubrange(1..<2, with: [])
  547. XCTAssertEqual(array.count, 2)
  548. assertEqualTo(array[0], values[0])
  549. assertEqualTo(array[1], values[2])
  550. }
  551. func testMove() {
  552. assertThrows(array.move(from: 1, to: 0), reason: "out of bounds")
  553. array.append(objectsIn: values)
  554. array.move(from: 2, to: 0)
  555. assertEqualTo(array[0], values[2])
  556. assertEqualTo(array[1], values[0])
  557. assertEqualTo(array[2], values[1])
  558. assertThrows(array.move(from: 3, to: 0), reason: "Index 3 is out of bounds")
  559. assertThrows(array.move(from: 0, to: 3), reason: "Index 3 is out of bounds")
  560. assertThrows(array.move(from: -1, to: 0), reason: "negative value")
  561. assertThrows(array.move(from: 0, to: -1), reason: "negative value")
  562. }
  563. func testSwap() {
  564. assertThrows(array.swapAt(0, 1), reason: "out of bounds")
  565. array.append(objectsIn: values)
  566. array.swapAt(0, 2)
  567. assertEqualTo(array[0], values[2])
  568. assertEqualTo(array[1], values[1])
  569. assertEqualTo(array[2], values[0])
  570. assertThrows(array.swapAt(3, 0), reason: "Index 3 is out of bounds")
  571. assertThrows(array.swapAt(0, 3), reason: "Index 3 is out of bounds")
  572. assertThrows(array.swapAt(-1, 0), reason: "negative value")
  573. assertThrows(array.swapAt(0, -1), reason: "negative value")
  574. }
  575. }
  576. class MinMaxPrimitiveListTests<O: ObjectFactory, V: ValueFactory>: PrimitiveListTestsBase<O, V> where V.T: MinMaxType {
  577. func testMin() {
  578. XCTAssertNil(array.min())
  579. array.append(objectsIn: values.reversed())
  580. assertEqualTo(array.min(), values.first)
  581. }
  582. func testMax() {
  583. XCTAssertNil(array.max())
  584. array.append(objectsIn: values.reversed())
  585. assertEqualTo(array.max(), values.last)
  586. }
  587. }
  588. class OptionalMinMaxPrimitiveListTests<O: ObjectFactory, V: ValueFactory>: PrimitiveListTestsBase<O, V> where V.W: MinMaxType {
  589. // V.T and V.W? are the same thing, but the type system doesn't know that
  590. // and the protocol constraint is on V.W
  591. var array2: List<V.W?> {
  592. return unsafeDowncast(array!, to: List<V.W?>.self)
  593. }
  594. func testMin() {
  595. XCTAssertNil(array2.min())
  596. array.append(objectsIn: values.reversed())
  597. let expected = values[1] as! V.W
  598. assertEqualTo(array2.min(), expected)
  599. }
  600. func testMax() {
  601. XCTAssertNil(array2.max())
  602. array.append(objectsIn: values.reversed())
  603. let expected = values[2] as! V.W
  604. assertEqualTo(array2.max(), expected)
  605. }
  606. }
  607. class AddablePrimitiveListTests<O: ObjectFactory, V: ValueFactory>: PrimitiveListTestsBase<O, V> where V.T: AddableType {
  608. func testSum() {
  609. assertEqualTo(array.sum(), V.T())
  610. array.append(objectsIn: values)
  611. // Expressing "can be added and converted to a floating point type" as
  612. // a protocol requirement is awful, so sidestep it all with obj-c
  613. let expected = ((values.map(dynamicBridgeCast) as NSArray).value(forKeyPath: "@sum.self")! as! NSNumber).doubleValue
  614. let actual: V.T = array.sum()
  615. XCTAssertEqual((dynamicBridgeCast(fromSwift: actual) as! NSNumber).doubleValue, expected, accuracy: 0.01)
  616. }
  617. func testAverage() {
  618. XCTAssertNil(array.average())
  619. array.append(objectsIn: values)
  620. let expected = ((values.map(dynamicBridgeCast) as NSArray).value(forKeyPath: "@avg.self")! as! NSNumber).doubleValue
  621. XCTAssertEqual(array.average()!, expected, accuracy: 0.01)
  622. }
  623. }
  624. class OptionalAddablePrimitiveListTests<O: ObjectFactory, V: ValueFactory>: PrimitiveListTestsBase<O, V> where V.W: AddableType {
  625. // V.T and V.W? are the same thing, but the type system doesn't know that
  626. // and the protocol constraint is on V.W
  627. var array2: List<V.W?> {
  628. return unsafeDowncast(array!, to: List<V.W?>.self)
  629. }
  630. func testSum() {
  631. assertEqualTo(array2.sum(), V.W())
  632. array.append(objectsIn: values)
  633. var nonNil = values!
  634. nonNil.remove(at: 0)
  635. // Expressing "can be added and converted to a floating point type" as
  636. // a protocol requirement is awful, so sidestep it all with obj-c
  637. let expected = ((nonNil.map(dynamicBridgeCast) as NSArray).value(forKeyPath: "@sum.self")! as! NSNumber).doubleValue
  638. let actual: V.W = array2.sum()
  639. XCTAssertEqual((dynamicBridgeCast(fromSwift: actual) as! NSNumber).doubleValue, expected, accuracy: 0.01)
  640. }
  641. func testAverage() {
  642. XCTAssertNil(array2.average())
  643. array.append(objectsIn: values)
  644. var nonNil = values!
  645. nonNil.remove(at: 0)
  646. let expected = ((nonNil.map(dynamicBridgeCast) as NSArray).value(forKeyPath: "@avg.self")! as! NSNumber).doubleValue
  647. XCTAssertEqual(array2.average()!, expected, accuracy: 0.01)
  648. }
  649. }
  650. class SortablePrimitiveListTests<O: ObjectFactory, V: ValueFactory>: PrimitiveListTestsBase<O, V> where V.T: Comparable {
  651. func testSorted() {
  652. var shuffled = values!
  653. shuffled.removeFirst()
  654. shuffled.append(values!.first!)
  655. array.append(objectsIn: shuffled)
  656. assertEqual(Array(array.sorted(ascending: true)), values)
  657. assertEqual(Array(array.sorted(ascending: false)), values.reversed())
  658. }
  659. }
  660. class OptionalSortablePrimitiveListTests<O: ObjectFactory, V: ValueFactory>: PrimitiveListTestsBase<O, V> where V.W: Comparable {
  661. func testSorted() {
  662. var shuffled = values!
  663. shuffled.removeFirst()
  664. shuffled.append(values!.first!)
  665. array.append(objectsIn: shuffled)
  666. let array2 = unsafeDowncast(array!, to: List<V.W?>.self)
  667. let values2 = unsafeBitCast(values!, to: Array<V.W?>.self)
  668. assertEqual(Array(array2.sorted(ascending: true)), values2)
  669. assertEqual(Array(array2.sorted(ascending: false)), values2.reversed())
  670. }
  671. }
  672. func addTests<OF: ObjectFactory>(_ suite: XCTestSuite, _ type: OF.Type) {
  673. _ = PrimitiveListTests<OF, IntFactory>._defaultTestSuite().tests.map(suite.addTest)
  674. _ = PrimitiveListTests<OF, Int8Factory>._defaultTestSuite().tests.map(suite.addTest)
  675. _ = PrimitiveListTests<OF, Int16Factory>._defaultTestSuite().tests.map(suite.addTest)
  676. _ = PrimitiveListTests<OF, Int32Factory>._defaultTestSuite().tests.map(suite.addTest)
  677. _ = PrimitiveListTests<OF, Int64Factory>._defaultTestSuite().tests.map(suite.addTest)
  678. _ = PrimitiveListTests<OF, FloatFactory>._defaultTestSuite().tests.map(suite.addTest)
  679. _ = PrimitiveListTests<OF, DoubleFactory>._defaultTestSuite().tests.map(suite.addTest)
  680. _ = PrimitiveListTests<OF, StringFactory>._defaultTestSuite().tests.map(suite.addTest)
  681. _ = PrimitiveListTests<OF, DataFactory>._defaultTestSuite().tests.map(suite.addTest)
  682. _ = PrimitiveListTests<OF, DateFactory>._defaultTestSuite().tests.map(suite.addTest)
  683. _ = MinMaxPrimitiveListTests<OF, IntFactory>._defaultTestSuite().tests.map(suite.addTest)
  684. _ = MinMaxPrimitiveListTests<OF, Int8Factory>._defaultTestSuite().tests.map(suite.addTest)
  685. _ = MinMaxPrimitiveListTests<OF, Int16Factory>._defaultTestSuite().tests.map(suite.addTest)
  686. _ = MinMaxPrimitiveListTests<OF, Int32Factory>._defaultTestSuite().tests.map(suite.addTest)
  687. _ = MinMaxPrimitiveListTests<OF, Int64Factory>._defaultTestSuite().tests.map(suite.addTest)
  688. _ = MinMaxPrimitiveListTests<OF, FloatFactory>._defaultTestSuite().tests.map(suite.addTest)
  689. _ = MinMaxPrimitiveListTests<OF, DoubleFactory>._defaultTestSuite().tests.map(suite.addTest)
  690. _ = MinMaxPrimitiveListTests<OF, DateFactory>._defaultTestSuite().tests.map(suite.addTest)
  691. _ = AddablePrimitiveListTests<OF, IntFactory>._defaultTestSuite().tests.map(suite.addTest)
  692. _ = AddablePrimitiveListTests<OF, Int8Factory>._defaultTestSuite().tests.map(suite.addTest)
  693. _ = AddablePrimitiveListTests<OF, Int16Factory>._defaultTestSuite().tests.map(suite.addTest)
  694. _ = AddablePrimitiveListTests<OF, Int32Factory>._defaultTestSuite().tests.map(suite.addTest)
  695. _ = AddablePrimitiveListTests<OF, Int64Factory>._defaultTestSuite().tests.map(suite.addTest)
  696. _ = AddablePrimitiveListTests<OF, FloatFactory>._defaultTestSuite().tests.map(suite.addTest)
  697. _ = AddablePrimitiveListTests<OF, DoubleFactory>._defaultTestSuite().tests.map(suite.addTest)
  698. _ = PrimitiveListTests<OF, OptionalIntFactory>._defaultTestSuite().tests.map(suite.addTest)
  699. _ = PrimitiveListTests<OF, OptionalInt8Factory>._defaultTestSuite().tests.map(suite.addTest)
  700. _ = PrimitiveListTests<OF, OptionalInt16Factory>._defaultTestSuite().tests.map(suite.addTest)
  701. _ = PrimitiveListTests<OF, OptionalInt32Factory>._defaultTestSuite().tests.map(suite.addTest)
  702. _ = PrimitiveListTests<OF, OptionalInt64Factory>._defaultTestSuite().tests.map(suite.addTest)
  703. _ = PrimitiveListTests<OF, OptionalFloatFactory>._defaultTestSuite().tests.map(suite.addTest)
  704. _ = PrimitiveListTests<OF, OptionalDoubleFactory>._defaultTestSuite().tests.map(suite.addTest)
  705. _ = PrimitiveListTests<OF, OptionalStringFactory>._defaultTestSuite().tests.map(suite.addTest)
  706. _ = PrimitiveListTests<OF, OptionalDataFactory>._defaultTestSuite().tests.map(suite.addTest)
  707. _ = PrimitiveListTests<OF, OptionalDateFactory>._defaultTestSuite().tests.map(suite.addTest)
  708. _ = OptionalMinMaxPrimitiveListTests<OF, OptionalIntFactory>._defaultTestSuite().tests.map(suite.addTest)
  709. _ = OptionalMinMaxPrimitiveListTests<OF, OptionalInt8Factory>._defaultTestSuite().tests.map(suite.addTest)
  710. _ = OptionalMinMaxPrimitiveListTests<OF, OptionalInt16Factory>._defaultTestSuite().tests.map(suite.addTest)
  711. _ = OptionalMinMaxPrimitiveListTests<OF, OptionalInt32Factory>._defaultTestSuite().tests.map(suite.addTest)
  712. _ = OptionalMinMaxPrimitiveListTests<OF, OptionalInt64Factory>._defaultTestSuite().tests.map(suite.addTest)
  713. _ = OptionalMinMaxPrimitiveListTests<OF, OptionalFloatFactory>._defaultTestSuite().tests.map(suite.addTest)
  714. _ = OptionalMinMaxPrimitiveListTests<OF, OptionalDoubleFactory>._defaultTestSuite().tests.map(suite.addTest)
  715. _ = OptionalMinMaxPrimitiveListTests<OF, OptionalDateFactory>._defaultTestSuite().tests.map(suite.addTest)
  716. _ = OptionalAddablePrimitiveListTests<OF, OptionalIntFactory>._defaultTestSuite().tests.map(suite.addTest)
  717. _ = OptionalAddablePrimitiveListTests<OF, OptionalInt8Factory>._defaultTestSuite().tests.map(suite.addTest)
  718. _ = OptionalAddablePrimitiveListTests<OF, OptionalInt16Factory>._defaultTestSuite().tests.map(suite.addTest)
  719. _ = OptionalAddablePrimitiveListTests<OF, OptionalInt32Factory>._defaultTestSuite().tests.map(suite.addTest)
  720. _ = OptionalAddablePrimitiveListTests<OF, OptionalInt64Factory>._defaultTestSuite().tests.map(suite.addTest)
  721. _ = OptionalAddablePrimitiveListTests<OF, OptionalFloatFactory>._defaultTestSuite().tests.map(suite.addTest)
  722. _ = OptionalAddablePrimitiveListTests<OF, OptionalDoubleFactory>._defaultTestSuite().tests.map(suite.addTest)
  723. }
  724. class UnmanagedPrimitiveListTests: TestCase {
  725. class func _defaultTestSuite() -> XCTestSuite {
  726. let suite = XCTestSuite(name: "Unmanaged Primitive Lists")
  727. addTests(suite, UnmanagedObjectFactory.self)
  728. return suite
  729. }
  730. #if swift(>=4)
  731. override class var defaultTestSuite: XCTestSuite {
  732. return _defaultTestSuite()
  733. }
  734. #else
  735. override class func defaultTestSuite() -> XCTestSuite {
  736. return _defaultTestSuite()
  737. }
  738. #endif
  739. }
  740. class ManagedPrimitiveListTests: TestCase {
  741. class func _defaultTestSuite() -> XCTestSuite {
  742. let suite = XCTestSuite(name: "Managed Primitive Lists")
  743. addTests(suite, ManagedObjectFactory.self)
  744. _ = SortablePrimitiveListTests<ManagedObjectFactory, IntFactory>._defaultTestSuite().tests.map(suite.addTest)
  745. _ = SortablePrimitiveListTests<ManagedObjectFactory, Int8Factory>._defaultTestSuite().tests.map(suite.addTest)
  746. _ = SortablePrimitiveListTests<ManagedObjectFactory, Int16Factory>._defaultTestSuite().tests.map(suite.addTest)
  747. _ = SortablePrimitiveListTests<ManagedObjectFactory, Int32Factory>._defaultTestSuite().tests.map(suite.addTest)
  748. _ = SortablePrimitiveListTests<ManagedObjectFactory, Int64Factory>._defaultTestSuite().tests.map(suite.addTest)
  749. _ = SortablePrimitiveListTests<ManagedObjectFactory, FloatFactory>._defaultTestSuite().tests.map(suite.addTest)
  750. _ = SortablePrimitiveListTests<ManagedObjectFactory, DoubleFactory>._defaultTestSuite().tests.map(suite.addTest)
  751. _ = SortablePrimitiveListTests<ManagedObjectFactory, StringFactory>._defaultTestSuite().tests.map(suite.addTest)
  752. _ = SortablePrimitiveListTests<ManagedObjectFactory, DateFactory>._defaultTestSuite().tests.map(suite.addTest)
  753. _ = OptionalSortablePrimitiveListTests<ManagedObjectFactory, OptionalIntFactory>._defaultTestSuite().tests.map(suite.addTest)
  754. _ = OptionalSortablePrimitiveListTests<ManagedObjectFactory, OptionalInt8Factory>._defaultTestSuite().tests.map(suite.addTest)
  755. _ = OptionalSortablePrimitiveListTests<ManagedObjectFactory, OptionalInt16Factory>._defaultTestSuite().tests.map(suite.addTest)
  756. _ = OptionalSortablePrimitiveListTests<ManagedObjectFactory, OptionalInt32Factory>._defaultTestSuite().tests.map(suite.addTest)
  757. _ = OptionalSortablePrimitiveListTests<ManagedObjectFactory, OptionalInt64Factory>._defaultTestSuite().tests.map(suite.addTest)
  758. _ = OptionalSortablePrimitiveListTests<ManagedObjectFactory, OptionalFloatFactory>._defaultTestSuite().tests.map(suite.addTest)
  759. _ = OptionalSortablePrimitiveListTests<ManagedObjectFactory, OptionalDoubleFactory>._defaultTestSuite().tests.map(suite.addTest)
  760. _ = OptionalSortablePrimitiveListTests<ManagedObjectFactory, OptionalStringFactory>._defaultTestSuite().tests.map(suite.addTest)
  761. _ = OptionalSortablePrimitiveListTests<ManagedObjectFactory, OptionalDateFactory>._defaultTestSuite().tests.map(suite.addTest)
  762. return suite
  763. }
  764. #if swift(>=4)
  765. override class var defaultTestSuite: XCTestSuite {
  766. return _defaultTestSuite()
  767. }
  768. #else
  769. override class func defaultTestSuite() -> XCTestSuite {
  770. return _defaultTestSuite()
  771. }
  772. #endif
  773. }