From d25768cef0361f4ec61ab51e7fa099a52d61b8bc Mon Sep 17 00:00:00 2001 From: Ilya Puchka Date: Sat, 15 Jun 2019 23:11:12 +0100 Subject: [PATCH] improved docs about native data tables --- .../Tests/StepDefinitions/SanitySteps.swift | 8 +- Pod/Core/DataTable.swift | 14 +++ Pod/Native/NativeDataTable.swift | 108 +++++++++++++----- README.md | 3 +- 4 files changed, 97 insertions(+), 36 deletions(-) diff --git a/Example/Tests/StepDefinitions/SanitySteps.swift b/Example/Tests/StepDefinitions/SanitySteps.swift index 2151bc6..e865a75 100644 --- a/Example/Tests/StepDefinitions/SanitySteps.swift +++ b/Example/Tests/StepDefinitions/SanitySteps.swift @@ -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 ] ] ) } diff --git a/Pod/Core/DataTable.swift b/Pod/Core/DataTable.swift index cbe7e03..191769e 100644 --- a/Pod/Core/DataTable.swift +++ b/Pod/Core/DataTable.swift @@ -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: CodableMatchedStringRepresentable where T: Codable { public let values: T diff --git a/Pod/Native/NativeDataTable.swift b/Pod/Native/NativeDataTable.swift index 7f93418..3f3ab94 100644 --- a/Pod/Native/NativeDataTable.swift +++ b/Pod/Native/NativeDataTable.swift @@ -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(_ 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 @@ -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(_ 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 @@ -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(_ 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 @@ -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(_ 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 @@ -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(_ 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 @@ -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(_ 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 @@ -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(_ 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 @@ -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(_ 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 diff --git a/README.md b/README.md index f626c37..b9a759c 100644 --- a/README.md +++ b/README.md @@ -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. @@ -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