Skip to content
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

Allow using Examples after Outline #122

Merged
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
6 changes: 3 additions & 3 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PODS:
- SwiftLint (0.23.0)
- XCTest-Gherkin/Core (0.16.0)
- XCTest-Gherkin/Native (0.16.0):
- XCTest-Gherkin/Core (0.18.0)
- XCTest-Gherkin/Native (0.18.0):
- XCTest-Gherkin/Core

DEPENDENCIES:
Expand All @@ -18,7 +18,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
SwiftLint: 6ddf7d305644c2239cb768a11d97cce804816691
XCTest-Gherkin: c85a2efe41928da4cef5ddbcac55f5009d02dc30
XCTest-Gherkin: 36f4c87978447d1e8cd3ee36d242b9b5f7f524fd

PODFILE CHECKSUM: 040d56cac22fe93f01093a8f0021b445faf03233

Expand Down
4 changes: 2 additions & 2 deletions Example/Pods/Local Podspecs/XCTest-Gherkin.podspec.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Example/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

574 changes: 282 additions & 292 deletions Example/Pods/Pods.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions Example/Tests/Features/ExampleFeatures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,51 @@ final class ExampleFeatures: XCTestCase {
}
}

func testExamplesAfterOutline() {
// Examples can be passed after Outline via trailing closure

// swiftlint:disable multiple_closures_with_trailing_closure
Outline({
Given("I use the example name <name>")
Then("The age should be <age>")
}) {[
[ "name" , "age", "height" ],
[ "Alice", "20" , "170" ],
[ "Bob" , "20" , "170" ]
]}

Outline({
Given("I use the example name <name>")
Then("The age should be <age>")
}) {
[
["name": "Alice", "age": 20, "height": 170],
["name": "Bob", "age": 20, "height": 170 ]
]
}
// swiftlint:enable multiple_closures_with_trailing_closure

// or via explicit Examples parameter
Outline({
Given("I use the example name <name>")
Then("The age should be <age>")
}, examples: [
[ "name" , "age", "height" ],
[ "Alice", "20" , "170" ],
[ "Bob" , "20" , "170" ]
])

Outline({
Given("I use the example name <name>")
Then("The age should be <age>")
}, examples:
[
["name": "Alice", "age": 20, "height": 170],
["name": "Bob", "age": 20, "height": 170 ]
]
)
}

let examples: [[ExampleStringRepresentable]] = [
[ "name", "age", "height" ],
[ "Alice", 20, 170 ],
Expand Down
2 changes: 1 addition & 1 deletion Example/XCTest-Gherkin.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "pushd \"${SRCROOT}/..\"\n ./scripts/lint\n exit $?\npopd";
shellScript = "pushd \"${SRCROOT}/..\"\n ./scripts/lint\n exit $?\npopd\n";
};
4A3C67E5CC96F27175DCF5DB /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
Expand Down
24 changes: 23 additions & 1 deletion Pod/Core/Example.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public extension XCTestCase {

- parameter routine: A block containing your Given/When/Then which will be run once per example
*/
func Outline( _ routine: ()->() ) {
func Outline(_ routine: ()->()) {
precondition(state.examples != nil, "You need to define examples before running an Outline block - use Examples(...)");
precondition(state.examples!.count > 0, "You've called Examples but haven't passed anything in. Nice try.")

Expand All @@ -113,6 +113,28 @@ public extension XCTestCase {
}
}

func Outline(_ routine: ()->(), examples titles: [String], _ allValues: [String]...) {
Outline(routine, examples: [titles] + allValues)
}

func Outline(_ routine: ()->(), _ allValues: () -> [[String]]) {
Outline(routine, examples: allValues())
}

func Outline(_ routine: ()->(), examples allValues: [[String]]) {
Examples(allValues)
Outline(routine)
}

func Outline(_ routine: ()->(), _ allValues: () -> [[String: ExampleStringRepresentable]]) {
Outline(routine, examples: allValues())
}

func Outline(_ routine: ()->(), examples allValues: [[String: ExampleStringRepresentable]]) {
Examples(allValues)
Outline(routine)
}

func exampleValue<T: ExampleStringRepresentable>(_ title: String) -> T? {
let value = state.currentExample?[title]
if let value = value as? T {
Expand Down
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,35 @@ func testOutlineTests() {

This will run the tests twice, once with the values `Alice,20` and once with the values `Bob,20`.

NB The examples have to be defined _before_ the `Outline {..}` whereas in Gherkin you specify them afterwards. Sorry about that.
The easiest way to use `Examples` and `Outline` functions is to call `Examples` before `Outline`. But in Gherkin feature files Examples always go after Scenario Outline. If you want to keep this order in native tests (and don't care about little bit funky Xcode indentation) you can provide examples after defining Outline via trailing closure or explicit `Examples` parameter:

```swift
func testOutlineTests() {
Outline({
Given("I use the example name <name>")
Then("The age should be <age>")
}) {
[
[ "name" , "age", "height" ],
[ "Alice", "20" , "170" ],
[ "Bob" , "20" , "170" ]
]
}

// or

Outline({
Given("I use the example name <name>")
Then("The age should be <age>")
}, examples:
[
[ "name" , "age", "height" ],
[ "Alice", "20" , "170" ],
[ "Bob" , "20" , "170" ]
]
)
}
```

### Background
If you are repeating the same steps in each scenario you can move them to a `Background`. A `Background` is run before each scenario (effectively just before first scenario step is execuated) or outline pass (but **after** `setUp()`). You can have as many steps in `Background` as you want.
Expand Down