Guest User

Untitled

a guest
Sep 30th, 2018
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 36.68 KB | None | 0 0
  1. //
  2. // SwiftAdvanceTests.swift
  3. // SwiftAdvanceTests
  4. //
  5. // Created by wuufone on 2018/9/17.
  6. // Copyright © 2018年 wuufone. All rights reserved.
  7. //
  8.  
  9. import XCTest
  10. @testable import SwiftAdvance
  11.  
  12. class SwiftAdvanceTests: XCTestCase {
  13.  
  14. // 我們先假設整數 (Int) 的最大值為 1 億
  15. func testBoundInt() {
  16. XCTAssertEqual(-9223372036854775808, Int.min)
  17. XCTAssertEqual(9223372036854775807, Int.max)
  18. XCTAssertEqual((pow(Decimal(2), Int(63))-1 as NSDecimalNumber).intValue, Int.max)
  19. }
  20.  
  21. func testFormat() {
  22. XCTAssertEqual(10000000, 1000_0000)
  23.  
  24. /* 指數 (exponent, exp)。 e 表示十進位;p 表示二進位。*/
  25. XCTAssertEqual(100.1, 1.001e2)
  26. XCTAssertEqual(100.1, 1001e-1)
  27. XCTAssertEqual(0x4, 0x1p2)
  28. }
  29.  
  30. func testTypeAlias() {
  31. typealias Location = CGPoint
  32. XCTAssertEqual(Location(), CGPoint())
  33. }
  34.  
  35. func testOptional() {
  36. var aVariable: Any?
  37. XCTAssertNil(aVariable)
  38.  
  39. aVariable = EMPTY
  40. XCTAssertNotNil(aVariable)
  41. }
  42.  
  43. func testOptionalBinding() {
  44. class MyView: UIView {
  45. var button: UIButton?
  46. }
  47. let myViewInstance = MyView()
  48. guard let button = myViewInstance.button else {
  49. XCTAssertNil(myViewInstance.button)
  50. return
  51. }
  52. XCTAssertNil(button)
  53. }
  54.  
  55. func testIfLetSentence() {
  56. let aValue: String? = nil
  57. if let anotherValue = aValue {
  58. XCTFail("\(anotherValue) 應該是 nil,此行不該被執行。")
  59. }
  60. guard aValue == nil else {
  61. XCTFail("\(String(describing: aValue)) 應該是 nil,此行不該被執行。")
  62. return
  63. }
  64. }
  65.  
  66. func testFunctionWithOptionalReturn() {
  67. func findSomething(name: String) -> NSObject? {
  68. return nil
  69. }
  70.  
  71. var somethingDone: Bool = false
  72. if let foundThing = findSomething(name: "Stuff") {
  73. print("This is a say way to use \(foundThing).")
  74. somethingDone = true
  75. }
  76. XCTAssertFalse(somethingDone)
  77. }
  78.  
  79. func testOptionalChaining() {
  80. class Person {
  81. var job: Job?
  82. }
  83. class Job {
  84. var title: String
  85. init(title: String) {
  86. self.title = title
  87. }
  88. }
  89. let employee = Person()
  90. let engineer = Job(title: "engineer")
  91. employee.job = engineer
  92.  
  93. /* not use optional chaining
  94. var title: String = ""
  95. if employee.job != nil {
  96. title = employee.job.title
  97. }
  98. XCTAssertEqual("engineer", title)
  99. */
  100.  
  101. // 使用 optional chaining (very gracefully)
  102. if let title = employee.job?.title {
  103. XCTAssertEqual("engineer", title)
  104. } else {
  105. XCTFail()
  106. }
  107. }
  108.  
  109. func testConvertingErrorsToOptionalValues() {
  110. func someThrowingFunction() throws -> String { return "test" }
  111.  
  112. // 不使用 do / catch 的話: Errors thrown from here are not handled
  113. do {
  114. let result = try someThrowingFunction()
  115. XCTAssertEqual("test", result)
  116. } catch {}
  117.  
  118. // 使用 try? (very gracefully)
  119. XCTAssertEqual("test", try? someThrowingFunction())
  120.  
  121. // 在確定不會產生 Error 的情形下使用
  122. XCTAssertEqual("test", try! someThrowingFunction())
  123. }
  124.  
  125. func testClassPropertiesWithOptional() {
  126. class SomeClass {
  127. var property1: Any?
  128. var proeprty2: Any?
  129. }
  130. }
  131.  
  132. func testClassHasProperties() {
  133. class Book {
  134. private(set) var title: String?
  135. init(title: String) {
  136. self.title = title
  137. }
  138. }
  139. let aBook = Book(title: "Learning Swift")
  140. XCTAssertEqual("Learning Swift", aBook.title)
  141. // aBook.title = "Learning Swift V2"
  142. }
  143.  
  144. func testComputedProperty() {
  145. class Rect {
  146. var width: Float
  147. var height: Float
  148. var area: Float {
  149. return self.width * self.height
  150. }
  151. init (width: Float, height: Float) {
  152. self.width = width
  153. self.height = height
  154. }
  155. }
  156. let aRect = Rect(width: 5, height: 2)
  157. XCTAssertEqual(10, aRect.area)
  158. }
  159.  
  160. func testClassHasPropertiesSwiftStyle() {
  161. class Book {
  162. var title: String? = nil
  163. private var _isbn: String? = nil
  164. var isbn: String? {
  165. get { return _isbn }
  166. set {
  167. if _isbn == nil { // _isbn 只有在為 nil 時才能被變更
  168. _isbn = newValue
  169. }
  170. }
  171. }
  172. }
  173. let aBook = Book()
  174. aBook.title = "Learning Swift"
  175. aBook.isbn = "1111111111"
  176. XCTAssertEqual("1111111111", aBook.isbn)
  177. aBook.isbn = "2222222222" // 試圖變更 isbn 值
  178. XCTAssertEqual("1111111111", aBook.isbn) // 斷言:isbn 不會改變
  179. }
  180.  
  181. func testWatchProperties() {
  182. class Book {
  183. var oldTitle: String? = nil // 舊標題的值
  184. private var _title: String? = nil
  185. var title: String? {
  186. get { return _title }
  187. set {
  188. oldTitle = _title
  189. _title = newValue
  190. }
  191. }
  192. }
  193. let aBook = Book()
  194. aBook.title = "學習 Swift 基礎"
  195. XCTAssertEqual("學習 Swift 基礎", aBook.title)
  196. aBook.title = "學習 Swift 進階"
  197. XCTAssertEqual("學習 Swift 基礎", aBook.oldTitle)
  198. XCTAssertEqual("學習 Swift 進階", aBook.title)
  199. }
  200.  
  201. func testWatchProperitesWithObserver() {
  202. class Book {
  203. var oldTitle: String? = nil
  204. var newTitle: String? = nil
  205. private var _title: String? = nil
  206. var title: String? {
  207. willSet {
  208. newTitle = newValue
  209. }
  210. didSet {
  211. oldTitle = oldValue
  212. }
  213. }
  214. }
  215. let aBook = Book()
  216. aBook.title = "學習 Swift 基礎"
  217. XCTAssertEqual("學習 Swift 基礎", aBook.title)
  218. aBook.title = "學習 Swift 進階"
  219. XCTAssertEqual("學習 Swift 基礎", aBook.oldTitle)
  220. XCTAssertEqual("學習 Swift 進階", aBook.title)
  221. }
  222.  
  223. func testPropertyObservers() {
  224. class WebForm {
  225. var oldEmail: String? = nil
  226. var newEmail: String? = nil
  227. var email: String {
  228. willSet {
  229. self.newEmail = newValue
  230. }
  231. didSet {
  232. self.oldEmail = oldValue
  233. }
  234. }
  235.  
  236. init(email: String) {
  237. self.email = email
  238. }
  239. }
  240.  
  241. // 使用建構子設值,並不會執行 willSet 和 didSet
  242. let webForm = WebForm(email: "old@abc.com")
  243. XCTAssertEqual(webForm.oldEmail, nil)
  244. XCTAssertEqual(webForm.newEmail, nil)
  245.  
  246. // 使用 email 特性的隱含 setter 時,會執行 willSet 和 didSet
  247. webForm.email = "new@abc.com"
  248. XCTAssertEqual(webForm.oldEmail, "old@abc.com")
  249. XCTAssertEqual(webForm.newEmail, "new@abc.com")
  250. }
  251.  
  252. func testCreateEmptyArray() {
  253. let emptyArray = [String]()
  254. XCTAssertTrue(type(of: emptyArray) == Array<String>.self)
  255.  
  256. let emptyArray2 = Array<String>()
  257. XCTAssertTrue(type(of: emptyArray) == type(of: emptyArray2))
  258. }
  259.  
  260. func testWalkThroughArray() {
  261. // devices 為陣列
  262. // iPhone 索引值為 0;iPad 為 1; iPod Touch 為 2
  263. let devices = ["iPhone", "iPad", "iPod Touch"]
  264.  
  265. // 使用 for-in 語法遍歷陣列中的每個元素
  266. var device: String?
  267. for _device in devices {
  268. device = _device
  269. }
  270. // 斷定: device 的值為陣列的最後一個元素
  271. XCTAssertEqual("iPod Touch", device)
  272.  
  273. /* One-Sided Ranges */
  274. for _device in devices[...1] { // 只遍歷索引小於等於 1 的元素
  275. device = _device
  276. }
  277. XCTAssertEqual("iPad", device)
  278.  
  279. for _device in devices[..<1] { // 只遍歷索引小於 1 的元素
  280. device = _device
  281. }
  282. XCTAssertEqual("iPhone", device)
  283.  
  284. for _device in devices[1...] { // 只遍歷索引大於 1 的元素
  285. device = _device
  286. }
  287. XCTAssertEqual("iPod Touch", device)
  288. }
  289.  
  290. func testOtherArrayOperation() {
  291. var someInts = [Int]()
  292. XCTAssertTrue(someInts.isEmpty) // 以 isEmpty 驗證陣列為空
  293.  
  294. // 陣列元素的增加
  295. someInts.append(100)
  296. XCTAssertEqual(100, someInts[0])
  297.  
  298. // 以單一值,填充給指定個數元素至陣列
  299. let location = Array(repeating: 0, count: 3)
  300. XCTAssertEqual([0, 0, 0], location)
  301.  
  302. // 陣列的加法
  303. XCTAssertEqual([0, 1, 2, 3], [0, 1] + [2, 3])
  304. // XCTAssertEqual([0, 1, 2], [0, 1, 2, 3] - [3]) // 減法行不通
  305.  
  306. // 陣列元素的移除
  307. someInts = [0, 1, 2, 3]
  308. someInts.remove(at: 3)
  309. XCTAssertEqual([0, 1, 2], someInts)
  310. }
  311.  
  312. func testEmptySet() {
  313. let emails: Set<String> = Set<String>()
  314. XCTAssertTrue(emails.isEmpty)
  315. }
  316.  
  317. func testEachOneSetElementIsUnique() {
  318. var emails: Set<String> = Set<String>()
  319. XCTAssertTrue(emails.isEmpty)
  320.  
  321. emails.insert("tom@abc.com")
  322. emails.insert("mac@abc.com")
  323. XCTAssertTrue(emails.count == 2)
  324.  
  325. // 無法加入重復的元素
  326. let (success, _) = emails.insert("mac@abc.com")
  327. XCTAssertFalse(success)
  328. XCTAssertTrue(emails.count == 2)
  329. }
  330.  
  331. func testSupersetAndSubset() {
  332. let emails: Set<String> = ["tom@abc.com", "mac@abc.com"]
  333. let email: Set<String> = ["tom@abc.com"]
  334. XCTAssertTrue(email.isSubset(of: emails))
  335. XCTAssertTrue(emails.isSuperset(of: email))
  336. }
  337.  
  338. func testSetOperation() {
  339. let emails: Set<String> = ["tom@abc.com", "mac@abc.com"]
  340. var email: Set<String> = ["tom@abc.com"]
  341.  
  342. // 交集
  343. XCTAssertEqual(emails.intersection(email), ["tom@abc.com"])
  344.  
  345. // 差集
  346. XCTAssertEqual(emails.subtracting(email), ["mac@abc.com"])
  347.  
  348. // 對稱差
  349. email.insert("kim@abc.com")
  350. XCTAssertEqual(emails.symmetricDifference(email), ["mac@abc.com", "kim@abc.com"])
  351.  
  352. // 聯集
  353. XCTAssertEqual(emails.union(email), ["tom@abc.com", "mac@abc.com", "kim@abc.com"])
  354.  
  355. // 不交集
  356. let newEmail: Set<String> = ["new@abc.com"]
  357. XCTAssertTrue(emails.isDisjoint(with: newEmail))
  358. XCTAssertTrue(newEmail.isDisjoint(with: emails))
  359. }
  360.  
  361. func testGenerateSetFromSet() {
  362. let emails: Set<String> = ["tom@abc.com", "mac@abc.com"]
  363. let moreEmails = NSMutableSet(set: emails)
  364. moreEmails.add("joe@abc.com")
  365. XCTAssertEqual(3, moreEmails.count)
  366. XCTAssertTrue(emails.isSubset(of: moreEmails as! Set<String>))
  367. }
  368.  
  369. func testSortedSet() {
  370. let emails: Set<String> = ["tom@abc.com", "mac@abc.com"]
  371. var sortedEmails = Array<String>()
  372. for e in emails.sorted() {
  373. sortedEmails.append(e)
  374. }
  375. XCTAssertEqual("mac@abc.com", sortedEmails.first)
  376. XCTAssertEqual("tom@abc.com", sortedEmails.last)
  377. }
  378.  
  379. func testCreateEmptyDictionary() {
  380. let emptyDictionary = [String:Float]()
  381. XCTAssertTrue(type(of: emptyDictionary) == Dictionary<String, Float>.self)
  382.  
  383. let emptyDictionary2 = Dictionary<String, Float>()
  384. XCTAssertTrue(type(of: emptyDictionary) == type(of: emptyDictionary2))
  385. }
  386.  
  387. func testSimpleDictionary() {
  388. var simpleMembers: [Int: String] = [1: "John", 2: "Tom", 3: "Doris"]
  389. XCTAssertTrue(simpleMembers[2] == "Tom")
  390. }
  391.  
  392. func testComplexDictionary() {
  393. var members: [[String: String]] = [
  394. ["name": "John",
  395. "email": "john@abc.com",
  396. "id": "1"],
  397. ["name": "Tom",
  398. "email": "tom@abc.com",
  399. "id": "2"],
  400. ["name": "Doris",
  401. "email": "doris@abc.com",
  402. "id": "3"],
  403. ]
  404. XCTAssertEqual(members[0]["email"], "john@abc.com")
  405. XCTAssertEqual(members[1]["name"], "Tom")
  406. XCTAssertEqual(members[2]["id"], "3")
  407. }
  408.  
  409. func testDictionaryUpdate() {
  410. var members: [[String: String]] = [
  411. ["name": "John",
  412. "email": "john@abc.com",
  413. "id": "1"],
  414. ["name": "Tom",
  415. "email": "tom@abc.com",
  416. "id": "2"]
  417. ]
  418. members[1].updateValue("tony@abc.com", forKey: "email")
  419. members[1].updateValue("Tony", forKey: "name")
  420. XCTAssertEqual(members[1]["name"], "Tony")
  421. }
  422.  
  423. func testThroughOutDictionary() {
  424. let members: [[String: String]] = [
  425. ["name": "John",
  426. "email": "john@abc.com",
  427. "id": "1"],
  428. ["name": "Tom",
  429. "email": "tom@abc.com",
  430. "id": "2"],
  431. ["name": "Doris",
  432. "email": "doris@abc.com",
  433. "id": "3"],
  434. ]
  435. var memberNames: Set<String> = Set<String>()
  436. for member in members {
  437. let memberInfo: [String: String] = member as [String: String]
  438. for (key, value) in memberInfo { // 使用 Tuple + for-in 結合
  439. if key == "name" {
  440. memberNames.insert(value)
  441. }
  442. }
  443. }
  444. XCTAssertEqual(memberNames, Set<String>(arrayLiteral: "John", "Tom", "Doris"))
  445. }
  446.  
  447. func testTupleGetElementByIndex() {
  448. let aTuple = (1, "someone's name", true)
  449. XCTAssertEqual("someone's name", aTuple.1)
  450. }
  451.  
  452. func testTuplePositionParameters() {
  453. let (_, _, z) = (1, 2, 3)
  454. XCTAssertEqual(3, z)
  455. let (_, y, _) = (1, 2, 3)
  456. XCTAssertEqual(2, y)
  457. }
  458.  
  459. func testTupleHasParameterLabel() {
  460. let vector3D = (x: 1, y: 2, z: 3)
  461. XCTAssertEqual(2, vector3D.y)
  462. }
  463.  
  464. func testCompareBetweenTuples() {
  465. let vector3D = (x: 1, y: 2, z: 3)
  466. XCTAssertEqual(2, vector3D.y)
  467.  
  468. let anotherVector3D = (x: 1, y:2, z: 4)
  469. XCTAssertTrue(vector3D < anotherVector3D)
  470. }
  471.  
  472. func testTupleWithSwitch() {
  473. let xValue = Int(arc4random_uniform(5) + 1)
  474. let yValue = Int(arc4random_uniform(5) + 1)
  475. let point = (xValue, yValue)
  476. var descriptionOfPoint: String = ""
  477. switch point {
  478. case (0, 0):
  479. descriptionOfPoint = "該點為原點"
  480. case (0, _):
  481. descriptionOfPoint = "該點在 Y 軸上"
  482. case (_, 0):
  483. descriptionOfPoint = "該點在 X 軸上"
  484. case let (x, y) where x == -y: // Value Bindings + where clause
  485. descriptionOfPoint = "該點在第四象限上"
  486. case let (x, y): // Value Bindings
  487. descriptionOfPoint = "該點(\(x),\(y))不在任何軸上"
  488. }
  489. print(descriptionOfPoint)
  490. XCTAssertEqual(descriptionOfPoint, "該點(\(xValue),\(yValue))不在任何軸上")
  491. }
  492.  
  493. func testStructureIsImmutable() {
  494. struct S {
  495. var aValue: Int?
  496. }
  497. var s1 = S()
  498. s1.aValue = 1
  499. var s2 = s1
  500. s2.aValue = 2
  501. XCTAssertEqual(1, s1.aValue)
  502. }
  503.  
  504. func testClassIsMutable() {
  505. class C {
  506. var aValue: Int?
  507. }
  508. let c1 = C()
  509. c1.aValue = 1
  510. let c2 = c1
  511. c2.aValue = 2
  512. XCTAssertEqual(2, c1.aValue)
  513. }
  514.  
  515. func testSimpleClosure() {
  516. var result: String? = nil
  517. let aSimpleClosure = { () -> Void in
  518. result = "A Simple Closure."
  519. }
  520. aSimpleClosure()
  521. XCTAssertEqual("A Simple Closure.", result)
  522. }
  523.  
  524. func testSimplestClosure() {
  525. var result: String? = nil
  526. let aSimplestClosure = {
  527. result = "A Simplest Closure."
  528. }
  529. aSimplestClosure()
  530. XCTAssertEqual("A Simplest Closure.", result)
  531. }
  532.  
  533. func testClosureAsFunctionParameter() {
  534. func setResult(_ aClosure: ()->Void) {
  535. aClosure()
  536. }
  537. var result: String? = nil
  538. let aSimplestClosure = {
  539. result = "A Simplest Closure."
  540. }
  541. setResult(aSimplestClosure)
  542. XCTAssertEqual("A Simplest Closure.", result)
  543. }
  544.  
  545. func testClosureAsReturnType() {
  546. func chineseToEnglish(word: String) -> String {
  547. if word == "您好" {
  548. return "Hello"
  549. }
  550. return "無法翻譯"
  551. }
  552. func chineseToNihongo(word: String) -> String {
  553. if word == "您好" {
  554. return "こんちは"
  555. }
  556. return "無法翻譯"
  557. }
  558. func getTranslator(from: String, to: String) -> ((String) -> String) {
  559. if from == "中" && to == "英" {
  560. return chineseToEnglish
  561. } else if from == "中" && to == "日" {
  562. return chineseToNihongo
  563. }
  564. return {(String) -> String in return "無法翻譯"}
  565. }
  566. let translator = getTranslator(from: "中", to: "英")
  567. XCTAssertTrue(translator("您好") == "Hello")
  568. XCTAssertTrue(translator("大家好") == "無法翻譯")
  569. }
  570.  
  571. func testTrailingClosure() {
  572. func executeClosure(_ closure: () -> String) -> String {
  573. return closure()
  574. }
  575. let result = executeClosure() {
  576. return "Hello"
  577. }
  578. XCTAssertEqual("Hello", result)
  579. }
  580.  
  581. func testTailingClousre2() {
  582. func anotherFunction(_ arg1: String, _ arg2: ()-> String) -> String{
  583. return "\(arg1), \(arg2())"
  584. }
  585. XCTAssertEqual ("Hello, World", anotherFunction("Hello") { return "World" })
  586. }
  587.  
  588. func testKeepArgs() {
  589. var args: [String] = [String]()
  590. func aFunction(_ arg: String) {
  591. args.append(arg)
  592. }
  593. aFunction("Hello")
  594. XCTAssertEqual(1, args.count)
  595. }
  596.  
  597. func testKeepClosures() {
  598. var closures: [()->String] = [()->String]()
  599. func aFunction(_ closure: @escaping ()->String) {
  600. closures.append(closure)
  601. }
  602. aFunction() {
  603. return "Hello."
  604. }
  605. XCTAssertEqual("Hello.", closures.first!())
  606. }
  607.  
  608. func testAutoClosure() {
  609. var steps = [String]()
  610. func readFile(_ filename: String) -> String {
  611. steps.append("==> ①")
  612. return "hello"
  613. }
  614. func aFunctionIncludeAutoClosure(filename: String, fileContent: @autoclosure () -> String) {
  615. steps.append("==> ②")
  616. if filename != "" {
  617. steps.append("==> ③")
  618. XCTAssertEqual("hello", fileContent())
  619. }
  620. }
  621. steps.append("==> ④")
  622. let filename = "aFile.txt"
  623. aFunctionIncludeAutoClosure(filename: filename, fileContent: readFile(filename))
  624. XCTAssertEqual(steps, ["==> ④", "==> ②", "==> ③", "==> ①"])
  625. }
  626.  
  627. func testCommonFunction() {
  628. func greet(myFriend person: String) -> String {
  629. return "Hello, \(person)"
  630. }
  631. XCTAssertTrue(greet(myFriend: "Tom") == "Hello, Tom")
  632. }
  633.  
  634. func testFunctionUseArgNameAsLabel() {
  635. func greet(person: String) -> String {
  636. return "Hello, \(person)"
  637. }
  638. XCTAssertTrue(greet(person: "Tom") == "Hello, Tom")
  639. }
  640.  
  641. func testFunctionIgnoreLabel() {
  642. func greet(_ person: String) -> String {
  643. return "Hello, \(person)"
  644. }
  645. XCTAssertTrue(greet("Tom") == "Hello, Tom")
  646. }
  647.  
  648. func testFunctionHasDefaultParameterValues() {
  649. func welcome(name: String = "Guest") -> String {
  650. return "Hello, \(name)."
  651. }
  652. XCTAssertEqual("Hello, Guest.", welcome())
  653. }
  654.  
  655. func testVariadicParameters() {
  656. func addTotal(_ numbers: Int...) -> Int {
  657. var total: Int = 0
  658. for number in numbers {
  659. total += number
  660. }
  661. return total
  662. }
  663. XCTAssertEqual(10, addTotal(2, 3, 4, 1))
  664. }
  665.  
  666. func testInOutParameters() {
  667. func swap(number1: inout Int, number2: inout Int) {
  668. let tempNumber = number1
  669. number1 = number2
  670. number2 = tempNumber
  671. }
  672. var n1 = 5, n2 = 3
  673. swap(number1: &n1, number2: &n2)
  674. XCTAssertEqual(3, n1)
  675. XCTAssertEqual(5, n2)
  676. }
  677.  
  678. func testDiscardableResultMethod() {
  679. @discardableResult
  680. func aMethod() -> String {
  681. return "hello."
  682. }
  683. aMethod() // 若沒有加上 @discardableResult 會出現告警:Result of call to 'aMethod()' is unused.
  684. }
  685.  
  686. func testDefer() {
  687. var aNumber = 0
  688. func aFunction() {
  689. defer {
  690. aNumber = 0
  691. }
  692. aNumber = 1
  693. aNumber = 2
  694. XCTAssertEqual(2, aNumber)
  695. }
  696. aFunction()
  697. XCTAssertEqual(0, aNumber)
  698. }
  699.  
  700. func testInitializerWithoutInheritance() {
  701. class A {
  702. var result: String = "a"
  703. init(newResult: String) { // 指定建構子
  704. self.result = newResult // 由於 A 不為任何類的子類,所以不需要呼叫 super。
  705. }
  706. convenience init() { // 便利建構子
  707. self.init(newResult: "") // 便利建構子呼叫指定建構子
  708. }
  709. required init(aBool: Bool) {}
  710. }
  711. let a = A() // 以便利建構子生成 A 的實例
  712. XCTAssertEqual("", a.result)
  713. }
  714.  
  715. func testInitializerWithInheritance() {
  716. class A {
  717. var result: String = "a"
  718. init(newResult: String) {
  719. self.result = newResult
  720. }
  721. convenience init() {
  722. self.init(newResult: "")
  723. }
  724. required init(aBool: Bool) {}
  725. }
  726.  
  727. class B: A {
  728. var number: Int?
  729.  
  730. // 繼承自父類的建構子
  731. override init(newResult: String) {
  732. super.init(newResult: "結果: \(newResult)")
  733. }
  734.  
  735. // 可失敗建構子 (Failable Initializer)
  736. init?(number: Int?) {
  737. super.init(newResult: "b")
  738. if number == nil { return nil }
  739. self.number = number
  740. }
  741.  
  742. // 便利建構子的覆寫不需要宣告 override
  743. // 便利建構子不會被繼承
  744. convenience init() {
  745. self.init(newResult: "b")
  746. }
  747.  
  748. // 由於父類 (A) 有宣告此建構A子,子類必須也加上
  749. required init(aBool: Bool) {
  750. super.init(aBool: aBool)
  751. }
  752. }
  753. let b = B()
  754. XCTAssertEqual("結果: b", b.result)
  755. XCTAssertNil(B(number: nil))
  756. }
  757.  
  758. func testDeInitializer() {
  759. class A {
  760. var aProperty: String = ""
  761. }
  762. class B {
  763. var aAInstance: A = A()
  764. deinit {
  765. aAInstance.aProperty = "B is over."
  766. }
  767. }
  768.  
  769. var b = B()
  770. let a = b.aAInstance
  771. XCTAssertEqual("", a.aProperty)
  772. b = B() // 取代舊的 B 實例
  773. XCTAssertEqual("B is over.", a.aProperty)
  774. }
  775.  
  776. func testReferenceDeadLock() {
  777. class Book {
  778. var author: Author?
  779. }
  780. class Author {
  781. var book: Book?
  782. }
  783.  
  784. var aBook: Book? = Book()
  785. let aAuthor: Author? = Author()
  786. aBook!.author = aAuthor
  787.  
  788. aAuthor!.book = aBook
  789.  
  790. aBook = nil
  791. XCTAssertNotNil(aAuthor!.book)
  792. }
  793.  
  794. func testWeakReference() {
  795. class Book {
  796. var author: Author?
  797. }
  798. class Author {
  799. weak var book: Book?
  800. }
  801.  
  802. var aBook: Book? = Book()
  803. let aAuthor: Author? = Author()
  804. aBook!.author = aAuthor
  805. aAuthor!.book = aBook
  806.  
  807. aBook = nil
  808. XCTAssertNil(aAuthor!.book)
  809. }
  810.  
  811. func testLazyStoredProperties() {
  812. class Animal {
  813. lazy var isLive: Bool = true // 在特性前加上 lazy 關鍵字
  814. var isHappy: Bool = true
  815. }
  816.  
  817. let animal = Animal()
  818.  
  819. // 為了能夠檢查在記憶體裡的狀況,這裡需使用 Swift 的反射 (reflect) 語法
  820. let mirror = Mirror(reflecting: animal)
  821.  
  822. // 取出物件的第一個特性,先證明為 isLive 特性
  823. XCTAssertEqual("isLive.storage", mirror.children.first?.label)
  824.  
  825. // 並證明其值仍為 nil,還沒被設定為 true
  826. XCTAssertEqual("nil", String(describing: (mirror.children.first?.value)!))
  827.  
  828. // 取出物件的另一個特性,應該是 isHappy,並證明其值已經被設定為 true
  829. XCTAssertEqual("true",
  830. String(describing: (mirror.children[mirror.children.index(after: mirror.children.startIndex)].value)))
  831.  
  832. // 取用 isLive 特性
  833. let _ = animal.isLive
  834.  
  835. // 取出物件的第一個特性,先證明為 isLive 特性
  836. XCTAssertEqual("isLive.storage", mirror.children.first?.label)
  837.  
  838. // 並證明其值被設定為 true (為 optional 型別)
  839. XCTAssertEqual("Optional(true)",
  840. String(describing: (mirror.children.first?.value)!))
  841. }
  842.  
  843. func testTypePropertiesAndMethods() {
  844. class Util {
  845. static var inch: Float = 0.0
  846. static func centWith() -> Float {
  847. return inch * 2.54
  848. }
  849. static func centWith(inch: Float) -> Float {
  850. return inch * 2.54
  851. }
  852. }
  853. Util.inch = 2
  854. XCTAssertEqual(5.08, Util.centWith())
  855. XCTAssertEqual(2.54, Util.centWith(inch: 1))
  856. }
  857.  
  858. func testBoringExample() {
  859. class SomeClass {
  860. var someProperty: String = ""
  861. func getSomeValue() -> String {
  862. return "hello"
  863. }
  864. }
  865. let aInstance = SomeClass()
  866. aInstance.someProperty = aInstance.getSomeValue()
  867. XCTAssertEqual("hello", aInstance.someProperty)
  868. }
  869.  
  870. func testAssignClosureResultToProperty() {
  871. class SomeClass {
  872. let someProperty: String = {
  873. return "some value"
  874. }()
  875. }
  876. XCTAssertEqual("some value", SomeClass().someProperty)
  877. }
  878.  
  879. func testAssignInstanceProperty() {
  880. class SomeClassForProperty: NSObject {
  881. override var description: String {
  882. return "some value"
  883. }
  884. }
  885. class SomeClass {
  886. let someProperty: String = SomeClassForProperty().description
  887. }
  888. XCTAssertEqual("some value", SomeClass().someProperty)
  889. }
  890.  
  891. func testExtension() {
  892. XCTAssertEqual("Hello".toChinese(), "您好")
  893. }
  894.  
  895. func testExtensionImplementProtocol() {
  896. XCTAssertEqual("Hello".sayFrenchHello(), "Bonjour")
  897. }
  898.  
  899. func testOptionalProtocol() {
  900. class SomeClass: AOptionalProtocol {}
  901. XCTAssertNotNil(SomeClass())
  902. }
  903.  
  904. func testClassOnlyProtocols() {
  905.  
  906. class SomeClass: SomeClassProtocol {}
  907. /*
  908. 由於 SomeClassProtocol 是繼承自 AnyObject 這個協定,
  909. 所以無法使用下列代碼讓結構/列舉宣告實作 SomeClassProtocol。
  910.  
  911. struct SomeStructure: SomeClassProtocol {}
  912. enum SomeEnum: SomeClassProtocol {}
  913.  
  914. 錯誤訊息如下:
  915. Non-class type 'SomeStructure'
  916. cannot conform to class protocol 'SomeClassProtocol'
  917. */
  918. }
  919.  
  920. func testSeveralTypesEnum() {
  921. enum Emotion {
  922. case happy, sad
  923. case laugh()
  924. case eat(foodName: String) /* Associated Values */
  925.  
  926. func brief() -> String {
  927. switch self {
  928. case .eat(foodName: let fName):
  929. return "有些人心情不好會大吃\(fName)一頓"
  930. default:
  931. return ""
  932. }
  933. }
  934. }
  935.  
  936. let eatEmotion: Emotion = Emotion.eat(foodName: "牛排")
  937. XCTAssertEqual(eatEmotion.brief(), "有些人心情不好會大吃牛排一頓")
  938. }
  939.  
  940. func testEnumRawValue() {
  941. enum Season: Int {
  942. case Spring, Summer, Fall, Winter
  943. }
  944. XCTAssertEqual(Season(rawValue: 1), Season.Summer)
  945. XCTAssertEqual(Season(rawValue: 3), Season.Winter)
  946. }
  947.  
  948. func testEnumOfCustomRawValue() {
  949. enum Swith: Int {
  950. case ON = 1, OFF = 0
  951. }
  952. XCTAssertEqual(Swith(rawValue: 1), Swith.ON)
  953. }
  954.  
  955. func testGenerics() {
  956. func add<Item>(item1: Item, item2: Item) -> Any {
  957. if item1 is Int {
  958. return (item1 as! Int) + (item2 as! Int)
  959. }
  960. if item1 is Double {
  961. return (item1 as! Double) + (item2 as! Double)
  962. }
  963. if item1 is String {
  964. return "\(item1)\(item2)"
  965. }
  966. return EMPTY
  967. }
  968. XCTAssertEqual(2, add(item1: 1, item2: 1) as! Int)
  969. XCTAssertEqual(2.5, add(item1: 0.5, item2: 2) as! Double)
  970. XCTAssertEqual("11", add(item1: "1", item2: "1") as! String)
  971. }
  972.  
  973. func testErroHandler() {
  974. enum RequestError: Error {
  975. case wrongFormat
  976. case deadNetwork
  977. func simpleDescription() -> String {
  978. if self == RequestError.wrongFormat {
  979. return "wrong format"
  980. }
  981. if self == RequestError.deadNetwork {
  982. return "dead network"
  983. }
  984. return "unknown"
  985. }
  986. }
  987.  
  988. func checkNetworkAvailable() -> Bool {
  989. return true
  990. }
  991.  
  992. func request(parameter: Dictionary<String, String>?) throws -> (String, String) {
  993. if parameter == nil || parameter?.keys.count == 0 {
  994. throw RequestError.wrongFormat
  995. }
  996. if !checkNetworkAvailable() {
  997. throw RequestError.deadNetwork
  998. }
  999. return ("200", "OK")
  1000. }
  1001.  
  1002. XCTAssertThrowsError(try request(parameter: Dictionary<String, String>()),
  1003. "Parameter dictionary is empty") { (error) in
  1004. XCTAssertTrue(error is RequestError)
  1005. }
  1006.  
  1007. var errorReason: String? = nil
  1008. do {
  1009. let response = try request(parameter: Dictionary<String, String>())
  1010. print(response)
  1011. } catch RequestError.wrongFormat {
  1012. errorReason = RequestError.wrongFormat.simpleDescription()
  1013. } catch RequestError.deadNetwork {
  1014. errorReason = RequestError.deadNetwork.simpleDescription()
  1015. } catch {
  1016. errorReason = "Unknown"
  1017. }
  1018. XCTAssertEqual("wrong format", errorReason)
  1019.  
  1020.  
  1021. let response = try? request(parameter: Dictionary<String, String>())
  1022. XCTAssertNil(response)
  1023. }
  1024.  
  1025. func testIf() {
  1026. let number1 = 10
  1027. let number2 = 9
  1028. let number3 = 8
  1029. var result = 0
  1030.  
  1031. /* 以下三個例子是同義的 */
  1032. if number1 > number2 {
  1033. if number2 > number3 {
  1034. result += 1
  1035. }
  1036. }
  1037.  
  1038. if (number1 > number2) && (number2 > number3) {
  1039. result += 1
  1040. }
  1041.  
  1042. if number1 > number2, number2 > number3 {
  1043. result += 1
  1044. }
  1045.  
  1046. XCTAssertEqual(3, result)
  1047.  
  1048. if (number1 < number2) || (number2 > number3) {
  1049. result += 1
  1050. }
  1051.  
  1052. XCTAssertEqual(4, result)
  1053. }
  1054.  
  1055. func testNilCoalescingOperator() {
  1056. var aInt: Int?
  1057. aInt = Int("1")
  1058. XCTAssertEqual(1, aInt ?? 0)
  1059.  
  1060. aInt = Int("a")
  1061. XCTAssertEqual(0, aInt ?? 0)
  1062. }
  1063.  
  1064. func testTernaryConditionalOperator() {
  1065. let score = 65
  1066. XCTAssertEqual("考試通過", ((score >= 60) ? "考試通過" : "考試不及格"))
  1067. }
  1068.  
  1069. func testClosedRange() {
  1070. var result:Int = 0
  1071. for number in 1...10 {
  1072. result += number
  1073. }
  1074. XCTAssertEqual(55, result)
  1075. }
  1076.  
  1077. func testHalfOpenRange() {
  1078. var result:Int = 0
  1079. for number in 1..<11 {
  1080. result += number
  1081. }
  1082. XCTAssertEqual(55, result)
  1083. }
  1084.  
  1085. func testMultilineString() {
  1086. let articleTexts = """
  1087. 歡迎一起來學習 Swift "最新版"!
  1088. Swift 是蘋果官方發佈的程式語言。
  1089. """
  1090. XCTAssertNotEqual("歡迎一起來學習 Swift \"最新版\"!Swift 是蘋果官方發佈的程式語言。", articleTexts)
  1091. XCTAssertEqual("歡迎一起來學習 Swift \"最新版\"!\nSwift 是蘋果官方發佈的程式語言。", articleTexts)
  1092. }
  1093.  
  1094. func testSpecialCharacters() {
  1095. let blackHeart = "\u{2665}"
  1096. XCTAssertEqual(blackHeart, "♥")
  1097. }
  1098.  
  1099. func testGetFirstCharacterFromString() {
  1100. let greeting = "您好,有什麼能為您服務的?"
  1101. XCTAssertEqual("您", greeting[greeting.startIndex])
  1102. }
  1103.  
  1104. func testCountStringLength() {
  1105. let greeting = "您好,有什麼能為您服務的?"
  1106. XCTAssertEqual(greeting.count, greeting.endIndex.encodedOffset)
  1107. }
  1108.  
  1109. func testSubStringWithBefore() {
  1110. let greeting = "您好,有什麼能為您服務的?"
  1111. XCTAssertEqual("?", greeting[greeting.index(before: greeting.endIndex)])
  1112. }
  1113.  
  1114. func testFromIntToStringIndex() {
  1115. let greeting = "您好,有什麼能為您服務的?"
  1116. XCTAssertEqual("?", greeting[greeting.index(before: String.Index(encodedOffset: greeting.count))])
  1117. }
  1118.  
  1119. func testGetIndexPositonOfCharacter() {
  1120. let greeting = "您好,有什麼能為您服務的?"
  1121. let indexOfComma = greeting.index(of: ",")
  1122. XCTAssertEqual(indexOfComma, String.Index(encodedOffset: 2))
  1123. }
  1124.  
  1125. func testStringReverse() {
  1126. let greeting = "您好,有什麼能為您服務的?"
  1127. XCTAssertEqual("?的務服您為能麼什有,好您", String(greeting.reversed()))
  1128. }
  1129.  
  1130. func testStringInsert() {
  1131. var welcome = "hello"
  1132.  
  1133. // 插入字元
  1134. welcome.insert(",", at: welcome.endIndex)
  1135. XCTAssertEqual("hello,", welcome)
  1136.  
  1137. // 插入字串
  1138. welcome.insert(contentsOf: " world.", at: welcome.endIndex)
  1139. XCTAssertEqual("hello, world.", welcome)
  1140. }
  1141.  
  1142. func testStringRemove() {
  1143. var welcome = "hello, world."
  1144. welcome.remove(at: welcome.index(before: welcome.endIndex))
  1145. XCTAssertEqual("hello, world", welcome)
  1146.  
  1147. welcome.removeSubrange(
  1148. welcome.index(welcome.endIndex, offsetBy: -(", world".count))
  1149. ..<
  1150. welcome.endIndex)
  1151. XCTAssertEqual("hello", welcome)
  1152. }
  1153.  
  1154. }
  1155.  
  1156. protocol LearningLanguage {
  1157. var languageName: String {get set}
  1158. var description: String {get set}
  1159. func recite()
  1160. }
  1161.  
  1162. protocol LearningLanguageWithMutaingKeyword {
  1163. var languageName: String {get set}
  1164. var description: String {get set}
  1165. mutating func recite()
  1166. }
  1167.  
  1168. @objc protocol AOptionalProtocol {
  1169. @objc optional func aOptionalMethod()
  1170. }
  1171.  
  1172.  
  1173. extension String {
  1174. func toChinese() -> String {
  1175. if self == "Hello" {
  1176. return "您好"
  1177. }
  1178. return "Unknown"
  1179. }
  1180. }
  1181.  
  1182. protocol LearningFrench {
  1183. func sayFrenchHello() -> String
  1184. }
  1185.  
  1186. extension String: LearningFrench {
  1187. func sayFrenchHello() -> String {
  1188. if self == "Hello" {
  1189. return "Bonjour"
  1190. }
  1191. return "Unknown"
  1192. }
  1193. }
  1194.  
  1195. protocol SomeClassProtocol: AnyObject {} // AnyObject 為 protocol
  1196.  
  1197. class JustForGenerics: XCTestCase {
  1198. func testTypeConstraintGenerics() {
  1199. func add<Item: Addable>(item1: Item, item2: Item) -> Item {
  1200. return item1 + item2
  1201. }
  1202. XCTAssertEqual(2, add(item1: 1, item2: 1))
  1203. XCTAssertEqual("11", add(item1: "1", item2: "1"))
  1204. }
  1205. }
  1206.  
  1207. protocol Addable {
  1208. static func +(lItem: Self, rItem: Self) -> Self
  1209. }
  1210.  
  1211. extension Int: Addable {}
  1212.  
  1213. extension String: Addable {
  1214. static func +(lItem: String, rItem: String) -> String {
  1215. return "\(lItem)\(rItem)"
  1216. }
  1217. }
Add Comment
Please, Sign In to add comment