Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ソースコードから読み解く - Quick はどのように実装されているのか?/quick-code-reading

70d9714ea13fc1133803d61fb16e4160?s=47 Yusuke Hosonuma
September 12, 2018

ソースコードから読み解く - Quick はどのように実装されているのか?/quick-code-reading

俺コン 2018 Summer / Day. 1
https://orecon.connpass.com/event/94858/

70d9714ea13fc1133803d61fb16e4160?s=128

Yusuke Hosonuma

September 12, 2018
Tweet

Transcript

  1. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ιʔείʔυ͔ΒಡΈղ͘ 2VJDL͸ͲͷΑ͏ʹ ࣮૷͞Ε͍ͯΔͷ͔ʁ

    1 Զίϯ 2018 Summer / Day. 1 2018/09/12 (Wed) 
 ࡉপ ༞հ@DeNA
  2. "CPVU 2 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  3. :VTVLF)PTPOVNB • ॴଐ ⁃ %F/"ɹ48&5άϧʔϓɹςετج൫νʔϜ • 'BWPSJUF ⁃  •

    ۙگ ⁃ J04%$Ͱ෼ൃද ⁃ ੔ମ͸͍͍ͧʂ Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 3 @tobi462ʢτϏʣ Swift 4.2
  4. :VTVLF)PTPOVNB • ॴଐ ⁃ %F/"ɹ48&5άϧʔϓɹςετج൫νʔϜ • 'BWPSJUF ⁃  •

    ۙگ ⁃ J04%$Ͱ෼ൃද ⁃ ੔ମ͸͍͍ͧʂ Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 4 @tobi462ʢτϏʣ Swift 4.2 ݄ࠒʹ։࠵ʁ
  5. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 5 $G1ݕࡧαʔϏε ϖϯΪϯଜ5FDIͰ࡞Γ·ͨ͠ʂ

    ൃදεϥΠυ΁ͷϦϯΫ
  6. Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 6 $G1ݕࡧαʔϏε ϖϯΪϯଜ5FDIͰ࡞Γ·ͨ͠ʂ

    ൃදεϥΠυ΁ͷϦϯΫ iosdc-cfps.penginmura.tech
  7. 2VJDL 7 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  8. 8 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. #%%ϑϨʔϜϫʔΫ 4XJGUൃදͷ೔ޙʹ044ެ։

    9$5FTUͱ౷߹ • ςετφϏήʔλͰදࣔ • Τϥʔϝοηʔδ΋ͪΌΜͱग़Δ Quick 34QFDΠϯεύΠΞ
  9. /JNCMF 9 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  10. Nimble 10 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ΞαʔγϣϯϥΠϒϥϦ

    .BUIDFS"1* 2VJDL͔Β͸ಠཱ Nimble
  11. 11 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. import XCTest

    import Quick import Nimble class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } }
  12. 12 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. import XCTest

    import Quick import Nimble class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } ςετߏ଄Խͱͯ͠ͷ2VJDL
  13. 13 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. import XCTest

    import Quick import Nimble class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } Ξαʔγϣϯͱͯ͠ͷ/JNCMF
  14. 14 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Xcode

  15. 15 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. φϏήʔλʹදࣔ Xcode

  16. 16 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ςετͱͯ͠ೝࣝ Xcode

  17. 17 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Τϥʔ͕ΤσΟλʹදࣔ Xcode

    Quick ͸Α͘Ͱ͖ͯΔͳ͊ Swift ΫϩʔδϟʹΑΔ DSL ΋ૉఢͩ
  18. ͱ͜ΖͰ 18 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  19. 19 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Α͘ߟ͑ͯΈΔͱ Ͳ͏΍࣮ͬͯݱ͞ΕͯΔΜͩΖ͏ʁ

    ͋ΒͨΊͯݟͯΈΔ
  20. 20 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  21. 21 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ͳͥφϏήʔλʹJUʹରԠ͢Δ໊લ͕ʁ

  22. 22 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. UFTU9YYͬͯϝιου໊͡Όͳ͍͚Ͳʁ

  23. 23 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ؔ਺ͳͷʹͲ͏΍ͬͯ%4-ߏ଄Λอ࣋ʁ

  24. 24 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Τϥʔ΋Ͳ͏΍ͬͯग़ͯ͠ΔΜͩʁ

  25. 25 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. Τϥʔ΋Ͳ͏΍ͬͯग़ͯ͠ΔΜͩʁ ෼͔Βͳ͍

    Զͨͪ͸งғؾͰ Quick Λॻ͍͍ͯΔ
  26. 5PEBZ 26 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  27. ࿩͢͜ͱ 27 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 2VJDL͕Ͳ͏΍࣮ͬͯݱ͞ΕͯΔ͔ʁ

    • 9$5FTUͱͷ౷߹ • %4- ࿩͞ͳ͍͜ͱ 2VJDL/JNCMFͷ࢖͍ํ /JNCMFͷ࢓૊Έ ϚϧνϓϥοτϑΥʔϜରԠͱ͔ Today ίʔυΛಡΈͭͭʂ ࡉ͔͍ͱ͜Ζ͸ׂѪ͍ͯ͘͠ʂ
  28. 28 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ίʔυϦʔσΟϯά͍ͯ͘͠ͱ͜Ζ 

    ΤϯτϦϙΠϯτ  %4-͔Βͷߏ଄ͷ૊Έཱͯ  9$5FTU͔Βͷݺͼग़͠
  29. 29 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ίʔυϦʔσΟϯά͍ͯ͘͠ͱ͜Ζ 

    ΤϯτϦϙΠϯτ  %4-͔Βͷߏ଄ͷ૊Έཱͯ  9$5FTU͔Βͷݺͼग़͠ Let’s Code Reading !
  30. ϥΠϒϥϦͷؔ܎ 30 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  31. 31 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 2VJDL /JNCMF

    9$5FTU 'PVOEBUJPO 0CKFDUJWF$3VOUJNFΛར༻ ར༻͸೚ҙ ϥΠϒϥϦͷؔ܎
  32. 32 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 2VJDL /JNCMF

    9$5FTU 'PVOEBUJPO ࠓ͔Βݟ͍ͯ͘ ϥΠϒϥϦͷؔ܎
  33. ΤϯτϦϙΠϯτ 33 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  34. 34 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. import XCTest

    import Quick import Nimble class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } }
  35. 35 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. import XCTest

    import Quick import Nimble class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } ࠓճͷαϯϓϧͷ4QFD
  36. 36 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. import XCTest

    import Quick import Nimble class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } Ͳ͔͜Βݺ͹Ε͍ͯΔ͔ʁ
  37. 37 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. import XCTest

    import Quick import Nimble class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } ਌ΫϥεΛݟͯΈΔ
  38. 38 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. #import <XCTest/XCTest.h>

    @interface QuickSpec : XCTestCase - (void)spec; @property (class, nonatomic, readonly) QuickSpec *current; @end QuickSpec.h
  39. 39 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. #import <XCTest/XCTest.h>

    @interface QuickSpec : XCTestCase - (void)spec; @property (class, nonatomic, readonly) QuickSpec *current; @end QuickSpec.h ͍͖ͳΓ Objective-C ʂ Ͱ΋ɺ਺গͳ͍͏ͪͷ1ιʔε
  40. 40 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // QuickSpec.h

    #import <XCTest/XCTest.h> @interface QuickSpec : XCTestCase - (void)spec; @property (class, nonatomic, readonly) QuickSpec *current; @end 9$5FTU$BTFΛܧঝ͍ͯ͠Δ QuickSpec.h
  41. 41 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // QuickSpec.m

    @implementation QuickSpec + (void)initialize { [QuickConfiguration initialize]; World *world = [World sharedWorld]; [world performWithCurrentExampleGroup:[world rootExampleGroupForSpecClass:self] closure:^{ QuickSpec *spec = [self new]; @try { [spec spec]; } @catch (NSException *exception) { ... } [self testInvocations]; }]; } QuickSpec.m
  42. 42 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // QuickSpec.m

    @implementation QuickSpec + (void)initialize { [QuickConfiguration initialize]; World *world = [World sharedWorld]; [world performWithCurrentExampleGroup:[world rootExampleGroupForSpecClass:self] closure:^{ QuickSpec *spec = [self new]; @try { [spec spec]; } @catch (NSException *exception) { ... } [self testInvocations]; }]; } 0CKFDUJWF$3VOUJNFʹΫϥε͕ ϩʔυ͞Εͨͱ͖ʹݺͼग़͞ΕΔ QuickSpec.m
  43. 43 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // QuickSpec.m

    @implementation QuickSpec + (void)initialize { [QuickConfiguration initialize]; World *world = [World sharedWorld]; [world performWithCurrentExampleGroup:[world rootExampleGroupForSpecClass:self] closure:^{ QuickSpec *spec = [self new]; @try { [spec spec]; } @catch (NSException *exception) { ... } [self testInvocations]; }]; } 8PSMEͷ4JOHMFUPOΛऔಘ͠ ΫϩʔδϟΛ࣮ߦ͠Α͏ͱ͍ͯ͠Δ QuickSpec.m
  44. 44 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // QuickSpec.m

    @implementation QuickSpec + (void)initialize { [QuickConfiguration initialize]; World *world = [World sharedWorld]; [world performWithCurrentExampleGroup:[world rootExampleGroupForSpecClass:self] closure:^{ QuickSpec *spec = [self new]; @try { [spec spec]; } @catch (NSException *exception) { ... } [self testInvocations]; }]; } ͜͜Ͱࣗ਎ͷΠϯελϯεΛੜ੒ͯ͠ TQFDΛ࣮ߦ͍ͯ͠Δʂ QuickSpec.m
  45. 45 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // QuickSpec.m

    @implementation QuickSpec + (void)initialize { [QuickConfiguration initialize]; World *world = [World sharedWorld]; [world performWithCurrentExampleGroup:[world rootExampleGroupForSpecClass:self] closure:^{ QuickSpec *spec = [self new]; @try { [spec spec]; } @catch (NSException *exception) { ... } [self testInvocations]; }]; } ͜͜Ͱࣗ਎ͷΠϯελϯεΛੜ੒ͯ͠ TQFDΛ࣮ߦ͍ͯ͠Δʂ QuickSpec.m spec ͕ݺ͹ΕΔ࢓૊Έ͸ ͳΜͱͳ͘Θ͔ͬͨͧʂ
  46. 46 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ͜͜·Ͱग़͖ͯͨιʔε CalcSpec.swift

    QuickSpec.h / m
  47. %4-ͷॲཧ 47 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  48. 48 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift
  49. 49 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } ߏ଄తʹ͸͜͏ͳͬͯΔ CalcSpec.swift beforeEach describe context it describe
  50. 50 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } ߏ଄తʹ͸͜͏ͳͬͯΔ CalcSpec.swift beforeEach describe context it describe ॱ൪ʹݟ͍ͯ͘
  51. 51 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe
  52. EFTDSJCF 52 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  53. 53 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. public func

    describe(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.describe(description, flags: flags, closure: closure) } public func context(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.context(description, flags: flags, closure: closure) } public func beforeEach(_ closure: @escaping BeforeExampleClosure) { World.sharedWorld.beforeEach(closure) } DSL.swift
  54. 54 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. public func

    describe(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.describe(description, flags: flags, closure: closure) } public func context(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.context(description, flags: flags, closure: closure) } public func beforeEach(_ closure: @escaping BeforeExampleClosure) { World.sharedWorld.beforeEach(closure) } ... 8PSMEͷγϯάϧτϯʹରͯ͠ ҕৡ͍ͯ͠Δ͚ͩ DSL.swift
  55. 55 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } World+DSL.swift
  56. 56 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } 8PSMEͷFYUFOTJPO World+DSL.swift
  57. 57 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } &YBNQMF(SPVQΛੜ੒ͯ͠ World+DSL.swift
  58. 58 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } ݱࡏͷ&YBNQMF(SPVQʹ௥Ճ͠ World+DSL.swift
  59. 59 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } ΫϩʔδϟΛ౉࣮ͯ͠ߦ͍ͯ͠Δʂ World+DSL.swift
  60. 60 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } World.swift
  61. 61 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } ୀආͯ͠ݱࡏͷ&YBNQMF(SPVQΛஔ͖׵͑ World.swift
  62. 62 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } ΫϩʔδϟΛ࣮ߦ͠ World.swift
  63. 63 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } ୀආͯͨ͠&YBNQMF(SPVQΛݩʹ໭͍ͯ͠Δ World.swift
  64. 64 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } ୀආͯͨ͠&YBNQMF(SPVQΛݩʹ໭͍ͯ͠Δ World.swift closure ͬͯͳΜ͚ͩͬʁ ͦ͏͍͑͹
  65. 65 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // World.swift

    final internal class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } }
  66. 66 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // World.swift

    final internal class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } EFTDSJCFͷத਎ͩʂ
  67. 67 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // World.swift

    final internal class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } EFTDSJCFͷத਎ͩʂ ͳΜͱͳ͘ݟ͖͑ͯͨͧʂ
  68. 68 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ͜͜·Ͱग़͖ͯͨιʔε CalcSpec.swift

    QuickSpec.h / m World+DSL.swift World.swift
  69. CFGPSF&BDI 69 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  70. 70 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe
  71. 71 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. public func

    describe(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.describe(description, flags: flags, closure: closure) } public func context(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.context(description, flags: flags, closure: closure) } public func beforeEach(_ closure: @escaping BeforeExampleClosure) { World.sharedWorld.beforeEach(closure) } DSL.swift
  72. 72 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. public func

    describe(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.describe(description, flags: flags, closure: closure) } public func context(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.context(description, flags: flags, closure: closure) } public func beforeEach(_ closure: @escaping BeforeExampleClosure) { World.sharedWorld.beforeEach(closure) } DSL.swift ΍͸Γ8PSMEͷγϯάϧτϯʹରͯ͠ Ҡৡ͍ͯ͠Δ͚ͩ
  73. 73 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. public func

    describe(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.describe(description, flags: flags, closure: closure) } public func context(_ description: String, flags: FilterFlags = [:], closure: () -> Void) { World.sharedWorld.context(description, flags: flags, closure: closure) } public func beforeEach(_ closure: @escaping BeforeExampleClosure) { World.sharedWorld.beforeEach(closure) } DSL.swift ΍͸Γ8PSMEͷγϯάϧτϯʹରͯ͠ Ҡৡ͍ͯ͠Δ͚ͩ DSL ෦෼͸ શ෦͜ͷ࢓૊ͬΆ͍ͧʁ
  74. 74 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } World+DSL.swift
  75. 75 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } ݱࡏͷ&YBNQMF(SPVQͷ World+DSL.swift
  76. 76 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } IPPLTʹΫϩʔδϟΛ௥Ճͯ͠Δ World+DSL.swift
  77. 77 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } // ExampleGroup.swift final public class ExampleGroup: NSObject { internal let hooks = ExampleHooks() } // ExampleHooks.swift final internal class ExampleHooks { internal var befores: [BeforeExampleWithMetadataClosure] = [] internal func appendBefore(_ closure: @escaping BeforeExampleClosure) { befores.append { (_: ExampleMetadata) in closure() } } } ExampleGroup.swift / ExampleHooks.swift
  78. 78 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } // ExampleGroup.swift final public class ExampleGroup: NSObject { internal let hooks = ExampleHooks() } // ExampleHooks.swift final internal class ExampleHooks { internal var befores: [BeforeExampleWithMetadataClosure] = [] internal func appendBefore(_ closure: @escaping BeforeExampleClosure) { befores.append { (_: ExampleMetadata) in closure() } } } ExampleGroup.swift / ExampleHooks.swift
  79. 79 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } // ExampleGroup.swift final public class ExampleGroup: NSObject { internal let hooks = ExampleHooks() } // ExampleHooks.swift final internal class ExampleHooks { internal var befores: [BeforeExampleWithMetadataClosure] = [] internal func appendBefore(_ closure: @escaping BeforeExampleClosure) { befores.append { (_: ExampleMetadata) in closure() } } } ഑ྻʹΫϩʔδϟΛBQQFOEͯ͠Δ ExampleGroup.swift / ExampleHooks.swift
  80. 80 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } // ExampleGroup.swift final public class ExampleGroup: NSObject { internal let hooks = ExampleHooks() } // ExampleHooks.swift final internal class ExampleHooks { internal var befores: [BeforeExampleWithMetadataClosure] = [] internal func appendBefore(_ closure: @escaping BeforeExampleClosure) { befores.append { (_: ExampleMetadata) in closure() } } } ഑ྻʹΫϩʔδϟΛBQQFOEͯ͠Δ ExampleGroup.swift / ExampleHooks.swift currentExampleGropup ͕ ͳΜ͔ͩϙΠϯτΈ͍ͨͧʁ
  81. 81 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } World+DSL.swift
  82. 82 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } // World.swift final internal class World: _WorldBase { internal var currentExampleGroup: ExampleGroup! internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } World+DSL.swift / World.swift
  83. 83 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } // World.swift final internal class World: _WorldBase { internal var currentExampleGroup: ExampleGroup! internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } 8PSME͕͍࣋ͬͯͯ World+DSL.swift / World.swift
  84. 84 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } // World.swift final internal class World: _WorldBase { internal var currentExampleGroup: ExampleGroup! internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } ͖ͬ͞Ұ࣌ୀආͯͨ͠΍ͭͩʂ World+DSL.swift / World.swift
  85. 85 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func beforeEach(_ closure: @escaping BeforeExampleClosure) { guard currentExampleMetadata == nil else { raiseError("...") } currentExampleGroup.hooks.appendBefore(closure) } } // World.swift final internal class World: _WorldBase { internal var currentExampleGroup: ExampleGroup! internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } ͖ͬ͞Ұ࣌ୀආͯͨ͠΍ͭͩʂ World+DSL.swift / World.swift ͳΜ͔ͩͭͳ͕͖ͬͯͨͧʁ
  86. 86 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ͜͜·Ͱग़͖ͯͨιʔε CalcSpec.swift

    QuickSpec.h / m World+DSL.swift World.swift ExampleGroup.swift ExampleHooks.swift
  87. EFTDSJCF 87 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ࠶ͼ

  88. 88 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe ͖ͬ͞ݟͨ΍ͭ
  89. 89 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } ࠶ܝ World+DSL.swift
  90. 90 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } ৽͍͠&YBNQMF(SPVQΛੜ੒ͯ͠ ݱࡏͷ&YBNQMF(SPVQʹ௥Ճ World+DSL.swift
  91. 91 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } ৽͍͠&YBNQMF(SPVQΛੜ੒ͯ͠ ݱࡏͷ&YBNQMF(SPVQʹ௥Ճ World+DSL.swift ExampleGroup ͬͯ describe ͷ͜ͱͰ͸ʁ
  92. 92 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } }
  93. 93 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } lBEEz ੜ੒ͯ͠Δͷ͸ࠓճͷEFTDSJCFͰ
  94. 94 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } લճͷ͕DVSSFOU&YBNQMF(SPVQͰ
  95. 95 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } ৽͍͠ͷΛ௥Ճͯ͠
  96. 96 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } ΫϩʔδϟΛ౉ͯ͠ॲཧͯ͠Δʂ
  97. 97 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // World+DSL.swift

    extension World { internal func describe(_ description: String, flags: FilterFlags, closure: () -> Void) { let group = ExampleGroup(description: description, flags: flags) currentExampleGroup.appendExampleGroup(group) performWithCurrentExampleGroup(group, closure: closure) } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } ΫϩʔδϟΛ౉ͯ͠ॲཧͯ͠Δʂ DSL ߏ଄͕૊ΈཱͯΒΕΔ ࢓૊Έ͕ݟ͖͑ͯͨͧʂ
  98. 98 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } World.swift
  99. 99 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } ྫͷҰ࣌ୀආͯͨ͠ίʔυ World.swift
  100. 100 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } ͖ͬ͞࡞ͬͨ&YBNQMF(SPVQͱ த਎ͷΫϩʔδϟ͕Ҿ਺ʹ World.swift
  101. 101 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } World currentExampleGroup ݱࡏͷ&YBNQMF(SPVQΛ World.swift
  102. 102 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } World currentExampleGroup ৽͍͠ͷʹ੾Γସ͑ͯ World.swift
  103. 103 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } ΫϩʔδϟΛධՁ͠ World currentExampleGroup World.swift
  104. 104 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. final internal

    class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } World currentExampleGroup ݩʹ໭͍ͯ͠Δʂ World.swift
  105. 105 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // World.swift

    final internal class World: _WorldBase { internal func performWithCurrentExampleGroup(_ group: ExampleGroup, closure: () -> Void) { let previousExampleGroup = currentExampleGroup currentExampleGroup = group closure() currentExampleGroup = previousExampleGroup } } class CalcSpec: QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } World currentExampleGroup ݩʹ໭͍ͯ͠Δʂ World.swift ͜Ε͕୯ͳΔؔ਺ʴΫϩʔδϟͰ ঢ়ଶΛอ࣋ͭͭ͠૊ΈཱͯΔ࢓૊Έ 8PSME͕ίϯςΩετΛ੾Γସ͍͑ͯ͘
  106. 106 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ͜͜·Ͱग़͖ͯͨιʔε CalcSpec.swift

    QuickSpec.h / m World+DSL.swift World.swift ExampleGroup.swift ExampleHooks.swift
  107. DPOUFYU 107 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  108. 108 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe
  109. 109 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func context(_ description: String, flags: FilterFlags, closure: () -> Void) { guard currentExampleMetadata == nil else { raiseError("...") } self.describe(description, flags: flags, closure: closure) } } World+DSL.swift
  110. 110 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func context(_ description: String, flags: FilterFlags, closure: () -> Void) { guard currentExampleMetadata == nil else { raiseError("...") } self.describe(description, flags: flags, closure: closure) } } EFTDSJCFΛݺΜͰΔ͚ͩ World+DSL.swift
  111. 111 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { internal func context(_ description: String, flags: FilterFlags, closure: () -> Void) { guard currentExampleMetadata == nil else { raiseError("...") } self.describe(description, flags: flags, closure: closure) } } EFTDSJCFΛݺΜͰΔ͚ͩ World+DSL.swift describe = context = ExampleGroup %4-ͱ໊ͯ͠લ͕ఏڙ͞Ε͍ͯΔ͚ͩ ࣮ଶ͸
  112. JU 112 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. lͦΕz͕ݟ͑ͨΒɺऴΘΓɻ

  113. 113 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } ࠷ޙʂ CalcSpec.swift beforeEach describe context it describe
  114. 114 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. public func

    it(_ description: String, flags: FilterFlags = [:], file: String = #file, line: UInt = #line, closure: @escaping () -> Void) { World.sharedWorld.it(description, flags: flags, file: file, line: line, closure: closure) } DSL.swift
  115. 115 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. public func

    it(_ description: String, flags: FilterFlags = [:], file: String = #file, line: UInt = #line, closure: @escaping () -> Void) { World.sharedWorld.it(description, flags: flags, file: file, line: line, closure: closure) } ϚΫϩͰʮϑΝΠϧʯͱʮߦʯΛड͚औΓ DSL.swift
  116. 116 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. public func

    it(_ description: String, flags: FilterFlags = [:], file: String = #file, line: UInt = #line, closure: @escaping () -> Void) { World.sharedWorld.it(description, flags: flags, file: file, line: line, closure: closure) } ͍ͭ΋ͷΑ͏ʹ8PSMEʹҕৡ DSL.swift
  117. 117 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { @nonobjc internal func it(_ description: String, flags: FilterFlags, file: String, line: UInt, closure: @escaping () -> Void) { let callsite = Callsite(file: file, line: line) let example = Example(description: description, callsite: callsite, flags: flags, closure: closure) currentExampleGroup.appendExample(example) } } World+DSL.swift
  118. 118 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { @nonobjc internal func it(_ description: String, flags: FilterFlags, file: String, line: UInt, closure: @escaping () -> Void) { let callsite = Callsite(file: file, line: line) let example = Example(description: description, callsite: callsite, flags: flags, closure: closure) currentExampleGroup.appendExample(example) } } ϑΝΠϧͱߦΛߏ଄ମʹϥοϓ͠ World+DSL.swift
  119. 119 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { @nonobjc internal func it(_ description: String, flags: FilterFlags, file: String, line: UInt, closure: @escaping () -> Void) { let callsite = Callsite(file: file, line: line) let example = Example(description: description, callsite: callsite, flags: flags, closure: closure) currentExampleGroup.appendExample(example) } } &YBNQMFΛੜ੒͠ World+DSL.swift
  120. 120 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. extension World

    { @nonobjc internal func it(_ description: String, flags: FilterFlags, file: String, line: UInt, closure: @escaping () -> Void) { let callsite = Callsite(file: file, line: line) let example = Example(description: description, callsite: callsite, flags: flags, closure: closure) currentExampleGroup.appendExample(example) } } DVSSFOU&YBNQMF(SPVQʹ௥Ճ World+DSL.swift
  121. 121 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // World+DSL.swift

    extension World { @nonobjc internal func it(_ description: String, flags: FilterFlags, file: String, line: UInt, closure: @escaping () -> Void) { let callsite = Callsite(file: file, line: line) let example = Example(description: description, callsite: callsite, flags: flags, closure: closure) currentExampleGroup.appendExample(example) } } DVSSFOU&YBNQMF(SPVQʹ௥Ճ Έͳ·Ͱݴ͏ͳ ΋͏෼͔͍ͬͯΔ
  122. 122 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. // World+DSL.swift

    extension World { @nonobjc internal func it(_ description: String, flags: FilterFlags, file: String, line: UInt, closure: @escaping () -> Void) { let callsite = Callsite(file: file, line: line) let example = Example(description: description, callsite: callsite, flags: flags, closure: closure) currentExampleGroup.appendExample(example) } } DVSSFOU&YBNQMF(SPVQʹ௥Ճ it = Example ͩʂ ಡΊΔɺಡΊΔͧʂ
  123. %4-શମΛݟ௚͢ 123 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  124. 124 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe
  125. 125 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe ΦϒδΣΫτͷߏ଄͕ ݟ͖͑ͯͨͧ
  126. 126 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe ExampleGroup: calc EFTDSJCF͸&YBNQMF(SPVQ
  127. 127 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe ExampleGroup: calc hooks.befores
  128. 128 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe ExampleGroup: calc hooks.befores ExampleGroup: add
  129. 129 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe ExampleGroup: calc hooks.befores ExampleGroup: add ExampleGroup: 1 + 1 DPOUFYU΋&YBNQMF(SPVQ
  130. 130 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe ExampleGroup: calc hooks.befores ExampleGroup: add ExampleGroup: 1 + 1 Example: works JU͸&YBNQMF
  131. 131 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe ExampleGroup: calc hooks.befores ExampleGroup: add ExampleGroup: 1 + 1 Example: works CallSite (file, line) expect(calc.add(1, 1)).to(equal(2)) ϑΝΠϧɾߦɺΞαʔγϣϯίʔυΛ࣋ͭ
  132. 132 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift beforeEach describe context it describe ExampleGroup: calc hooks.befores ExampleGroup: add ExampleGroup: 1 + 1 Example: works CallSite (file, line) expect(calc.add(1, 1)).to(equal(2)) ϑΝΠϧɾߦɺΞαʔγϣϯίʔυΛ࣋ͭ Quick ͷ DSL ׬શʹཧղͨ͠
  133. 9$5FTU͔Βͷݺͼग़͠ 133 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  134. 134 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift
  135. 135 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift %4-ͷΤϯτϦϙΠϯτҎ֎͸ఆ͍ٛͯ͠ͳ͍
  136. 136 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. class CalcSpec:

    QuickSpec { override func spec() { describe("calc") { var calc: Calc! beforeEach { calc = Calc() } describe("add") { context("1 + 1") { it("works") { expect(calc.add(1, 1)).to(equal(2)) } } } } } } CalcSpec.swift %4-ͷΤϯτϦϙΠϯτҎ֎͸ఆ͍ٛͯ͠ͳ͍ ΤϯτϦϙΠϯτʹ ൿີ͕͋Δʹҧ͍ͳ͍ ΋͏Ұ౓ݟͯΈΔ
  137. 137 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (void)initialize { [QuickConfiguration initialize]; World *world = [World sharedWorld]; [world performWithCurrentExampleGroup:[world rootExampleGroupForSpecClass:self] closure:^{ QuickSpec *spec = [self new]; @try { [spec spec]; } @catch (NSException *exception) { ... } [self testInvocations]; }]; } QuickSpec.m
  138. 138 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (void)initialize { [QuickConfiguration initialize]; World *world = [World sharedWorld]; [world performWithCurrentExampleGroup:[world rootExampleGroupForSpecClass:self] closure:^{ QuickSpec *spec = [self new]; @try { [spec spec]; } @catch (NSException *exception) { ... } [self testInvocations]; }]; } TQFD͕ݺ͹ΕͨޙͰ QuickSpec.m
  139. 139 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (void)initialize { [QuickConfiguration initialize]; World *world = [World sharedWorld]; [world performWithCurrentExampleGroup:[world rootExampleGroupForSpecClass:self] closure:^{ QuickSpec *spec = [self new]; @try { [spec spec]; } @catch (NSException *exception) { ... } [self testInvocations]; }]; } Կ͔ݺΜͰΔʂ QuickSpec.m
  140. 140 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (NSArray *)testInvocations { NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet<NSString*> *selectorNames = [NSMutableSet set]; for (Example *example in examples) { SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.selector = selector; [invocations addObject:invocation]; } return invocations; } QuickSpec.m
  141. 141 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (NSArray *)testInvocations { NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet<NSString*> *selectorNames = [NSMutableSet set]; for (Example *example in examples) { SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.selector = selector; [invocations addObject:invocation]; } return invocations; } JUʹରԠ͢Δ&YBNQMFΛநग़ͯ͠ QuickSpec.m
  142. 142 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (NSArray *)testInvocations { NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet<NSString*> *selectorNames = [NSMutableSet set]; for (Example *example in examples) { SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.selector = selector; [invocations addObject:invocation]; } return invocations; } &YBNQMFΛΠϯελϯεϝιουʹ௥Ճͯ͠ QuickSpec.m
  143. 143 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (NSArray *)testInvocations { NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet<NSString*> *selectorNames = [NSMutableSet set]; for (Example *example in examples) { SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.selector = selector; [invocations addObject:invocation]; } return invocations; } 4FMFDUPS͔Β/4*OWPDBUJPOΛੜ੒ͯ͠ QuickSpec.m
  144. 144 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (NSArray *)testInvocations { NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet<NSString*> *selectorNames = [NSMutableSet set]; for (Example *example in examples) { SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.selector = selector; [invocations addObject:invocation]; } return invocations; } ͦͷҰཡΛฦͯ͠Δʂ QuickSpec.m
  145. 145 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (NSArray *)testInvocations { NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet<NSString*> *selectorNames = [NSMutableSet set]; for (Example *example in examples) { SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.selector = selector; [invocations addObject:invocation]; } return invocations; } ͦͷҰཡΛฦͯ͠Δʂ QuickSpec.m Selector ͸෼͔Δ͚Ͳ NSInvocation ͬͯԿͩʁ TFMFDUPSͱ͔Ͱ
  146. 146 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. NSInvocation ϝοηʔδϯάΛදݱͨ͠ΦϒδΣΫτ

    0CKFDUJWF$3VOUJNFݶఆͷػೳ ଞݴޠͰݴ͑͹ʮϦϑϨΫγϣϯʯʹ͍ۙ 0CKFDUJWF$ʹ͓͚Δϝιουݺͼग़͠
  147. 147 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. NSInvocation ϝοηʔδϯάΛදݱͨ͠ΦϒδΣΫτ

    0CKFDUJWF$3VOUJNFݶఆͷػೳ ଞݴޠͰݴ͑͹ʮϦϑϨΫγϣϯʯʹ͍ۙ 0CKFDUJWF$ʹ͓͚Δϝιουݺͼग़͠ Dog walk(time: Time) NSInvocation XBML
  148. 148 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. NSInvocation ϝοηʔδϯάΛදݱͨ͠ΦϒδΣΫτ

    0CKFDUJWF$3VOUJNFݶఆͷػೳ ଞݴޠͰݴ͑͹ʮϦϑϨΫγϣϯʯʹ͍ۙ 0CKFDUJWF$ʹ͓͚Δϝιουݺͼग़͠ Dog walk(time: Time) NSInvocation XBML ίϯύΠϧ࣌ʹ֬ఆͯ͠ͳ͍ ϝιου΋ಈతʹݺͼग़ͤΔʂ 0CKFDUJWF$Ͱ͸
  149. 149 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (NSArray *)testInvocations { NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet<NSString*> *selectorNames = [NSMutableSet set]; for (Example *example in examples) { SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.selector = selector; [invocations addObject:invocation]; } return invocations; } QuickSpec.m
  150. 150 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (NSArray *)testInvocations { NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet<NSString*> *selectorNames = [NSMutableSet set]; for (Example *example in examples) { SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.selector = selector; [invocations addObject:invocation]; } return invocations; } it("works") { expect(calc.add(1, 1)).to(equal(2)) } Example: works NSInvocation JUʹର͢Δݺͼग़͠Λੜ੒ͯ͠ฦͯ͠Δʂ QuickSpec.m
  151. 151 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. @implementation QuickSpec

    + (NSArray *)testInvocations { NSArray *examples = [[World sharedWorld] examplesForSpecClass:[self class]]; NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[examples count]]; NSMutableSet<NSString*> *selectorNames = [NSMutableSet set]; for (Example *example in examples) { SEL selector = [self addInstanceMethodForExample:example classSelectorNames:selectorNames]; NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.selector = selector; [invocations addObject:invocation]; } return invocations; } it("works") { expect(calc.add(1, 1)).to(equal(2)) } Example: works NSInvocation JUʹର͢Δݺͼग़͠Λੜ੒ͯ͠ฦͯ͠Δʂ QuickSpec.m ͜Εͬͯ΋͔ͯ͠͠ ͋ͷҰཡʹରԠͯ͠Δʁ ͋Εʁ
  152. 152 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  153. 153 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ͋ͷҰཡ

  154. 154 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ͋ͷҰཡ ࢼ͠ʹσόοάͯ͠

    Selector ͷத਎Λ೷͍ͯΈΔ
  155. 155 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  156. 156 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  157. 157 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ׬શʹҰக

  158. 158 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. + (NSArray

    *)testInvocations Ͱ ςετର৅ͷҰཡΛฦͤΔ࢓૊Έ 9$5FTU͸
  159. ͜͜·ͰͷྲྀΕΛৼΓฦΔ 159 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  160. 160 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  161. 161 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ΫϥεϩʔυʹΑΓࣗ਎͕ੜ੒͞Εͯ

  162. 162 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. TQFD ͕ݺͼग़͞ΕΔ

  163. 163 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. 8PSMEͰίϯςΩετΛҡ࣋ͭͭ͠ %4-ΛΦϒδΣΫτߏ଄ʹ૊Έཱͯ

  164. 164 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. &YBNQMFSVO΁ͷ/4*OWPDBUJPOΛ 9$5FTU͔ΒͷίʔϧόοΫͰฦ͢

  165. 165 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ͦͷҰཡ͕9$5FTUʹΑΓ࣮ߦ͞Ε ςετ݁Ռ͕φϏήʔλʹදࣔ͞ΕΔ

  166. 166 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ͦͷҰཡ͕9$5FTUʹΑΓ࣮ߦ͞Ε ςετ݁Ռ͕φϏήʔλʹදࣔ͞ΕΔ

    Quick ׬શʹཧղͨ͠
  167. ·ͱΊ 167 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.

  168. 168 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ·ͱΊ 2VJDL͕Ͳ͏ಈ͔͘ݟ͖ͯͨ

    • ΤϯτϦϙΠϯτ • %4-͔ΒΦϒδΣΫτߏ଄ͷੜ੒ • 9$5FTUʹςετର৅ҰཡΛ౉͢ 0CKFDUJWF$ϥϯλΠϜͷ׆༻ • Ϋϥεϩʔυ࣌ͷJOJUJBMJ[F • /4*OWPDBUJPOʹΑΔಈతϝοηʔδϯά 8PSME͕ίϯςΩετΛҡ࣋
  169. 169 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ·ͱΊ 2VJDL͕Ͳ͏ಈ͔͘ݟ͖ͯͨ

    • ΤϯτϦϙΠϯτɿTQFD  • %4-͔ΒΦϒδΣΫτߏ଄ͷੜ੒ • 8PSMEΛ࢖ͬͨίϯςΩετҡ࣋ • 9$5FTUʹςετର৅ҰཡΛฦ͢ 0CKFDUJWF$ϥϯλΠϜͷ׆༻ • Ϋϥεϩʔυ࣌ͷJOJUJBMJ[F • /4*OWPDBUJPOʹΑΔಈతϝοηʔδϯά ͋ͳͨ΋ࠓ೔͔Β Quick ίϯτϦϏϡʔλ ࢲ΋
  170. ॓୊ 170 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ࢲ΋ͪΌΜͱ΍Γ·͢

  171. 171 Copyright (C) DeNA Co.,Ltd. All Rights Reserved. ॓୊ &YBNQMF࣮ߦ࣌ʹCFGPSF&BDI͕ॲཧ͞ΕΔ࢓૊Έ

    • BGUFS&BDI͸ʁ • CFGPSF4VJUF͸ʁ ςετ໊͸Ͳ͜Ͱઃఆ͞Ε͍ͯΔʁ /JNCMFͷΤϥʔ͕ਖ਼͍͠Ґஔʹදࣔ͞ΕΔ࢓૊Έ
  172. %JEZPVFOKPZ $PEFSFBEJOH 172 Copyright (C) DeNA Co.,Ltd. All Rights Reserved.