Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // SwiftAdvanceTests.swift
- // SwiftAdvanceTests
- //
- // Created by wuufone on 2018/9/17.
- // Copyright © 2018年 wuufone. All rights reserved.
- //
- import XCTest
- @testable import SwiftAdvance
- class SwiftAdvanceTests: XCTestCase {
- // 我們先假設整數 (Int) 的最大值為 1 億
- func testBoundInt() {
- XCTAssertEqual(-9223372036854775808, Int.min)
- XCTAssertEqual(9223372036854775807, Int.max)
- XCTAssertEqual((pow(Decimal(2), Int(63))-1 as NSDecimalNumber).intValue, Int.max)
- }
- func testFormat() {
- XCTAssertEqual(10000000, 1000_0000)
- /* 指數 (exponent, exp)。 e 表示十進位;p 表示二進位。*/
- XCTAssertEqual(100.1, 1.001e2)
- XCTAssertEqual(100.1, 1001e-1)
- XCTAssertEqual(0x4, 0x1p2)
- }
- func testTypeAlias() {
- typealias Location = CGPoint
- XCTAssertEqual(Location(), CGPoint())
- }
- func testOptional() {
- var aVariable: Any?
- XCTAssertNil(aVariable)
- aVariable = EMPTY
- XCTAssertNotNil(aVariable)
- }
- func testOptionalBinding() {
- class MyView: UIView {
- var button: UIButton?
- }
- let myViewInstance = MyView()
- guard let button = myViewInstance.button else {
- XCTAssertNil(myViewInstance.button)
- return
- }
- XCTAssertNil(button)
- }
- func testIfLetSentence() {
- let aValue: String? = nil
- if let anotherValue = aValue {
- XCTFail("\(anotherValue) 應該是 nil,此行不該被執行。")
- }
- guard aValue == nil else {
- XCTFail("\(String(describing: aValue)) 應該是 nil,此行不該被執行。")
- return
- }
- }
- func testFunctionWithOptionalReturn() {
- func findSomething(name: String) -> NSObject? {
- return nil
- }
- var somethingDone: Bool = false
- if let foundThing = findSomething(name: "Stuff") {
- print("This is a say way to use \(foundThing).")
- somethingDone = true
- }
- XCTAssertFalse(somethingDone)
- }
- func testOptionalChaining() {
- class Person {
- var job: Job?
- }
- class Job {
- var title: String
- init(title: String) {
- self.title = title
- }
- }
- let employee = Person()
- let engineer = Job(title: "engineer")
- employee.job = engineer
- /* not use optional chaining
- var title: String = ""
- if employee.job != nil {
- title = employee.job.title
- }
- XCTAssertEqual("engineer", title)
- */
- // 使用 optional chaining (very gracefully)
- if let title = employee.job?.title {
- XCTAssertEqual("engineer", title)
- } else {
- XCTFail()
- }
- }
- func testConvertingErrorsToOptionalValues() {
- func someThrowingFunction() throws -> String { return "test" }
- // 不使用 do / catch 的話: Errors thrown from here are not handled
- do {
- let result = try someThrowingFunction()
- XCTAssertEqual("test", result)
- } catch {}
- // 使用 try? (very gracefully)
- XCTAssertEqual("test", try? someThrowingFunction())
- // 在確定不會產生 Error 的情形下使用
- XCTAssertEqual("test", try! someThrowingFunction())
- }
- func testClassPropertiesWithOptional() {
- class SomeClass {
- var property1: Any?
- var proeprty2: Any?
- }
- }
- func testClassHasProperties() {
- class Book {
- private(set) var title: String?
- init(title: String) {
- self.title = title
- }
- }
- let aBook = Book(title: "Learning Swift")
- XCTAssertEqual("Learning Swift", aBook.title)
- // aBook.title = "Learning Swift V2"
- }
- func testComputedProperty() {
- class Rect {
- var width: Float
- var height: Float
- var area: Float {
- return self.width * self.height
- }
- init (width: Float, height: Float) {
- self.width = width
- self.height = height
- }
- }
- let aRect = Rect(width: 5, height: 2)
- XCTAssertEqual(10, aRect.area)
- }
- func testClassHasPropertiesSwiftStyle() {
- class Book {
- var title: String? = nil
- private var _isbn: String? = nil
- var isbn: String? {
- get { return _isbn }
- set {
- if _isbn == nil { // _isbn 只有在為 nil 時才能被變更
- _isbn = newValue
- }
- }
- }
- }
- let aBook = Book()
- aBook.title = "Learning Swift"
- aBook.isbn = "1111111111"
- XCTAssertEqual("1111111111", aBook.isbn)
- aBook.isbn = "2222222222" // 試圖變更 isbn 值
- XCTAssertEqual("1111111111", aBook.isbn) // 斷言:isbn 不會改變
- }
- func testWatchProperties() {
- class Book {
- var oldTitle: String? = nil // 舊標題的值
- private var _title: String? = nil
- var title: String? {
- get { return _title }
- set {
- oldTitle = _title
- _title = newValue
- }
- }
- }
- let aBook = Book()
- aBook.title = "學習 Swift 基礎"
- XCTAssertEqual("學習 Swift 基礎", aBook.title)
- aBook.title = "學習 Swift 進階"
- XCTAssertEqual("學習 Swift 基礎", aBook.oldTitle)
- XCTAssertEqual("學習 Swift 進階", aBook.title)
- }
- func testWatchProperitesWithObserver() {
- class Book {
- var oldTitle: String? = nil
- var newTitle: String? = nil
- private var _title: String? = nil
- var title: String? {
- willSet {
- newTitle = newValue
- }
- didSet {
- oldTitle = oldValue
- }
- }
- }
- let aBook = Book()
- aBook.title = "學習 Swift 基礎"
- XCTAssertEqual("學習 Swift 基礎", aBook.title)
- aBook.title = "學習 Swift 進階"
- XCTAssertEqual("學習 Swift 基礎", aBook.oldTitle)
- XCTAssertEqual("學習 Swift 進階", aBook.title)
- }
- func testPropertyObservers() {
- class WebForm {
- var oldEmail: String? = nil
- var newEmail: String? = nil
- var email: String {
- willSet {
- self.newEmail = newValue
- }
- didSet {
- self.oldEmail = oldValue
- }
- }
- init(email: String) {
- self.email = email
- }
- }
- // 使用建構子設值,並不會執行 willSet 和 didSet
- let webForm = WebForm(email: "old@abc.com")
- XCTAssertEqual(webForm.oldEmail, nil)
- XCTAssertEqual(webForm.newEmail, nil)
- // 使用 email 特性的隱含 setter 時,會執行 willSet 和 didSet
- webForm.email = "new@abc.com"
- XCTAssertEqual(webForm.oldEmail, "old@abc.com")
- XCTAssertEqual(webForm.newEmail, "new@abc.com")
- }
- func testCreateEmptyArray() {
- let emptyArray = [String]()
- XCTAssertTrue(type(of: emptyArray) == Array<String>.self)
- let emptyArray2 = Array<String>()
- XCTAssertTrue(type(of: emptyArray) == type(of: emptyArray2))
- }
- func testWalkThroughArray() {
- // devices 為陣列
- // iPhone 索引值為 0;iPad 為 1; iPod Touch 為 2
- let devices = ["iPhone", "iPad", "iPod Touch"]
- // 使用 for-in 語法遍歷陣列中的每個元素
- var device: String?
- for _device in devices {
- device = _device
- }
- // 斷定: device 的值為陣列的最後一個元素
- XCTAssertEqual("iPod Touch", device)
- /* One-Sided Ranges */
- for _device in devices[...1] { // 只遍歷索引小於等於 1 的元素
- device = _device
- }
- XCTAssertEqual("iPad", device)
- for _device in devices[..<1] { // 只遍歷索引小於 1 的元素
- device = _device
- }
- XCTAssertEqual("iPhone", device)
- for _device in devices[1...] { // 只遍歷索引大於 1 的元素
- device = _device
- }
- XCTAssertEqual("iPod Touch", device)
- }
- func testOtherArrayOperation() {
- var someInts = [Int]()
- XCTAssertTrue(someInts.isEmpty) // 以 isEmpty 驗證陣列為空
- // 陣列元素的增加
- someInts.append(100)
- XCTAssertEqual(100, someInts[0])
- // 以單一值,填充給指定個數元素至陣列
- let location = Array(repeating: 0, count: 3)
- XCTAssertEqual([0, 0, 0], location)
- // 陣列的加法
- XCTAssertEqual([0, 1, 2, 3], [0, 1] + [2, 3])
- // XCTAssertEqual([0, 1, 2], [0, 1, 2, 3] - [3]) // 減法行不通
- // 陣列元素的移除
- someInts = [0, 1, 2, 3]
- someInts.remove(at: 3)
- XCTAssertEqual([0, 1, 2], someInts)
- }
- func testEmptySet() {
- let emails: Set<String> = Set<String>()
- XCTAssertTrue(emails.isEmpty)
- }
- func testEachOneSetElementIsUnique() {
- var emails: Set<String> = Set<String>()
- XCTAssertTrue(emails.isEmpty)
- emails.insert("tom@abc.com")
- emails.insert("mac@abc.com")
- XCTAssertTrue(emails.count == 2)
- // 無法加入重復的元素
- let (success, _) = emails.insert("mac@abc.com")
- XCTAssertFalse(success)
- XCTAssertTrue(emails.count == 2)
- }
- func testSupersetAndSubset() {
- let emails: Set<String> = ["tom@abc.com", "mac@abc.com"]
- let email: Set<String> = ["tom@abc.com"]
- XCTAssertTrue(email.isSubset(of: emails))
- XCTAssertTrue(emails.isSuperset(of: email))
- }
- func testSetOperation() {
- let emails: Set<String> = ["tom@abc.com", "mac@abc.com"]
- var email: Set<String> = ["tom@abc.com"]
- // 交集
- XCTAssertEqual(emails.intersection(email), ["tom@abc.com"])
- // 差集
- XCTAssertEqual(emails.subtracting(email), ["mac@abc.com"])
- // 對稱差
- email.insert("kim@abc.com")
- XCTAssertEqual(emails.symmetricDifference(email), ["mac@abc.com", "kim@abc.com"])
- // 聯集
- XCTAssertEqual(emails.union(email), ["tom@abc.com", "mac@abc.com", "kim@abc.com"])
- // 不交集
- let newEmail: Set<String> = ["new@abc.com"]
- XCTAssertTrue(emails.isDisjoint(with: newEmail))
- XCTAssertTrue(newEmail.isDisjoint(with: emails))
- }
- func testGenerateSetFromSet() {
- let emails: Set<String> = ["tom@abc.com", "mac@abc.com"]
- let moreEmails = NSMutableSet(set: emails)
- moreEmails.add("joe@abc.com")
- XCTAssertEqual(3, moreEmails.count)
- XCTAssertTrue(emails.isSubset(of: moreEmails as! Set<String>))
- }
- func testSortedSet() {
- let emails: Set<String> = ["tom@abc.com", "mac@abc.com"]
- var sortedEmails = Array<String>()
- for e in emails.sorted() {
- sortedEmails.append(e)
- }
- XCTAssertEqual("mac@abc.com", sortedEmails.first)
- XCTAssertEqual("tom@abc.com", sortedEmails.last)
- }
- func testCreateEmptyDictionary() {
- let emptyDictionary = [String:Float]()
- XCTAssertTrue(type(of: emptyDictionary) == Dictionary<String, Float>.self)
- let emptyDictionary2 = Dictionary<String, Float>()
- XCTAssertTrue(type(of: emptyDictionary) == type(of: emptyDictionary2))
- }
- func testSimpleDictionary() {
- var simpleMembers: [Int: String] = [1: "John", 2: "Tom", 3: "Doris"]
- XCTAssertTrue(simpleMembers[2] == "Tom")
- }
- func testComplexDictionary() {
- var members: [[String: String]] = [
- ["name": "John",
- "email": "john@abc.com",
- "id": "1"],
- ["name": "Tom",
- "email": "tom@abc.com",
- "id": "2"],
- ["name": "Doris",
- "email": "doris@abc.com",
- "id": "3"],
- ]
- XCTAssertEqual(members[0]["email"], "john@abc.com")
- XCTAssertEqual(members[1]["name"], "Tom")
- XCTAssertEqual(members[2]["id"], "3")
- }
- func testDictionaryUpdate() {
- var members: [[String: String]] = [
- ["name": "John",
- "email": "john@abc.com",
- "id": "1"],
- ["name": "Tom",
- "email": "tom@abc.com",
- "id": "2"]
- ]
- members[1].updateValue("tony@abc.com", forKey: "email")
- members[1].updateValue("Tony", forKey: "name")
- XCTAssertEqual(members[1]["name"], "Tony")
- }
- func testThroughOutDictionary() {
- let members: [[String: String]] = [
- ["name": "John",
- "email": "john@abc.com",
- "id": "1"],
- ["name": "Tom",
- "email": "tom@abc.com",
- "id": "2"],
- ["name": "Doris",
- "email": "doris@abc.com",
- "id": "3"],
- ]
- var memberNames: Set<String> = Set<String>()
- for member in members {
- let memberInfo: [String: String] = member as [String: String]
- for (key, value) in memberInfo { // 使用 Tuple + for-in 結合
- if key == "name" {
- memberNames.insert(value)
- }
- }
- }
- XCTAssertEqual(memberNames, Set<String>(arrayLiteral: "John", "Tom", "Doris"))
- }
- func testTupleGetElementByIndex() {
- let aTuple = (1, "someone's name", true)
- XCTAssertEqual("someone's name", aTuple.1)
- }
- func testTuplePositionParameters() {
- let (_, _, z) = (1, 2, 3)
- XCTAssertEqual(3, z)
- let (_, y, _) = (1, 2, 3)
- XCTAssertEqual(2, y)
- }
- func testTupleHasParameterLabel() {
- let vector3D = (x: 1, y: 2, z: 3)
- XCTAssertEqual(2, vector3D.y)
- }
- func testCompareBetweenTuples() {
- let vector3D = (x: 1, y: 2, z: 3)
- XCTAssertEqual(2, vector3D.y)
- let anotherVector3D = (x: 1, y:2, z: 4)
- XCTAssertTrue(vector3D < anotherVector3D)
- }
- func testTupleWithSwitch() {
- let xValue = Int(arc4random_uniform(5) + 1)
- let yValue = Int(arc4random_uniform(5) + 1)
- let point = (xValue, yValue)
- var descriptionOfPoint: String = ""
- switch point {
- case (0, 0):
- descriptionOfPoint = "該點為原點"
- case (0, _):
- descriptionOfPoint = "該點在 Y 軸上"
- case (_, 0):
- descriptionOfPoint = "該點在 X 軸上"
- case let (x, y) where x == -y: // Value Bindings + where clause
- descriptionOfPoint = "該點在第四象限上"
- case let (x, y): // Value Bindings
- descriptionOfPoint = "該點(\(x),\(y))不在任何軸上"
- }
- print(descriptionOfPoint)
- XCTAssertEqual(descriptionOfPoint, "該點(\(xValue),\(yValue))不在任何軸上")
- }
- func testStructureIsImmutable() {
- struct S {
- var aValue: Int?
- }
- var s1 = S()
- s1.aValue = 1
- var s2 = s1
- s2.aValue = 2
- XCTAssertEqual(1, s1.aValue)
- }
- func testClassIsMutable() {
- class C {
- var aValue: Int?
- }
- let c1 = C()
- c1.aValue = 1
- let c2 = c1
- c2.aValue = 2
- XCTAssertEqual(2, c1.aValue)
- }
- func testSimpleClosure() {
- var result: String? = nil
- let aSimpleClosure = { () -> Void in
- result = "A Simple Closure."
- }
- aSimpleClosure()
- XCTAssertEqual("A Simple Closure.", result)
- }
- func testSimplestClosure() {
- var result: String? = nil
- let aSimplestClosure = {
- result = "A Simplest Closure."
- }
- aSimplestClosure()
- XCTAssertEqual("A Simplest Closure.", result)
- }
- func testClosureAsFunctionParameter() {
- func setResult(_ aClosure: ()->Void) {
- aClosure()
- }
- var result: String? = nil
- let aSimplestClosure = {
- result = "A Simplest Closure."
- }
- setResult(aSimplestClosure)
- XCTAssertEqual("A Simplest Closure.", result)
- }
- func testClosureAsReturnType() {
- func chineseToEnglish(word: String) -> String {
- if word == "您好" {
- return "Hello"
- }
- return "無法翻譯"
- }
- func chineseToNihongo(word: String) -> String {
- if word == "您好" {
- return "こんちは"
- }
- return "無法翻譯"
- }
- func getTranslator(from: String, to: String) -> ((String) -> String) {
- if from == "中" && to == "英" {
- return chineseToEnglish
- } else if from == "中" && to == "日" {
- return chineseToNihongo
- }
- return {(String) -> String in return "無法翻譯"}
- }
- let translator = getTranslator(from: "中", to: "英")
- XCTAssertTrue(translator("您好") == "Hello")
- XCTAssertTrue(translator("大家好") == "無法翻譯")
- }
- func testTrailingClosure() {
- func executeClosure(_ closure: () -> String) -> String {
- return closure()
- }
- let result = executeClosure() {
- return "Hello"
- }
- XCTAssertEqual("Hello", result)
- }
- func testTailingClousre2() {
- func anotherFunction(_ arg1: String, _ arg2: ()-> String) -> String{
- return "\(arg1), \(arg2())"
- }
- XCTAssertEqual ("Hello, World", anotherFunction("Hello") { return "World" })
- }
- func testKeepArgs() {
- var args: [String] = [String]()
- func aFunction(_ arg: String) {
- args.append(arg)
- }
- aFunction("Hello")
- XCTAssertEqual(1, args.count)
- }
- func testKeepClosures() {
- var closures: [()->String] = [()->String]()
- func aFunction(_ closure: @escaping ()->String) {
- closures.append(closure)
- }
- aFunction() {
- return "Hello."
- }
- XCTAssertEqual("Hello.", closures.first!())
- }
- func testAutoClosure() {
- var steps = [String]()
- func readFile(_ filename: String) -> String {
- steps.append("==> ①")
- return "hello"
- }
- func aFunctionIncludeAutoClosure(filename: String, fileContent: @autoclosure () -> String) {
- steps.append("==> ②")
- if filename != "" {
- steps.append("==> ③")
- XCTAssertEqual("hello", fileContent())
- }
- }
- steps.append("==> ④")
- let filename = "aFile.txt"
- aFunctionIncludeAutoClosure(filename: filename, fileContent: readFile(filename))
- XCTAssertEqual(steps, ["==> ④", "==> ②", "==> ③", "==> ①"])
- }
- func testCommonFunction() {
- func greet(myFriend person: String) -> String {
- return "Hello, \(person)"
- }
- XCTAssertTrue(greet(myFriend: "Tom") == "Hello, Tom")
- }
- func testFunctionUseArgNameAsLabel() {
- func greet(person: String) -> String {
- return "Hello, \(person)"
- }
- XCTAssertTrue(greet(person: "Tom") == "Hello, Tom")
- }
- func testFunctionIgnoreLabel() {
- func greet(_ person: String) -> String {
- return "Hello, \(person)"
- }
- XCTAssertTrue(greet("Tom") == "Hello, Tom")
- }
- func testFunctionHasDefaultParameterValues() {
- func welcome(name: String = "Guest") -> String {
- return "Hello, \(name)."
- }
- XCTAssertEqual("Hello, Guest.", welcome())
- }
- func testVariadicParameters() {
- func addTotal(_ numbers: Int...) -> Int {
- var total: Int = 0
- for number in numbers {
- total += number
- }
- return total
- }
- XCTAssertEqual(10, addTotal(2, 3, 4, 1))
- }
- func testInOutParameters() {
- func swap(number1: inout Int, number2: inout Int) {
- let tempNumber = number1
- number1 = number2
- number2 = tempNumber
- }
- var n1 = 5, n2 = 3
- swap(number1: &n1, number2: &n2)
- XCTAssertEqual(3, n1)
- XCTAssertEqual(5, n2)
- }
- func testDiscardableResultMethod() {
- @discardableResult
- func aMethod() -> String {
- return "hello."
- }
- aMethod() // 若沒有加上 @discardableResult 會出現告警:Result of call to 'aMethod()' is unused.
- }
- func testDefer() {
- var aNumber = 0
- func aFunction() {
- defer {
- aNumber = 0
- }
- aNumber = 1
- aNumber = 2
- XCTAssertEqual(2, aNumber)
- }
- aFunction()
- XCTAssertEqual(0, aNumber)
- }
- func testInitializerWithoutInheritance() {
- class A {
- var result: String = "a"
- init(newResult: String) { // 指定建構子
- self.result = newResult // 由於 A 不為任何類的子類,所以不需要呼叫 super。
- }
- convenience init() { // 便利建構子
- self.init(newResult: "") // 便利建構子呼叫指定建構子
- }
- required init(aBool: Bool) {}
- }
- let a = A() // 以便利建構子生成 A 的實例
- XCTAssertEqual("", a.result)
- }
- func testInitializerWithInheritance() {
- class A {
- var result: String = "a"
- init(newResult: String) {
- self.result = newResult
- }
- convenience init() {
- self.init(newResult: "")
- }
- required init(aBool: Bool) {}
- }
- class B: A {
- var number: Int?
- // 繼承自父類的建構子
- override init(newResult: String) {
- super.init(newResult: "結果: \(newResult)")
- }
- // 可失敗建構子 (Failable Initializer)
- init?(number: Int?) {
- super.init(newResult: "b")
- if number == nil { return nil }
- self.number = number
- }
- // 便利建構子的覆寫不需要宣告 override
- // 便利建構子不會被繼承
- convenience init() {
- self.init(newResult: "b")
- }
- // 由於父類 (A) 有宣告此建構A子,子類必須也加上
- required init(aBool: Bool) {
- super.init(aBool: aBool)
- }
- }
- let b = B()
- XCTAssertEqual("結果: b", b.result)
- XCTAssertNil(B(number: nil))
- }
- func testDeInitializer() {
- class A {
- var aProperty: String = ""
- }
- class B {
- var aAInstance: A = A()
- deinit {
- aAInstance.aProperty = "B is over."
- }
- }
- var b = B()
- let a = b.aAInstance
- XCTAssertEqual("", a.aProperty)
- b = B() // 取代舊的 B 實例
- XCTAssertEqual("B is over.", a.aProperty)
- }
- func testReferenceDeadLock() {
- class Book {
- var author: Author?
- }
- class Author {
- var book: Book?
- }
- var aBook: Book? = Book()
- let aAuthor: Author? = Author()
- aBook!.author = aAuthor
- aAuthor!.book = aBook
- aBook = nil
- XCTAssertNotNil(aAuthor!.book)
- }
- func testWeakReference() {
- class Book {
- var author: Author?
- }
- class Author {
- weak var book: Book?
- }
- var aBook: Book? = Book()
- let aAuthor: Author? = Author()
- aBook!.author = aAuthor
- aAuthor!.book = aBook
- aBook = nil
- XCTAssertNil(aAuthor!.book)
- }
- func testLazyStoredProperties() {
- class Animal {
- lazy var isLive: Bool = true // 在特性前加上 lazy 關鍵字
- var isHappy: Bool = true
- }
- let animal = Animal()
- // 為了能夠檢查在記憶體裡的狀況,這裡需使用 Swift 的反射 (reflect) 語法
- let mirror = Mirror(reflecting: animal)
- // 取出物件的第一個特性,先證明為 isLive 特性
- XCTAssertEqual("isLive.storage", mirror.children.first?.label)
- // 並證明其值仍為 nil,還沒被設定為 true
- XCTAssertEqual("nil", String(describing: (mirror.children.first?.value)!))
- // 取出物件的另一個特性,應該是 isHappy,並證明其值已經被設定為 true
- XCTAssertEqual("true",
- String(describing: (mirror.children[mirror.children.index(after: mirror.children.startIndex)].value)))
- // 取用 isLive 特性
- let _ = animal.isLive
- // 取出物件的第一個特性,先證明為 isLive 特性
- XCTAssertEqual("isLive.storage", mirror.children.first?.label)
- // 並證明其值被設定為 true (為 optional 型別)
- XCTAssertEqual("Optional(true)",
- String(describing: (mirror.children.first?.value)!))
- }
- func testTypePropertiesAndMethods() {
- class Util {
- static var inch: Float = 0.0
- static func centWith() -> Float {
- return inch * 2.54
- }
- static func centWith(inch: Float) -> Float {
- return inch * 2.54
- }
- }
- Util.inch = 2
- XCTAssertEqual(5.08, Util.centWith())
- XCTAssertEqual(2.54, Util.centWith(inch: 1))
- }
- func testBoringExample() {
- class SomeClass {
- var someProperty: String = ""
- func getSomeValue() -> String {
- return "hello"
- }
- }
- let aInstance = SomeClass()
- aInstance.someProperty = aInstance.getSomeValue()
- XCTAssertEqual("hello", aInstance.someProperty)
- }
- func testAssignClosureResultToProperty() {
- class SomeClass {
- let someProperty: String = {
- return "some value"
- }()
- }
- XCTAssertEqual("some value", SomeClass().someProperty)
- }
- func testAssignInstanceProperty() {
- class SomeClassForProperty: NSObject {
- override var description: String {
- return "some value"
- }
- }
- class SomeClass {
- let someProperty: String = SomeClassForProperty().description
- }
- XCTAssertEqual("some value", SomeClass().someProperty)
- }
- func testExtension() {
- XCTAssertEqual("Hello".toChinese(), "您好")
- }
- func testExtensionImplementProtocol() {
- XCTAssertEqual("Hello".sayFrenchHello(), "Bonjour")
- }
- func testOptionalProtocol() {
- class SomeClass: AOptionalProtocol {}
- XCTAssertNotNil(SomeClass())
- }
- func testClassOnlyProtocols() {
- class SomeClass: SomeClassProtocol {}
- /*
- 由於 SomeClassProtocol 是繼承自 AnyObject 這個協定,
- 所以無法使用下列代碼讓結構/列舉宣告實作 SomeClassProtocol。
- struct SomeStructure: SomeClassProtocol {}
- 或
- enum SomeEnum: SomeClassProtocol {}
- 錯誤訊息如下:
- Non-class type 'SomeStructure'
- cannot conform to class protocol 'SomeClassProtocol'
- */
- }
- func testSeveralTypesEnum() {
- enum Emotion {
- case happy, sad
- case laugh()
- case eat(foodName: String) /* Associated Values */
- func brief() -> String {
- switch self {
- case .eat(foodName: let fName):
- return "有些人心情不好會大吃\(fName)一頓"
- default:
- return ""
- }
- }
- }
- let eatEmotion: Emotion = Emotion.eat(foodName: "牛排")
- XCTAssertEqual(eatEmotion.brief(), "有些人心情不好會大吃牛排一頓")
- }
- func testEnumRawValue() {
- enum Season: Int {
- case Spring, Summer, Fall, Winter
- }
- XCTAssertEqual(Season(rawValue: 1), Season.Summer)
- XCTAssertEqual(Season(rawValue: 3), Season.Winter)
- }
- func testEnumOfCustomRawValue() {
- enum Swith: Int {
- case ON = 1, OFF = 0
- }
- XCTAssertEqual(Swith(rawValue: 1), Swith.ON)
- }
- func testGenerics() {
- func add<Item>(item1: Item, item2: Item) -> Any {
- if item1 is Int {
- return (item1 as! Int) + (item2 as! Int)
- }
- if item1 is Double {
- return (item1 as! Double) + (item2 as! Double)
- }
- if item1 is String {
- return "\(item1)\(item2)"
- }
- return EMPTY
- }
- XCTAssertEqual(2, add(item1: 1, item2: 1) as! Int)
- XCTAssertEqual(2.5, add(item1: 0.5, item2: 2) as! Double)
- XCTAssertEqual("11", add(item1: "1", item2: "1") as! String)
- }
- func testErroHandler() {
- enum RequestError: Error {
- case wrongFormat
- case deadNetwork
- func simpleDescription() -> String {
- if self == RequestError.wrongFormat {
- return "wrong format"
- }
- if self == RequestError.deadNetwork {
- return "dead network"
- }
- return "unknown"
- }
- }
- func checkNetworkAvailable() -> Bool {
- return true
- }
- func request(parameter: Dictionary<String, String>?) throws -> (String, String) {
- if parameter == nil || parameter?.keys.count == 0 {
- throw RequestError.wrongFormat
- }
- if !checkNetworkAvailable() {
- throw RequestError.deadNetwork
- }
- return ("200", "OK")
- }
- XCTAssertThrowsError(try request(parameter: Dictionary<String, String>()),
- "Parameter dictionary is empty") { (error) in
- XCTAssertTrue(error is RequestError)
- }
- var errorReason: String? = nil
- do {
- let response = try request(parameter: Dictionary<String, String>())
- print(response)
- } catch RequestError.wrongFormat {
- errorReason = RequestError.wrongFormat.simpleDescription()
- } catch RequestError.deadNetwork {
- errorReason = RequestError.deadNetwork.simpleDescription()
- } catch {
- errorReason = "Unknown"
- }
- XCTAssertEqual("wrong format", errorReason)
- let response = try? request(parameter: Dictionary<String, String>())
- XCTAssertNil(response)
- }
- func testIf() {
- let number1 = 10
- let number2 = 9
- let number3 = 8
- var result = 0
- /* 以下三個例子是同義的 */
- if number1 > number2 {
- if number2 > number3 {
- result += 1
- }
- }
- if (number1 > number2) && (number2 > number3) {
- result += 1
- }
- if number1 > number2, number2 > number3 {
- result += 1
- }
- XCTAssertEqual(3, result)
- if (number1 < number2) || (number2 > number3) {
- result += 1
- }
- XCTAssertEqual(4, result)
- }
- func testNilCoalescingOperator() {
- var aInt: Int?
- aInt = Int("1")
- XCTAssertEqual(1, aInt ?? 0)
- aInt = Int("a")
- XCTAssertEqual(0, aInt ?? 0)
- }
- func testTernaryConditionalOperator() {
- let score = 65
- XCTAssertEqual("考試通過", ((score >= 60) ? "考試通過" : "考試不及格"))
- }
- func testClosedRange() {
- var result:Int = 0
- for number in 1...10 {
- result += number
- }
- XCTAssertEqual(55, result)
- }
- func testHalfOpenRange() {
- var result:Int = 0
- for number in 1..<11 {
- result += number
- }
- XCTAssertEqual(55, result)
- }
- func testMultilineString() {
- let articleTexts = """
- 歡迎一起來學習 Swift "最新版"!
- Swift 是蘋果官方發佈的程式語言。
- """
- XCTAssertNotEqual("歡迎一起來學習 Swift \"最新版\"!Swift 是蘋果官方發佈的程式語言。", articleTexts)
- XCTAssertEqual("歡迎一起來學習 Swift \"最新版\"!\nSwift 是蘋果官方發佈的程式語言。", articleTexts)
- }
- func testSpecialCharacters() {
- let blackHeart = "\u{2665}"
- XCTAssertEqual(blackHeart, "♥")
- }
- func testGetFirstCharacterFromString() {
- let greeting = "您好,有什麼能為您服務的?"
- XCTAssertEqual("您", greeting[greeting.startIndex])
- }
- func testCountStringLength() {
- let greeting = "您好,有什麼能為您服務的?"
- XCTAssertEqual(greeting.count, greeting.endIndex.encodedOffset)
- }
- func testSubStringWithBefore() {
- let greeting = "您好,有什麼能為您服務的?"
- XCTAssertEqual("?", greeting[greeting.index(before: greeting.endIndex)])
- }
- func testFromIntToStringIndex() {
- let greeting = "您好,有什麼能為您服務的?"
- XCTAssertEqual("?", greeting[greeting.index(before: String.Index(encodedOffset: greeting.count))])
- }
- func testGetIndexPositonOfCharacter() {
- let greeting = "您好,有什麼能為您服務的?"
- let indexOfComma = greeting.index(of: ",")
- XCTAssertEqual(indexOfComma, String.Index(encodedOffset: 2))
- }
- func testStringReverse() {
- let greeting = "您好,有什麼能為您服務的?"
- XCTAssertEqual("?的務服您為能麼什有,好您", String(greeting.reversed()))
- }
- func testStringInsert() {
- var welcome = "hello"
- // 插入字元
- welcome.insert(",", at: welcome.endIndex)
- XCTAssertEqual("hello,", welcome)
- // 插入字串
- welcome.insert(contentsOf: " world.", at: welcome.endIndex)
- XCTAssertEqual("hello, world.", welcome)
- }
- func testStringRemove() {
- var welcome = "hello, world."
- welcome.remove(at: welcome.index(before: welcome.endIndex))
- XCTAssertEqual("hello, world", welcome)
- welcome.removeSubrange(
- welcome.index(welcome.endIndex, offsetBy: -(", world".count))
- ..<
- welcome.endIndex)
- XCTAssertEqual("hello", welcome)
- }
- }
- protocol LearningLanguage {
- var languageName: String {get set}
- var description: String {get set}
- func recite()
- }
- protocol LearningLanguageWithMutaingKeyword {
- var languageName: String {get set}
- var description: String {get set}
- mutating func recite()
- }
- @objc protocol AOptionalProtocol {
- @objc optional func aOptionalMethod()
- }
- extension String {
- func toChinese() -> String {
- if self == "Hello" {
- return "您好"
- }
- return "Unknown"
- }
- }
- protocol LearningFrench {
- func sayFrenchHello() -> String
- }
- extension String: LearningFrench {
- func sayFrenchHello() -> String {
- if self == "Hello" {
- return "Bonjour"
- }
- return "Unknown"
- }
- }
- protocol SomeClassProtocol: AnyObject {} // AnyObject 為 protocol
- class JustForGenerics: XCTestCase {
- func testTypeConstraintGenerics() {
- func add<Item: Addable>(item1: Item, item2: Item) -> Item {
- return item1 + item2
- }
- XCTAssertEqual(2, add(item1: 1, item2: 1))
- XCTAssertEqual("11", add(item1: "1", item2: "1"))
- }
- }
- protocol Addable {
- static func +(lItem: Self, rItem: Self) -> Self
- }
- extension Int: Addable {}
- extension String: Addable {
- static func +(lItem: String, rItem: String) -> String {
- return "\(lItem)\(rItem)"
- }
- }
Add Comment
Please, Sign In to add comment