cucumber-compatibility-kit 11.3.0 → 13.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/features/attachments/attachments.feature +3 -0
- data/features/attachments/attachments.feature.ndjson +77 -67
- data/features/attachments/attachments.feature.rb +9 -3
- data/features/attachments/cucumber.jpeg +0 -0
- data/features/attachments/document.pdf +0 -0
- data/features/cdata/cdata.feature.ndjson +1 -1
- data/features/data-tables/data-tables.feature.ndjson +1 -1
- data/features/data-tables/data-tables.feature.rb +2 -0
- data/features/examples-tables/examples-tables.feature.ndjson +1 -1
- data/features/examples-tables/examples-tables.feature.rb +2 -0
- data/features/hooks/hooks.feature.ndjson +1 -1
- data/features/hooks/hooks.feature.rb +2 -0
- data/features/markdown/markdown.feature.md.ndjson +1 -1
- data/features/minimal/minimal.feature.ndjson +1 -1
- data/features/minimal/minimal.feature.rb +3 -1
- data/features/parameter-types/parameter-types.feature.ndjson +1 -1
- data/features/parameter-types/parameter-types.feature.rb +2 -1
- data/features/pending/pending.feature.ndjson +1 -1
- data/features/pending/pending.feature.rb +3 -1
- data/features/retry/retry.feature.ndjson +1 -1
- data/features/retry/retry.feature.rb +2 -0
- data/features/rules/rules.feature.ndjson +1 -1
- data/features/rules/rules.feature.rb +2 -0
- data/features/skipped/skipped.feature.ndjson +1 -1
- data/features/skipped/skipped.feature.rb +3 -1
- data/features/stack-traces/stack-traces.feature.ndjson +1 -1
- data/features/stack-traces/stack-traces.feature.rb +2 -0
- data/features/undefined/undefined.feature.ndjson +1 -1
- data/features/undefined/undefined.feature.rb +3 -1
- data/features/unknown-parameter-type/unknown-parameter-type.feature.ndjson +1 -1
- data/features/unknown-parameter-type/unknown-parameter-type.feature.rb +3 -1
- data/lib/cucumber-compatibility-kit.rb +2 -0
- data/lib/keys_checker.rb +51 -15
- data/lib/messages_comparator.rb +2 -0
- data/lib/shared_examples.rb +8 -3
- data/spec/capture_warnings.rb +6 -5
- data/spec/cucumber-compatibility-kit_spec.rb +9 -7
- data/spec/keys_checker_spec.rb +13 -24
- data/spec/messages_comparator_spec.rb +22 -11
- metadata +64 -12
@@ -1,4 +1,4 @@
|
|
1
|
-
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.
|
1
|
+
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.3.0"},"os":{"name":"linux","version":"5.15.0-84-generic"},"protocolVersion":"22.0.0","runtime":{"name":"node.js","version":"18.18.0"}}}
|
2
2
|
{"source":{"data":"Feature: Pending steps\n\n During development, step definitions can signal at runtime that they are\n not yet implemented (or \"pending\") by returning or throwing a particular\n value.\n\n This causes subsequent steps in the scenario to be skipped, and the overall\n result to be treated as a failure.\n\n Scenario: Unimplemented step signals pending status\n Given a step that isnt implemented yet\n\n Scenario: Steps before unimplemented steps are executed\n Given an implemented step\n When a step that isnt implemented yet\n\n Scenario: Steps after unimplemented steps are skipped\n Given a step that isnt implemented yet\n Then a step that we expect to be skipped\n","mediaType":"text/x.cucumber.gherkin+plain","uri":"samples/pending/pending.feature"}}
|
3
3
|
{"gherkinDocument":{"comments":[],"feature":{"children":[{"scenario":{"description":"","examples":[],"id":"4","keyword":"Scenario","location":{"column":3,"line":10},"name":"Unimplemented step signals pending status","steps":[{"id":"3","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":11},"text":"a step that isnt implemented yet"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"7","keyword":"Scenario","location":{"column":3,"line":13},"name":"Steps before unimplemented steps are executed","steps":[{"id":"5","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":14},"text":"an implemented step"},{"id":"6","keyword":"When ","keywordType":"Action","location":{"column":5,"line":15},"text":"a step that isnt implemented yet"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"10","keyword":"Scenario","location":{"column":3,"line":17},"name":"Steps after unimplemented steps are skipped","steps":[{"id":"8","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":18},"text":"a step that isnt implemented yet"},{"id":"9","keyword":"Then ","keywordType":"Outcome","location":{"column":5,"line":19},"text":"a step that we expect to be skipped"}],"tags":[]}}],"description":" During development, step definitions can signal at runtime that they are\n not yet implemented (or \"pending\") by returning or throwing a particular\n value.\n\n This causes subsequent steps in the scenario to be skipped, and the overall\n result to be treated as a failure.","keyword":"Feature","language":"en","location":{"column":1,"line":1},"name":"Pending steps","tags":[]},"uri":"samples/pending/pending.feature"}}
|
4
4
|
{"pickle":{"astNodeIds":["4"],"id":"12","language":"en","name":"Unimplemented step signals pending status","steps":[{"astNodeIds":["3"],"id":"11","text":"a step that isnt implemented yet","type":"Context"}],"tags":[],"uri":"samples/pending/pending.feature"}}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.
|
1
|
+
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.3.0"},"os":{"name":"linux","version":"5.15.0-84-generic"},"protocolVersion":"22.0.0","runtime":{"name":"node.js","version":"18.18.0"}}}
|
2
2
|
{"source":{"data":"Feature: Retry\n\n Some Cucumber implementations support a Retry mechanism, where test cases that fail\n can be retried up to a limited number of attempts in the same test run.\n\n Non-passing statuses other than FAILED don't trigger a retry - they are not going to pass\n however many times we attempt them.\n\n Scenario: test case passes on the first attempt\n Given a step that always passes\n\n Scenario: test case passes on the second attempt\n Given a step that passes the second time\n\n Scenario: test case passes on the final attempt\n Given a step that passes the third time\n\n Scenario: test case fails on every attempt\n Given a step that always fails\n\n Scenario: don't retry on UNDEFINED\n Given a non-existent step\n","mediaType":"text/x.cucumber.gherkin+plain","uri":"samples/retry/retry.feature"}}
|
3
3
|
{"gherkinDocument":{"comments":[],"feature":{"children":[{"scenario":{"description":"","examples":[],"id":"5","keyword":"Scenario","location":{"column":3,"line":9},"name":"test case passes on the first attempt","steps":[{"id":"4","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":10},"text":"a step that always passes"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"7","keyword":"Scenario","location":{"column":3,"line":12},"name":"test case passes on the second attempt","steps":[{"id":"6","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":13},"text":"a step that passes the second time"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"9","keyword":"Scenario","location":{"column":3,"line":15},"name":"test case passes on the final attempt","steps":[{"id":"8","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":16},"text":"a step that passes the third time"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"11","keyword":"Scenario","location":{"column":3,"line":18},"name":"test case fails on every attempt","steps":[{"id":"10","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":19},"text":"a step that always fails"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"13","keyword":"Scenario","location":{"column":3,"line":21},"name":"don't retry on UNDEFINED","steps":[{"id":"12","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":22},"text":"a non-existent step"}],"tags":[]}}],"description":" Some Cucumber implementations support a Retry mechanism, where test cases that fail\n can be retried up to a limited number of attempts in the same test run.\n\n Non-passing statuses other than FAILED don't trigger a retry - they are not going to pass\n however many times we attempt them.","keyword":"Feature","language":"en","location":{"column":1,"line":1},"name":"Retry","tags":[]},"uri":"samples/retry/retry.feature"}}
|
4
4
|
{"pickle":{"astNodeIds":["5"],"id":"15","language":"en","name":"test case passes on the first attempt","steps":[{"astNodeIds":["4"],"id":"14","text":"a step that always passes","type":"Context"}],"tags":[],"uri":"samples/retry/retry.feature"}}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.
|
1
|
+
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.3.0"},"os":{"name":"linux","version":"5.15.0-84-generic"},"protocolVersion":"22.0.0","runtime":{"name":"node.js","version":"18.18.0"}}}
|
2
2
|
{"source":{"data":"Feature: Rules\n You can place scenarios inside rules. This makes is possible to structure\n Gherkin documents in the same way as [example maps](https://cucumber.io/blog/bdd/example-mapping-introduction/).\n You can also use the Examples synonym for Scenario to make them even more similar.\n\n Rule: a sale cannot happen if change cannot be returned\n # sad path\n Example: no change\n Given there are 5 0.20 coins inside\n When the customer tries to buy a 0.85 chocolate with a 1 coin\n Then the sale should not happen\n\n # happy path\n Example: exact change\n Given there are 5 0.20 coins inside\n And there are 3 chocolates inside\n When the customer tries to buy a 0.80 chocolate with a 1 coin\n Then the customer's change should be 1 0.20 coin\n\n @some-tag\n Rule: a sale cannot happen if we're out of stock\n # sad path\n Example: no chocolates left\n Given there are no chocolates inside\n But there are 10 0.5 coins inside\n When the customer tries to buy a 0.85 chocolate with a 1 coin\n Then the sale should not happen\n","mediaType":"text/x.cucumber.gherkin+plain","uri":"samples/rules/rules.feature"}}
|
3
3
|
{"gherkinDocument":{"comments":[{"location":{"column":1,"line":7},"text":" # sad path"},{"location":{"column":1,"line":13},"text":" # happy path"},{"location":{"column":1,"line":22},"text":" # sad path"}],"feature":{"children":[{"rule":{"children":[{"scenario":{"description":"","examples":[],"id":"9","keyword":"Example","location":{"column":5,"line":8},"name":"no change","steps":[{"id":"6","keyword":"Given ","keywordType":"Context","location":{"column":7,"line":9},"text":"there are 5 0.20 coins inside"},{"id":"7","keyword":"When ","keywordType":"Action","location":{"column":7,"line":10},"text":"the customer tries to buy a 0.85 chocolate with a 1 coin"},{"id":"8","keyword":"Then ","keywordType":"Outcome","location":{"column":7,"line":11},"text":"the sale should not happen"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"14","keyword":"Example","location":{"column":5,"line":14},"name":"exact change","steps":[{"id":"10","keyword":"Given ","keywordType":"Context","location":{"column":7,"line":15},"text":"there are 5 0.20 coins inside"},{"id":"11","keyword":"And ","keywordType":"Conjunction","location":{"column":7,"line":16},"text":"there are 3 chocolates inside"},{"id":"12","keyword":"When ","keywordType":"Action","location":{"column":7,"line":17},"text":"the customer tries to buy a 0.80 chocolate with a 1 coin"},{"id":"13","keyword":"Then ","keywordType":"Outcome","location":{"column":7,"line":18},"text":"the customer's change should be 1 0.20 coin"}],"tags":[]}}],"description":"","id":"15","keyword":"Rule","location":{"column":3,"line":6},"name":"a sale cannot happen if change cannot be returned","tags":[]}},{"rule":{"children":[{"scenario":{"description":"","examples":[],"id":"20","keyword":"Example","location":{"column":5,"line":23},"name":"no chocolates left","steps":[{"id":"16","keyword":"Given ","keywordType":"Context","location":{"column":7,"line":24},"text":"there are no chocolates inside"},{"id":"17","keyword":"But ","keywordType":"Conjunction","location":{"column":7,"line":25},"text":"there are 10 0.5 coins inside"},{"id":"18","keyword":"When ","keywordType":"Action","location":{"column":7,"line":26},"text":"the customer tries to buy a 0.85 chocolate with a 1 coin"},{"id":"19","keyword":"Then ","keywordType":"Outcome","location":{"column":7,"line":27},"text":"the sale should not happen"}],"tags":[]}}],"description":"","id":"22","keyword":"Rule","location":{"column":3,"line":21},"name":"a sale cannot happen if we're out of stock","tags":[{"id":"21","location":{"column":3,"line":20},"name":"@some-tag"}]}}],"description":" You can place scenarios inside rules. This makes is possible to structure\n Gherkin documents in the same way as [example maps](https://cucumber.io/blog/bdd/example-mapping-introduction/).\n You can also use the Examples synonym for Scenario to make them even more similar.","keyword":"Feature","language":"en","location":{"column":1,"line":1},"name":"Rules","tags":[]},"uri":"samples/rules/rules.feature"}}
|
4
4
|
{"pickle":{"astNodeIds":["9"],"id":"26","language":"en","name":"no change","steps":[{"astNodeIds":["6"],"id":"23","text":"there are 5 0.20 coins inside","type":"Context"},{"astNodeIds":["7"],"id":"24","text":"the customer tries to buy a 0.85 chocolate with a 1 coin","type":"Action"},{"astNodeIds":["8"],"id":"25","text":"the sale should not happen","type":"Outcome"}],"tags":[],"uri":"samples/rules/rules.feature"}}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.
|
1
|
+
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.3.0"},"os":{"name":"linux","version":"5.15.0-84-generic"},"protocolVersion":"22.0.0","runtime":{"name":"node.js","version":"18.18.0"}}}
|
2
2
|
{"source":{"data":"Feature: Skipping scenarios\n\n Hooks and step definitions are able to signal at runtime that the scenario should\n be skipped by returning or throwing a particular value.\n\n This can be useful when e.g. the current environment doesn't have the right conditions\n for running the scenario.\n\n @skip\n Scenario: Skipping from a Before hook\n Given a step that we expect to be skipped\n\n Scenario: Skipping from a step doesn't affect the previous steps\n Given an implemented step\n When a step that skips\n\n Scenario: Skipping from a step causes the rest of the scenario to be skipped\n Given a step that skips\n When a step that we expect to be skipped\n","mediaType":"text/x.cucumber.gherkin+plain","uri":"samples/skipped/skipped.feature"}}
|
3
3
|
{"gherkinDocument":{"comments":[],"feature":{"children":[{"scenario":{"description":"","examples":[],"id":"6","keyword":"Scenario","location":{"column":3,"line":10},"name":"Skipping from a Before hook","steps":[{"id":"4","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":11},"text":"a step that we expect to be skipped"}],"tags":[{"id":"5","location":{"column":3,"line":9},"name":"@skip"}]}},{"scenario":{"description":"","examples":[],"id":"9","keyword":"Scenario","location":{"column":3,"line":13},"name":"Skipping from a step doesn't affect the previous steps","steps":[{"id":"7","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":14},"text":"an implemented step"},{"id":"8","keyword":"When ","keywordType":"Action","location":{"column":5,"line":15},"text":"a step that skips"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"12","keyword":"Scenario","location":{"column":3,"line":17},"name":"Skipping from a step causes the rest of the scenario to be skipped","steps":[{"id":"10","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":18},"text":"a step that skips"},{"id":"11","keyword":"When ","keywordType":"Action","location":{"column":5,"line":19},"text":"a step that we expect to be skipped"}],"tags":[]}}],"description":" Hooks and step definitions are able to signal at runtime that the scenario should\n be skipped by returning or throwing a particular value.\n\n This can be useful when e.g. the current environment doesn't have the right conditions\n for running the scenario.","keyword":"Feature","language":"en","location":{"column":1,"line":1},"name":"Skipping scenarios","tags":[]},"uri":"samples/skipped/skipped.feature"}}
|
4
4
|
{"pickle":{"astNodeIds":["6"],"id":"14","language":"en","name":"Skipping from a Before hook","steps":[{"astNodeIds":["4"],"id":"13","text":"a step that we expect to be skipped","type":"Context"}],"tags":[{"astNodeId":"5","name":"@skip"}],"uri":"samples/skipped/skipped.feature"}}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.
|
1
|
+
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.3.0"},"os":{"name":"linux","version":"5.15.0-84-generic"},"protocolVersion":"22.0.0","runtime":{"name":"node.js","version":"18.18.0"}}}
|
2
2
|
{"source":{"data":"Feature: Stack traces\n Nothing beats stack traces when it comes to diagnosing the source of a bug.\n Cucumber provides helpful stack traces that:\n \n - Include a stack frame from the Gherkin document\n - Remove uninteresting frames by default\n\n The first line of the stack trace must contain the feature file.\n\n Scenario: A failing step\n When a step throws an exception\n","mediaType":"text/x.cucumber.gherkin+plain","uri":"samples/stack-traces/stack-traces.feature"}}
|
3
3
|
{"gherkinDocument":{"comments":[],"feature":{"children":[{"scenario":{"description":"","examples":[],"id":"2","keyword":"Scenario","location":{"column":3,"line":10},"name":"A failing step","steps":[{"id":"1","keyword":"When ","keywordType":"Action","location":{"column":5,"line":11},"text":"a step throws an exception"}],"tags":[]}}],"description":" Nothing beats stack traces when it comes to diagnosing the source of a bug.\n Cucumber provides helpful stack traces that:\n \n - Include a stack frame from the Gherkin document\n - Remove uninteresting frames by default\n\n The first line of the stack trace must contain the feature file.","keyword":"Feature","language":"en","location":{"column":1,"line":1},"name":"Stack traces","tags":[]},"uri":"samples/stack-traces/stack-traces.feature"}}
|
4
4
|
{"pickle":{"astNodeIds":["2"],"id":"4","language":"en","name":"A failing step","steps":[{"astNodeIds":["1"],"id":"3","text":"a step throws an exception","type":"Action"}],"tags":[],"uri":"samples/stack-traces/stack-traces.feature"}}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.
|
1
|
+
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.3.0"},"os":{"name":"linux","version":"5.15.0-84-generic"},"protocolVersion":"22.0.0","runtime":{"name":"node.js","version":"18.18.0"}}}
|
2
2
|
{"source":{"data":"Feature: Undefined steps\n\n At runtime, Cucumber may encounter a step in a scenario that it cannot match to a\n step definition. In these cases, the scenario cannot run and so the step status\n will be UNDEFINED, with subsequent steps being skipped and the overall result treated\n as a failure.\n\n Scenario: Undefined step causes failure\n Given a step that isnt implemented yet\n\n Scenario: Steps before undefined steps are executed\n Given an implemented step\n When a step that isnt implemented yet\n\n Scenario: Steps after undefined steps are skipped\n Given a step that isnt implemented yet\n Then a step that we expect to be skipped\n","mediaType":"text/x.cucumber.gherkin+plain","uri":"samples/undefined/undefined.feature"}}
|
3
3
|
{"gherkinDocument":{"comments":[],"feature":{"children":[{"scenario":{"description":"","examples":[],"id":"3","keyword":"Scenario","location":{"column":3,"line":8},"name":"Undefined step causes failure","steps":[{"id":"2","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":9},"text":"a step that isnt implemented yet"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"6","keyword":"Scenario","location":{"column":3,"line":11},"name":"Steps before undefined steps are executed","steps":[{"id":"4","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":12},"text":"an implemented step"},{"id":"5","keyword":"When ","keywordType":"Action","location":{"column":5,"line":13},"text":"a step that isnt implemented yet"}],"tags":[]}},{"scenario":{"description":"","examples":[],"id":"9","keyword":"Scenario","location":{"column":3,"line":15},"name":"Steps after undefined steps are skipped","steps":[{"id":"7","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":16},"text":"a step that isnt implemented yet"},{"id":"8","keyword":"Then ","keywordType":"Outcome","location":{"column":5,"line":17},"text":"a step that we expect to be skipped"}],"tags":[]}}],"description":" At runtime, Cucumber may encounter a step in a scenario that it cannot match to a\n step definition. In these cases, the scenario cannot run and so the step status\n will be UNDEFINED, with subsequent steps being skipped and the overall result treated\n as a failure.","keyword":"Feature","language":"en","location":{"column":1,"line":1},"name":"Undefined steps","tags":[]},"uri":"samples/undefined/undefined.feature"}}
|
4
4
|
{"pickle":{"astNodeIds":["3"],"id":"11","language":"en","name":"Undefined step causes failure","steps":[{"astNodeIds":["2"],"id":"10","text":"a step that isnt implemented yet","type":"Context"}],"tags":[],"uri":"samples/undefined/undefined.feature"}}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.
|
1
|
+
{"meta":{"ci":{"buildNumber":"154666429","git":{"remote":"https://github.com/cucumber-ltd/shouty.rb.git","revision":"99684bcacf01d95875834d87903dcb072306c9ad"},"name":"GitHub Actions","url":"https://github.com/cucumber-ltd/shouty.rb/actions/runs/154666429"},"cpu":{"name":"x64"},"implementation":{"name":"fake-cucumber","version":"16.3.0"},"os":{"name":"linux","version":"5.15.0-84-generic"},"protocolVersion":"22.0.0","runtime":{"name":"node.js","version":"18.18.0"}}}
|
2
2
|
{"source":{"data":"Feature: Parameter Types\n Cucumber will generate an error message if a step definition registers\n an unknown parameter type, but the suite will run.\n\n Scenario: undefined parameter type\n Given CDG is closed because of a strike","mediaType":"text/x.cucumber.gherkin+plain","uri":"samples/unknown-parameter-type/unknown-parameter-type.feature"}}
|
3
3
|
{"gherkinDocument":{"comments":[],"feature":{"children":[{"scenario":{"description":"","examples":[],"id":"1","keyword":"Scenario","location":{"column":3,"line":5},"name":"undefined parameter type","steps":[{"id":"0","keyword":"Given ","keywordType":"Context","location":{"column":5,"line":6},"text":"CDG is closed because of a strike"}],"tags":[]}}],"description":" Cucumber will generate an error message if a step definition registers\n an unknown parameter type, but the suite will run.","keyword":"Feature","language":"en","location":{"column":1,"line":1},"name":"Parameter Types","tags":[]},"uri":"samples/unknown-parameter-type/unknown-parameter-type.feature"}}
|
4
4
|
{"pickle":{"astNodeIds":["1"],"id":"3","language":"en","name":"undefined parameter type","steps":[{"astNodeIds":["0"],"id":"2","text":"CDG is closed because of a strike","type":"Context"}],"tags":[],"uri":"samples/unknown-parameter-type/unknown-parameter-type.feature"}}
|
data/lib/keys_checker.rb
CHANGED
@@ -1,28 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CCK
|
2
4
|
class KeysChecker
|
3
|
-
def self.compare(
|
4
|
-
|
5
|
+
def self.compare(detected, expected)
|
6
|
+
new(detected, expected).compare
|
5
7
|
end
|
6
8
|
|
7
|
-
|
8
|
-
errors = []
|
9
|
-
|
10
|
-
found_keys = found.to_h(reject_nil_values: true).keys
|
11
|
-
expected_keys = expected.to_h(reject_nil_values: true).keys
|
12
|
-
|
13
|
-
return errors if found_keys.sort == expected_keys.sort
|
9
|
+
attr_reader :detected, :expected
|
14
10
|
|
15
|
-
|
11
|
+
def initialize(detected, expected)
|
12
|
+
@detected = detected
|
13
|
+
@expected = expected
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
}
|
16
|
+
def compare
|
17
|
+
return [] if identical_keys?
|
20
18
|
|
21
|
-
errors << "
|
22
|
-
errors << "Missing keys in message #{
|
19
|
+
errors << "Detected extra keys in message #{message_name}: #{extra_keys}" if extra_keys.any?
|
20
|
+
errors << "Missing keys in message #{message_name}: #{missing_keys}" if missing_keys.any?
|
23
21
|
errors
|
24
22
|
rescue StandardError => e
|
25
23
|
["Unexpected error: #{e.message}"]
|
26
24
|
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def detected_keys
|
29
|
+
@detected_keys ||= ordered_uniq_hash_keys(detected)
|
30
|
+
end
|
31
|
+
|
32
|
+
def expected_keys
|
33
|
+
@expected_keys ||= ordered_uniq_hash_keys(expected)
|
34
|
+
end
|
35
|
+
|
36
|
+
def identical_keys?
|
37
|
+
detected_keys == expected_keys
|
38
|
+
end
|
39
|
+
|
40
|
+
def missing_keys
|
41
|
+
(expected_keys - detected_keys).reject { |key| meta_message? && key == :ci }
|
42
|
+
end
|
43
|
+
|
44
|
+
def extra_keys
|
45
|
+
(detected_keys - expected_keys).reject { |key| meta_message? && key == :ci }
|
46
|
+
end
|
47
|
+
|
48
|
+
def meta_message?
|
49
|
+
detected.instance_of?(Cucumber::Messages::Meta)
|
50
|
+
end
|
51
|
+
|
52
|
+
def message_name
|
53
|
+
detected.class.name
|
54
|
+
end
|
55
|
+
|
56
|
+
def ordered_uniq_hash_keys(object)
|
57
|
+
object.to_h(reject_nil_values: true).keys.sort
|
58
|
+
end
|
59
|
+
|
60
|
+
def errors
|
61
|
+
@errors ||= []
|
62
|
+
end
|
27
63
|
end
|
28
64
|
end
|
data/lib/messages_comparator.rb
CHANGED
data/lib/shared_examples.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
require 'rspec'
|
3
5
|
require 'cucumber/messages'
|
@@ -10,8 +12,8 @@ RSpec.shared_examples 'cucumber compatibility kit' do
|
|
10
12
|
# let(:example) { } # the name of the example to test
|
11
13
|
# let(:messages) { } # the messages to validate
|
12
14
|
|
13
|
-
let(:example) { raise
|
14
|
-
let(:messages) { raise
|
15
|
+
let(:example) { raise '`example` missing: add `let(:example) { example_name }` to your spec' }
|
16
|
+
let(:messages) { raise '`messages` missing: add `let(:messages) { ndjson }` to your spec' }
|
15
17
|
|
16
18
|
let(:example_path) { Cucumber::CompatibilityKit.example_path(example) }
|
17
19
|
|
@@ -45,7 +47,10 @@ def parse_ndjson(ndjson)
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def message_type(message)
|
48
|
-
|
50
|
+
# TODO: This is duplicate code - from messages_comparator:45 - It should live in a common helper methods module
|
51
|
+
message.to_h.each do |key, value|
|
52
|
+
return key unless value.nil?
|
53
|
+
end
|
49
54
|
end
|
50
55
|
|
51
56
|
def debug_lists(expected, obtained)
|
data/spec/capture_warnings.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# With thanks to @myronmarston
|
3
4
|
# https://github.com/vcr/vcr/blob/master/spec/capture_warnings.rb
|
4
5
|
|
@@ -18,14 +19,14 @@ module CaptureWarnings
|
|
18
19
|
end
|
19
20
|
|
20
21
|
# Until they fix https://bugs.ruby-lang.org/issues/10661
|
21
|
-
if RUBY_VERSION ==
|
22
|
+
if RUBY_VERSION == '2.2.0'
|
22
23
|
project_warnings = project_warnings.reject { |w| w =~ /warning: possible reference to past scope/ }
|
23
24
|
end
|
24
25
|
|
25
26
|
if project_warnings.any?
|
26
27
|
puts "#{ project_warnings.count } warnings detected"
|
27
28
|
print_warnings('cucumber-expressions', project_warnings)
|
28
|
-
fail
|
29
|
+
fail 'Please remove all cucumber-expressions warnings.'
|
29
30
|
end
|
30
31
|
|
31
32
|
ensure_system_exit_if_required
|
@@ -56,11 +57,11 @@ module CaptureWarnings
|
|
56
57
|
|
57
58
|
def print_warnings(type, warnings)
|
58
59
|
puts
|
59
|
-
puts
|
60
|
+
puts '-' * 30 + " #{type} warnings: " + '-' * 30
|
60
61
|
puts
|
61
62
|
puts warnings.join("\n")
|
62
63
|
puts
|
63
|
-
puts
|
64
|
+
puts '-' * 75
|
64
65
|
puts
|
65
66
|
end
|
66
67
|
|
@@ -69,6 +70,6 @@ module CaptureWarnings
|
|
69
70
|
end
|
70
71
|
|
71
72
|
def capture_system_exit
|
72
|
-
@system_exit =
|
73
|
+
@system_exit = $ERROR_INFO
|
73
74
|
end
|
74
75
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'cucumber-compatibility-kit'
|
2
4
|
|
3
5
|
describe Cucumber::CompatibilityKit do
|
@@ -28,7 +30,7 @@ describe Cucumber::CompatibilityKit do
|
|
28
30
|
|
29
31
|
describe '#examples_path' do
|
30
32
|
it 'returns the path of the features folder' do
|
31
|
-
expect(
|
33
|
+
expect(described_class.examples_path)
|
32
34
|
.to eq(features_path)
|
33
35
|
end
|
34
36
|
end
|
@@ -36,14 +38,14 @@ describe Cucumber::CompatibilityKit do
|
|
36
38
|
describe '#example_path' do
|
37
39
|
context 'with an existing example' do
|
38
40
|
it 'returns the path of the folder of the example' do
|
39
|
-
expect(
|
41
|
+
expect(described_class.example_path('hooks'))
|
40
42
|
.to eq("#{features_path}/hooks")
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
46
|
context 'with an unexisting example' do
|
45
47
|
it 'raises ArgumentError' do
|
46
|
-
expect {
|
48
|
+
expect { described_class.example_path('should-not-exists') }
|
47
49
|
.to raise_error(ArgumentError)
|
48
50
|
end
|
49
51
|
end
|
@@ -51,22 +53,22 @@ describe Cucumber::CompatibilityKit do
|
|
51
53
|
|
52
54
|
describe '#gherkin_examples' do
|
53
55
|
it 'returns the list of gherkin examples' do
|
54
|
-
expect(
|
56
|
+
expect(described_class.gherkin_examples)
|
55
57
|
.to match_array(gherkin_examples)
|
56
58
|
end
|
57
59
|
end
|
58
60
|
|
59
61
|
describe '#markdown_examples' do
|
60
62
|
it 'returns the list of markdown examples' do
|
61
|
-
expect(
|
63
|
+
expect(described_class.markdown_examples)
|
62
64
|
.to match_array(markdown_examples)
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
66
68
|
describe '#all_examples' do
|
67
69
|
it 'returns the list of all available examples' do
|
68
|
-
expect(
|
70
|
+
expect(described_class.all_examples)
|
69
71
|
.to match_array(gherkin_examples + markdown_examples)
|
70
72
|
end
|
71
73
|
end
|
72
|
-
end
|
74
|
+
end
|
data/spec/keys_checker_spec.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rspec'
|
2
4
|
require 'cucumber/messages'
|
3
5
|
require_relative '../lib/keys_checker'
|
4
6
|
|
5
7
|
describe CCK::KeysChecker do
|
6
|
-
let(:subject) {
|
8
|
+
let(:subject) { described_class }
|
7
9
|
|
8
10
|
describe '#compare' do
|
9
11
|
let(:complete) do
|
@@ -14,15 +16,11 @@ describe CCK::KeysChecker do
|
|
14
16
|
end
|
15
17
|
|
16
18
|
let(:missing_data_table) do
|
17
|
-
Cucumber::Messages::PickleStepArgument.new(
|
18
|
-
doc_string: '1'
|
19
|
-
)
|
19
|
+
Cucumber::Messages::PickleStepArgument.new(doc_string: '1')
|
20
20
|
end
|
21
21
|
|
22
22
|
let(:missing_doc_string) do
|
23
|
-
Cucumber::Messages::PickleStepArgument.new(
|
24
|
-
data_table: '12'
|
25
|
-
)
|
23
|
+
Cucumber::Messages::PickleStepArgument.new(data_table: '12')
|
26
24
|
end
|
27
25
|
|
28
26
|
let(:wrong_values) do
|
@@ -40,14 +38,14 @@ describe CCK::KeysChecker do
|
|
40
38
|
|
41
39
|
it 'finds extra keys' do
|
42
40
|
expect(subject.compare(complete, missing_doc_string)).to eq(
|
43
|
-
['
|
41
|
+
['Detected extra keys in message Cucumber::Messages::PickleStepArgument: [:doc_string]']
|
44
42
|
)
|
45
43
|
end
|
46
44
|
|
47
45
|
it 'finds extra and missing' do
|
48
46
|
expect(subject.compare(missing_doc_string, missing_data_table)).to contain_exactly(
|
49
47
|
'Missing keys in message Cucumber::Messages::PickleStepArgument: [:doc_string]',
|
50
|
-
'
|
48
|
+
'Detected extra keys in message Cucumber::Messages::PickleStepArgument: [:data_table]'
|
51
49
|
)
|
52
50
|
end
|
53
51
|
|
@@ -64,9 +62,7 @@ describe CCK::KeysChecker do
|
|
64
62
|
end
|
65
63
|
|
66
64
|
let(:default_not_set) do
|
67
|
-
Cucumber::Messages::Duration.new(
|
68
|
-
nanos: 12
|
69
|
-
)
|
65
|
+
Cucumber::Messages::Duration.new(nanos: 12)
|
70
66
|
end
|
71
67
|
|
72
68
|
it 'does not raise an exception' do
|
@@ -75,26 +71,19 @@ describe CCK::KeysChecker do
|
|
75
71
|
end
|
76
72
|
|
77
73
|
context 'when executed as part of a CI' do
|
78
|
-
before
|
79
|
-
allow(ENV).to receive(:[]).with('CI').and_return(true)
|
80
|
-
end
|
74
|
+
before { allow(ENV).to receive(:[]).with('CI').and_return(true) }
|
81
75
|
|
82
76
|
it 'ignores actual CI related messages' do
|
83
|
-
|
84
|
-
ci: Cucumber::Messages::Ci.new(name: 'Some CI')
|
85
|
-
)
|
86
|
-
|
77
|
+
detected = Cucumber::Messages::Meta.new(ci: Cucumber::Messages::Ci.new(name: 'Some CI'))
|
87
78
|
expected = Cucumber::Messages::Meta.new
|
88
79
|
|
89
|
-
expect(subject.compare(
|
80
|
+
expect(subject.compare(detected, expected)).to be_empty
|
90
81
|
end
|
91
82
|
end
|
92
83
|
|
93
|
-
context 'when an
|
84
|
+
context 'when an unexpected error occurs' do
|
94
85
|
it 'does not raise error' do
|
95
|
-
expect {
|
96
|
-
subject.compare(nil, nil)
|
97
|
-
}.not_to raise_error
|
86
|
+
expect { subject.compare(nil, nil) }.not_to raise_error
|
98
87
|
end
|
99
88
|
|
100
89
|
it 'returns the error' do
|
@@ -1,26 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rspec'
|
2
4
|
require 'cucumber/messages'
|
3
5
|
require_relative '../lib/messages_comparator'
|
4
6
|
|
5
7
|
describe CCK::MessagesComparator do
|
6
|
-
subject() { CCK::MessagesComparator }
|
7
|
-
|
8
8
|
context 'when executed as part of a CI' do
|
9
|
-
before
|
10
|
-
|
9
|
+
before { allow(ENV).to receive(:[]).with('CI').and_return(true) }
|
10
|
+
|
11
|
+
it 'ignores any detected CI messages' do
|
12
|
+
detected_message_ci = Cucumber::Messages::Ci.new(name: 'Some CI')
|
13
|
+
detected_message_meta = Cucumber::Messages::Meta.new(ci: detected_message_ci)
|
14
|
+
detected_message_envelope = Cucumber::Messages::Envelope.new(meta: detected_message_meta)
|
15
|
+
|
16
|
+
expected_message_meta = Cucumber::Messages::Meta.new
|
17
|
+
expected_message_envelope = Cucumber::Messages::Envelope.new(meta: expected_message_meta)
|
18
|
+
|
19
|
+
comparator = described_class.new(CCK::KeysChecker, [detected_message_envelope], [expected_message_envelope])
|
20
|
+
|
21
|
+
expect(comparator.errors).to be_empty
|
11
22
|
end
|
12
23
|
|
13
|
-
it 'ignores
|
14
|
-
|
15
|
-
|
16
|
-
found_message_envelope = Cucumber::Messages::Envelope.new(meta: found_message_meta)
|
24
|
+
it 'ignores any expected CI messages' do
|
25
|
+
detected_message_meta = Cucumber::Messages::Meta.new
|
26
|
+
detected_message_envelope = Cucumber::Messages::Envelope.new(meta: detected_message_meta)
|
17
27
|
|
18
|
-
|
28
|
+
expected_message_ci = Cucumber::Messages::Ci.new(name: 'Some CI')
|
29
|
+
expected_message_meta = Cucumber::Messages::Meta.new(ci: expected_message_ci)
|
19
30
|
expected_message_envelope = Cucumber::Messages::Envelope.new(meta: expected_message_meta)
|
20
31
|
|
21
|
-
comparator =
|
32
|
+
comparator = described_class.new(CCK::KeysChecker, [detected_message_envelope], [expected_message_envelope])
|
22
33
|
|
23
34
|
expect(comparator.errors).to be_empty
|
24
35
|
end
|
25
36
|
end
|
26
|
-
end
|
37
|
+
end
|