Skip to content

Rename to Contract from Protocol #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 31 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ Concrete implementation is below:

```swift
class FooViewController: UIViewController {
private var model: FooModelContract
private var viewBinding: FooViewBindingContract?
private var controller: FooControllerContract?
private var model: FooModelProtocol
private var viewBinding: FooViewBindingProtocol?
private var controller: FooControllerProtocol?

init(model: FooModelContract) {
init(model: FooModelProtocol) {
self.model = model
super.init(nibName: nil, bundle: nil)
}
Expand Down Expand Up @@ -80,8 +80,8 @@ class FooViewController: UIViewController {
// FooModel is a state-machine that can transit to FooModelState.
// Notify change events to others via an observable `didChange` when
// API was successfully done or failed.
class FooModel: FooModelContract {
private let repository: FooRepositoryContract
class FooModel: FooModelProtocol {
private let repository: FooRepositoryProtocol
private let stateVariable: RxSwift.Variable<FooModelState>

/// An Observable that will notify events when the internal state is changed.
Expand All @@ -97,7 +97,7 @@ class FooModel: FooModelContract {

init(
startingWith initialState: FooModelState,
fetchingVia repository: FooRepositoryContract
fetchingVia repository: FooRepositoryProtocol
) {
self.stateVariable = RxSwift.Variable<FooModelState>(initialState)
self.repository = repository
Expand Down Expand Up @@ -140,13 +140,13 @@ enum FooModelState {
```

```swift
class FooViewBinding: FooViewBindingContract {
class FooViewBinding: FooViewBindingProtocol {
typealias Views = (bar: BarView, baz: BuzzView)
private let views: Views
private let model: FooModelContract
private let model: FooModelProtocol
private let disposeBag = RxSwift.DisposeBag()

init(observing model: FooModelContract, handling views: Views) {
init(observing model: FooModelProtocol, handling views: Views) {
self.model = model
self.views = views

Expand All @@ -170,14 +170,14 @@ class FooViewBinding: FooViewBindingContract {
```

```swift
class FooController: FooControllerContract {
private let model: FooModelContract
class FooController: FooControllerProtocol {
private let model: FooModelProtocol
private let view: BarView
private let disposeBag = RxSwift.DisposeBag()

init(
observing view: BarView,
willNotifyTo model: FooModelContract
willNotifyTo model: FooModelProtocol
) {
self.model = model

Expand All @@ -203,12 +203,12 @@ In this project, use Navigator class for connecting betweren 2 `UIViewController

```swift
class FooViewController: UIViewController {
private let navigator: NavigatorContract
private let sharedModel: FooBarModelContract
private let navigator: NavigatorProtocol
private let sharedModel: FooBarModelProtocol

init(
representing sharedModel: FooBarModelContract,
navigatingBy navigator: NavigatorContract
representing sharedModel: FooBarModelProtocol,
navigatingBy navigator: NavigatorProtocol
) {
self.sharedModel = sharedModel
self.navigator = navigator
Expand Down Expand Up @@ -243,7 +243,7 @@ And also you can use `UIStoryboardSegue`, but using the `Navigator` class have t
/**
A protocol for wrapper class of `UINavigationController#pushViewController(_:UIViewController, animated:Bool)`.
*/
protocol NavigatorContract {
protocol NavigatorProtocol {
/**
Push the specified UIViewController to the held UINavigationController.
*/
Expand All @@ -252,7 +252,7 @@ protocol NavigatorContract {



class Navigator: NavigatorContract {
class Navigator: NavigatorProtocol {
private let navigationController: UINavigationController


Expand Down Expand Up @@ -320,13 +320,13 @@ XCTAssertEqual(UserDefaults.standard.integer(forKey: "foo"), 10)
```swift
// GOOD DESIGN
class UserDefaultsCalculator {
private let readableRepository: ReadableRepositoryContract
private let writableRepository: WritableRepositoryContract
private let readableRepository: ReadableRepositoryProtocol
private let writableRepository: WritableRepositoryProtocol


init(
reading readableRepository: ReadableRepositoryContract,
writing writableRepository: WritableRepositoryContract
reading readableRepository: ReadableRepositoryProtocol,
writing writableRepository: WritableRepositoryProtocol
) {
self.readableRepository = readableRepository
self.writableRepository = writableRepository
Expand All @@ -344,12 +344,12 @@ class UserDefaultsCalculator {
}


protocol ReadableRepositoryContract {
protocol ReadableRepositoryProtocol {
func read() -> Int
}


class ReadableRepository: ReadableRepositoryContract {
class ReadableRepository: ReadableRepositoryProtocol {
private let userDefaults: UserDefaults


Expand All @@ -364,12 +364,12 @@ class ReadableRepository: ReadableRepositoryContract {
}


protocol WritableRepositoryContract {
protocol WritableRepositoryProtocol {
func write(_ value: Int)
}


class WritableRepository: WritableRepositoryContract {
class WritableRepository: WritableRepositoryProtocol {
private let userDefaults: UserDefaults


Expand Down Expand Up @@ -417,7 +417,7 @@ XCTAssertEqual(spy.callArgs.last!, 10)
```swift
// TestDoubles definitions

class ReadableRepositoryStub: ReadableRepositoryContract {
class ReadableRepositoryStub: ReadableRepositoryProtocol {
var nextValue: Int

init(firstValue: Int) {
Expand All @@ -430,7 +430,7 @@ class ReadableRepositoryStub: ReadableRepositoryContract {
}


class WritableRepositorySpy: WritableRepositoryContract {
class WritableRepositorySpy: WritableRepositoryProtocol {
private(set) var callArgs = [Int]()

func write(_ value: Int) {
Expand Down Expand Up @@ -502,11 +502,11 @@ class MyCell: UITableViewCell {

Taken together, we should follow the Test Pyramid:

![Ideal test volume is extlemly few UI tests and few integration tests and much unit tests and much type checkings.](https://raw.githubusercontent.com/Kuniwak/TestableDesignExample/master/Documentation/Images/TestingPyramid_en.png)
![Ideal test volume is extremely few UI tests and few integration tests and much unit tests and much type checkings.](https://raw.githubusercontent.com/Kuniwak/TestableDesignExample/master/Documentation/Images/TestingPyramid_en.png)



References
----------

1. XUnit Test Patterns: http://xunitpatterns.com/index.html
1. xUnit Test Patterns: http://xunitpatterns.com/index.html
58 changes: 29 additions & 29 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ iOS のためのテスト容易設計サンプル

```swift
class FooViewController: UIViewController {
private var model: FooModelContract
private var viewBinding: FooViewBindingContract?
private var controller: FooControllerContract?
private var model: FooModelProtocol
private var viewBinding: FooViewBindingProtocol?
private var controller: FooControllerProtocol?

init(model: FooModelContract) {
init(model: FooModelProtocol) {
self.model = model
super.init(nibName: nil, bundle: nil)
}
Expand Down Expand Up @@ -81,8 +81,8 @@ class FooViewController: UIViewController {
// FooModel は、FooModelState を状態としたステートマシンです。
// API 呼び出しの成功や失敗によって状態遷移が起きると、
// `didChange` という Observable を通して外部へ通知します。
class FooModel: FooModelContract {
private let repository: FooRepositoryContract
class FooModel: FooModelProtocol {
private let repository: FooRepositoryProtocol
private let stateVariable: RxSwift.Variable<FooModelState>

/// FooModel の内部状態に変化があったら通知される Observable。
Expand All @@ -98,7 +98,7 @@ class FooModel: FooModelContract {

init(
startingWith initialState: FooModelState,
fetchingVia repository: FooRepositoryContract
fetchingVia repository: FooRepositoryProtocol
) {
self.stateVariable = RxSwift.Variable<FooModelState>(initialState)
self.repository = repository
Expand Down Expand Up @@ -144,13 +144,13 @@ enum FooModelState {
// FooModel の状態変化に応じて表示を切り替えるクラス。
// Binding とは、仲介者を意味していて、複数の UIView を
// 操作する責務をもっています。
class FooViewBinding: FooViewBindingContract {
class FooViewBinding: FooViewBindingProtocol {
typealias Views = (bar: BarView, baz: BuzzView)
private let views: Views
private let model: FooModelContract
private let model: FooModelProtocol
private let disposeBag = RxSwift.DisposeBag()

init(observing model: FooModelContract, handling views: Views) {
init(observing model: FooModelProtocol, handling views: Views) {
self.model = model
self.views = views

Expand All @@ -175,14 +175,14 @@ class FooViewBinding: FooViewBindingContract {

```swift
// BarView からの UI イベントを、FooModel への入力へと変換します。
class FooController: FooControllerContract {
private let model: FooModelContract
class FooController: FooControllerProtocol {
private let model: FooModelProtocol
private let view: BarView
private let disposeBag = RxSwift.DisposeBag()

init(
observing view: BarView,
willNotifyTo model: FooModelContract
willNotifyTo model: FooModelProtocol
) {
self.model = model

Expand All @@ -207,12 +207,12 @@ UIViewController 間の接続方法

```swift
class FooViewController: UIViewController {
private let navigator: NavigatorContract
private let sharedModel: FooBarModelContract
private let navigator: NavigatorProtocol
private let sharedModel: FooBarModelProtocol

init(
representing sharedModel: FooBarModelContract,
navigatingBy navigator: NavigatorContract
representing sharedModel: FooBarModelProtocol,
navigatingBy navigator: NavigatorProtocol
) {
self.sharedModel = sharedModel
self.navigator = navigator
Expand Down Expand Up @@ -245,7 +245,7 @@ class FooViewController: UIViewController {
/**
`UINavigationController#pushViewController(_:UIViewController, animated:Bool)` のラッパークラス。
*/
protocol NavigatorContract {
protocol NavigatorProtocol {
/**
UIViewController を保持している UINavigationController へ push する。
*/
Expand All @@ -254,7 +254,7 @@ protocol NavigatorContract {



class Navigator: NavigatorContract {
class Navigator: NavigatorProtocol {
private let navigationController: UINavigationController


Expand Down Expand Up @@ -323,13 +323,13 @@ XCTAssertEqual(UserDefaults.standard.integer(forKey: "foo"), 10)
```swift
// よい設計
class UserDefaultsCalculator {
private let readableRepository: ReadableRepositoryContract
private let writableRepository: WritableRepositoryContract
private let readableRepository: ReadableRepositoryProtocol
private let writableRepository: WritableRepositoryProtocol


init(
reading readableRepository: ReadableRepositoryContract,
writing writableRepository: WritableRepositoryContract
reading readableRepository: ReadableRepositoryProtocol,
writing writableRepository: WritableRepositoryProtocol
) {
self.readableRepository = readableRepository
self.writableRepository = writableRepository
Expand All @@ -347,12 +347,12 @@ class UserDefaultsCalculator {
}


protocol ReadableRepositoryContract {
protocol ReadableRepositoryProtocol {
func read() -> Int
}


class ReadableRepository: ReadableRepositoryContract {
class ReadableRepository: ReadableRepositoryProtocol {
private let userDefaults: UserDefaults


Expand All @@ -367,12 +367,12 @@ class ReadableRepository: ReadableRepositoryContract {
}


protocol WritableRepositoryContract {
protocol WritableRepositoryProtocol {
func write(_ value: Int)
}


class WritableRepository: WritableRepositoryContract {
class WritableRepository: WritableRepositoryProtocol {
private let userDefaults: UserDefaults


Expand Down Expand Up @@ -419,7 +419,7 @@ XCTAssertEqual(spy.callArgs.last!, 10)
```swift
// 代替物の定義

class ReadableRepositoryStub: ReadableRepositoryContract {
class ReadableRepositoryStub: ReadableRepositoryProtocol {
var nextValue: Int

init(firstValue: Int) {
Expand All @@ -432,7 +432,7 @@ class ReadableRepositoryStub: ReadableRepositoryContract {
}


class WritableRepositorySpy: WritableRepositoryContract {
class WritableRepositorySpy: WritableRepositoryProtocol {
private(set) var callArgs = [Int]()

func write(_ value: Int) {
Expand Down