Skip to content

Commit

Permalink
improved docs about native data tables
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyapuchka committed Jun 15, 2019
1 parent 9d01bfa commit d25768c
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 36 deletions.
8 changes: 4 additions & 4 deletions Example/Tests/StepDefinitions/SanitySteps.swift
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,10 @@ final class SanitySteps: StepDefiner {
XCTAssertEqual(
match.values,
[
"KMSY": [ "lat": "29.993333", "lon": "-90.258056" ],
"KSFO": [ "lat": "37.618889", "lon": "-122.375000" ],
"KSEA": [ "lat": "47.448889", "lon": "-122.309444" ],
"KJFK": [ "lat": "40.639722", "lon": "-73.778889" ]
"KMSY": [ "lat": 29.993333, "lon": -90.258056 ],
"KSFO": [ "lat": 37.618889, "lon": -122.375000 ],
"KSEA": [ "lat": 47.448889, "lon": -122.309444 ],
"KJFK": [ "lat": 40.639722, "lon": -73.778889 ]
]
)
}
Expand Down
14 changes: 14 additions & 0 deletions Pod/Core/DataTable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@

import Foundation

/**
Use DataTable as the type of the step parameter to be able to pass collection of values to the step.

Example:
```
Given("I use the following names:") {
["Alice", "Bob"]
}

step("I use the following names: (.+)") { (match: DataTable<[String]>) in
...
}
```
*/
public struct DataTable<T: Collection>: CodableMatchedStringRepresentable where T: Codable {
public let values: T

Expand Down
108 changes: 78 additions & 30 deletions Pod/Native/NativeDataTable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,19 @@ extension StepDefiner {
extension StepDefiner {

/**
Input:
Define the step that accepts a data table as a single parameter.

Input from the feature file:
```
| 1 |
| 2 |
| 3 |

Result:
```

Values passed to the step:
```
[1, 2, 3]
```
*/
open func step<T: MatchedStringRepresentable>(_ expression: String, file: String = #file, line: Int = #line, f1: @escaping (NativeDataTable<[T]>)->()) {
self.step(expression, file: file, line: line, f1: f1) { (values: [[String]]) throws -> [T] in
Expand All @@ -84,13 +90,19 @@ extension StepDefiner {
}

/**
Input:
Define the step that accepts a data table as a single parameter.

Input from the feature file:
```
| 1 | 4 |
| 2 | 5 |
| 3 | 6 |
```

Result:
Values passed to the step:
```
[[1, 4], [2, 5], [3, 6]]
```
*/
open func step<T: MatchedStringRepresentable>(_ expression: String, file: String = #file, line: Int = #line, f1: @escaping (NativeDataTable<[[T]]>)->()) {
self.step(expression, file: file, line: line, f1: f1) { (values: [[String]]) throws -> [[T]] in
Expand All @@ -106,18 +118,24 @@ extension StepDefiner {
}

/**
Input:
Define the step that accepts a data table as a single parameter.

Input from the feature file:
```
| firstName | lastName | birthDate |
| Annie M. G. | Schmidt | 1911-03-20 |
| Roald | Dahl | 1916-09-13 |
| Astrid | Lindgren | 1907-11-14 |
```

Result:
Values passed to the step:
```
[
[ "firstName": "Annie M.G", "lastName": "Schmidt", "birthDate": "1911-03-20" ],
[ "firstName": "Roald", "lastName": "Dahl", "birthDate": "1916-09-13" ],
[ "firstName": "Astrid", "lastName": "Lindgren", "birthDate": "1907-11-14" ]
]
```
*/
open func step<T: MatchedStringRepresentable>(_ expression: String, file: String = #file, line: Int = #line, f1: @escaping (NativeDataTable<[[String: T]]>)->()) {
self.step(expression, file: file, line: line, f1: f1) { (values: [[String]]) throws -> [[String: T]] in
Expand All @@ -137,19 +155,25 @@ extension StepDefiner {
}

/**
Input:
Define the step that accepts a data table as a single parameter.

Input from the feature file:
```
| KMSY | Louis Armstrong New Orleans International Airport |
| KSFO | San Francisco International Airport |
| KSEA | Seattle–Tacoma International Airport |
| KJFK | John F. Kennedy International Airport |
```

Result:
Values passed to the step:
```
[
"KMSY": "Louis Armstrong New Orleans International Airport",
"KSFO": "San Francisco International Airport",
"KSEA": "Seattle–Tacoma International Airport",
"KJFK": "John F. Kennedy International Airport"
]
```
*/
open func step<T: MatchedStringRepresentable>(_ expression: String, file: String = #file, line: Int = #line, f1: @escaping (NativeDataTable<[String: T]>)->()) {
self.step(expression, file: file, line: line, f1: f1) { (values: [[String]]) throws -> [String: T] in
Expand All @@ -167,19 +191,25 @@ extension StepDefiner {
}

/**
Input:
Define the step that accepts a data table as a single parameter.

Input from the feature file:
```
| KMSY | 29.993333 | -90.258056 |
| KSFO | 37.618889 | -122.375000 |
| KSEA | 47.448889 | -122.309444 |
| KJFK | 40.639722 | -73.778889 |
```

Result:
Values passed to the step:
```
[
"KMSY": ["29.993333", "-90.258056"],
"KSFO": ["37.618889", "-122.375000"],
"KSEA": ["47.448889", "-122.309444"],
"KJFK": ["40.639722", "-73.778889"]
"KMSY": [29.993333, -90.258056],
"KSFO": [37.618889, -122.375000],
"KSEA": [47.448889, -122.309444],
"KJFK": [40.639722, -73.778889]
]
```
*/
open func step<T: MatchedStringRepresentable>(_ expression: String, file: String = #file, line: Int = #line, f1: @escaping (NativeDataTable<[String: [T]]>)->()) {
self.step(expression, file: file, line: line, f1: f1) { (values: [[String]]) throws -> [String: [T]] in
Expand All @@ -195,20 +225,26 @@ extension StepDefiner {
}

/**
Input:
Define the step that accepts a data table as a single parameter.

Input from the feature file:
```
| | lat | lon |
| KMSY | 29.993333 | -90.258056 |
| KSFO | 37.618889 | -122.375000 |
| KSEA | 47.448889 | -122.309444 |
| KJFK | 40.639722 | -73.778889 |
```

Result:
Values passed to the step:
```
[
"KMSY": [ "lat": "29.993333", "lon": "-90.258056" ],
"KSFO": [ "lat": "37.618889", "lon": "-122.375000" ],
"KSEA": [ "lat": "47.448889", "lon": "-122.309444" ],
"KJFK": [ "lat": "40.639722", "lon": "-73.778889" ]
"KMSY": [ "lat": 29.993333, "lon": -90.258056 ],
"KSFO": [ "lat": 37.618889, "lon": -122.375000 ],
"KSEA": [ "lat": 47.448889, "lon": -122.309444 ],
"KJFK": [ "lat": 40.639722, "lon": -73.778889 ]
]
```
*/
open func step<T: MatchedStringRepresentable>(_ expression: String, file: String = #file, line: Int = #line, f1: @escaping (NativeDataTable<[String: [String: T]]>)->()) {
self.step(expression, file: file, line: line, f1: f1) { (values: [[String]]) throws -> [String: [String: T]] in
Expand All @@ -227,18 +263,25 @@ extension StepDefiner {
}

// TODO: implement custom decoder that will decode string cell values to expected types instead of failing
// This currently only works if all properties are strings
/**
Input:
Step that parses data table

Define the step that accepts a data table as a single parameter.

Input from the feature file:
```
| name | age | height |
| Alice | 20 | 170 |
| Bob | 21 | 171 |

Output:
```

Values passed to the step:
```
[
Person(name: "Alice", age: 20, height: 170),
Person(name: "Bob", age: 21, height: 171)
Person(name: "Alice", age: "20", height: 170),
Person(name: "Bob", age: "21", height: 171)
]
```
*/
open func step<T: CodableMatchedStringRepresentable>(_ expression: String, file: String = #file, line: Int = #line, f1: @escaping (NativeDataTable<[T]>)->()) {
self.step(expression, file: file, line: line, f1: f1) { (values: [[String]]) throws -> [T] in
Expand All @@ -257,18 +300,23 @@ extension StepDefiner {
}

// TODO: implement custom decoder that will decode string cell values to expected types instead of failing
// This currently only works if all properties are strings
/**
Input:
Define the step that accepts a data table as a single parameter.

Input from the feature file:
```
| | name | age | height |
| 1 | Alice | 20 | 170 |
| 2 | Bob | 21 | 171 |
```

Output:
Values passed to the step:
```
[
1: Person(name: "Alice", age: 20, height: 170),
2: Person(name: "Bob", age: 21, height: 171)
]
```
*/
open func step<T: CodableMatchedStringRepresentable, U: MatchedStringRepresentable>(_ expression: String, file: String = #file, line: Int = #line, f1: @escaping (NativeDataTable<[U: T]>)->()) {
self.step(expression, file: file, line: line, f1: f1) { (values: [[String]]) throws -> [U: T] in
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,6 @@ step("I register as the following users: (.+)") { (match: DataTable<[String: Per
}
```

In the step

### 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 Expand Up @@ -350,6 +348,7 @@ There is an example of this in the Example/ project as part of this pod. Look at

The advantages of this are obvious; you get to quickly run your existing feature files and can get up and running quickly. The disadvanages are beacuse the tests are generated at runtime they can't be run individually from inside Xcode so debugging is tricker. I would use this to start testing inside Xcode but if it gets hairy, convert that feature file into a native Swift test and debug from there.

Note: when working with native feature files with data tables steps should use `NativeDataTable` type instead of `DataTable`. See [native_data_table.feature](Example/Tests/Features/NativeFeatures/native_data_table.feature) for examples of data table formats that you can use in the feature files.

### Localisation of feature files

Expand Down

0 comments on commit d25768c

Please sign in to comment.