cuke_modeler 1.3.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +60 -17
  3. data/CHANGELOG.md +312 -0
  4. data/Gemfile +19 -3
  5. data/LICENSE.txt +1 -1
  6. data/README.md +17 -7
  7. data/Rakefile +45 -28
  8. data/appveyor.yml +57 -17
  9. data/cuke_modeler.gemspec +6 -3
  10. data/lib/cuke_modeler/adapters/gherkin_2_adapter.rb +1 -0
  11. data/lib/cuke_modeler/adapters/gherkin_3_adapter.rb +1 -0
  12. data/lib/cuke_modeler/adapters/gherkin_4_adapter.rb +2 -1
  13. data/lib/cuke_modeler/adapters/gherkin_5_adapter.rb +12 -0
  14. data/lib/cuke_modeler/adapters/gherkin_6_adapter.rb +310 -0
  15. data/lib/cuke_modeler/adapters/gherkin_7_adapter.rb +307 -0
  16. data/lib/cuke_modeler/adapters/gherkin_8_adapter.rb +12 -0
  17. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +12 -0
  18. data/lib/cuke_modeler/containing.rb +16 -0
  19. data/lib/cuke_modeler/described.rb +1 -0
  20. data/lib/cuke_modeler/models/step.rb +31 -2
  21. data/lib/cuke_modeler/named.rb +1 -0
  22. data/lib/cuke_modeler/nested.rb +1 -0
  23. data/lib/cuke_modeler/parsed.rb +1 -0
  24. data/lib/cuke_modeler/parsing.rb +116 -68
  25. data/lib/cuke_modeler/sourceable.rb +1 -0
  26. data/lib/cuke_modeler/stepped.rb +1 -0
  27. data/lib/cuke_modeler/taggable.rb +1 -0
  28. data/lib/cuke_modeler/version.rb +1 -1
  29. data/testing/cucumber/features/analysis/step_comparison.feature +25 -0
  30. data/testing/cucumber/features/analysis/test_comparison.feature +1 -1
  31. data/testing/cucumber/step_definitions/feature_file_steps.rb +1 -1
  32. data/testing/cucumber/step_definitions/modeling_steps.rb +7 -2
  33. data/testing/cucumber/step_definitions/verification_steps.rb +11 -2
  34. data/testing/file_helper.rb +3 -0
  35. data/testing/gemfiles/gherkin2.gemfile +8 -0
  36. data/testing/gemfiles/gherkin3.gemfile +6 -0
  37. data/testing/gemfiles/gherkin4.gemfile +7 -0
  38. data/testing/gemfiles/gherkin5.gemfile +7 -0
  39. data/testing/gemfiles/gherkin6.gemfile +10 -0
  40. data/testing/gemfiles/gherkin7.gemfile +9 -0
  41. data/testing/gemfiles/gherkin8.gemfile +9 -0
  42. data/testing/gemfiles/gherkin9.gemfile +9 -0
  43. data/testing/helper_methods.rb +23 -0
  44. data/testing/rspec/spec/integration/{gherkin_2_adapter_spec.rb → adapters/gherkin_2_adapter_spec.rb} +13 -13
  45. data/testing/rspec/spec/integration/{gherkin_3_adapter_spec.rb → adapters/gherkin_3_adapter_spec.rb} +13 -13
  46. data/testing/rspec/spec/integration/{gherkin_4_adapter_spec.rb → adapters/gherkin_4_adapter_spec.rb} +13 -13
  47. data/testing/rspec/spec/integration/adapters/gherkin_5_adapter_spec.rb +165 -0
  48. data/testing/rspec/spec/integration/adapters/gherkin_6_adapter_spec.rb +159 -0
  49. data/testing/rspec/spec/integration/adapters/gherkin_7_adapter_spec.rb +162 -0
  50. data/testing/rspec/spec/integration/adapters/gherkin_8_adapter_spec.rb +162 -0
  51. data/testing/rspec/spec/integration/adapters/gherkin_9_adapter_spec.rb +162 -0
  52. data/testing/rspec/spec/integration/{background_integration_spec.rb → models/background_integration_spec.rb} +90 -86
  53. data/testing/rspec/spec/integration/{cell_integration_spec.rb → models/cell_integration_spec.rb} +49 -38
  54. data/testing/rspec/spec/integration/{comment_integration_spec.rb → models/comment_integration_spec.rb} +31 -20
  55. data/testing/rspec/spec/integration/{directory_integration_spec.rb → models/directory_integration_spec.rb} +3 -3
  56. data/testing/rspec/spec/integration/{doc_string_integration_spec.rb → models/doc_string_integration_spec.rb} +39 -35
  57. data/testing/rspec/spec/integration/{example_integration_spec.rb → models/example_integration_spec.rb} +109 -83
  58. data/testing/rspec/spec/integration/{feature_file_integration_spec.rb → models/feature_file_integration_spec.rb} +52 -38
  59. data/testing/rspec/spec/integration/{feature_integration_spec.rb → models/feature_integration_spec.rb} +125 -112
  60. data/testing/rspec/spec/integration/{model_integration_spec.rb → models/model_integration_spec.rb} +1 -1
  61. data/testing/rspec/spec/integration/{outline_integration_spec.rb → models/outline_integration_spec.rb} +138 -129
  62. data/testing/rspec/spec/integration/{row_integration_spec.rb → models/row_integration_spec.rb} +55 -35
  63. data/testing/rspec/spec/integration/{scenario_integration_spec.rb → models/scenario_integration_spec.rb} +92 -88
  64. data/testing/rspec/spec/integration/models/step_integration_spec.rb +573 -0
  65. data/testing/rspec/spec/integration/{table_integration_spec.rb → models/table_integration_spec.rb} +38 -34
  66. data/testing/rspec/spec/integration/{tag_integration_spec.rb → models/tag_integration_spec.rb} +56 -36
  67. data/testing/rspec/spec/integration/parsing_integration_spec.rb +45 -7
  68. data/testing/rspec/spec/spec_helper.rb +79 -43
  69. data/testing/rspec/spec/unit/cuke_modeler_unit_spec.rb +25 -0
  70. data/testing/rspec/spec/unit/{background_unit_spec.rb → models/background_unit_spec.rb} +1 -1
  71. data/testing/rspec/spec/unit/{cell_unit_spec.rb → models/cell_unit_spec.rb} +1 -1
  72. data/testing/rspec/spec/unit/{comment_unit_spec.rb → models/comment_unit_spec.rb} +1 -1
  73. data/testing/rspec/spec/unit/{directory_unit_spec.rb → models/directory_unit_spec.rb} +1 -1
  74. data/testing/rspec/spec/unit/{doc_string_unit_spec.rb → models/doc_string_unit_spec.rb} +1 -1
  75. data/testing/rspec/spec/unit/{example_unit_spec.rb → models/example_unit_spec.rb} +1 -1
  76. data/testing/rspec/spec/unit/{feature_file_unit_spec.rb → models/feature_file_unit_spec.rb} +1 -1
  77. data/testing/rspec/spec/unit/{feature_unit_spec.rb → models/feature_unit_spec.rb} +1 -1
  78. data/testing/rspec/spec/unit/{model_unit_spec.rb → models/model_unit_spec.rb} +1 -1
  79. data/testing/rspec/spec/unit/{outline_unit_spec.rb → models/outline_unit_spec.rb} +1 -1
  80. data/testing/rspec/spec/unit/{row_unit_spec.rb → models/row_unit_spec.rb} +1 -1
  81. data/testing/rspec/spec/unit/{scenario_unit_spec.rb → models/scenario_unit_spec.rb} +1 -1
  82. data/testing/rspec/spec/unit/{step_unit_spec.rb → models/step_unit_spec.rb} +2 -2
  83. data/testing/rspec/spec/unit/{table_unit_spec.rb → models/table_unit_spec.rb} +1 -1
  84. data/testing/rspec/spec/unit/{tag_unit_spec.rb → models/tag_unit_spec.rb} +1 -1
  85. data/testing/rspec/spec/unit/shared/containing_models_unit_specs.rb +102 -0
  86. data/todo.txt +5 -2
  87. metadata +80 -47
  88. data/History.md +0 -186
  89. data/testing/cucumber/support/transforms.rb +0 -3
  90. data/testing/rspec/spec/integration/step_integration_spec.rb +0 -459
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2017 Eric Kessler, et al
1
+ Copyright (c) 2014-2020 Eric Kessler, et al
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,11 +1,20 @@
1
+ Basic stuff:
1
2
  [![Gem Version](https://badge.fury.io/rb/cuke_modeler.svg)](https://rubygems.org/gems/cuke_modeler)
2
- [![Dependency Status](https://gemnasium.com/enkessler/cuke_modeler.svg)](https://gemnasium.com/enkessler/cuke_modeler)
3
+ [![Project License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/mit-license.php)
4
+ [![Downloads](https://img.shields.io/gem/dt/cuke_modeler.svg)](https://rubygems.org/gems/cuke_modeler)
5
+
6
+ User stuff:
7
+ [![Cucumber Docs](http://img.shields.io/badge/Documentation-Features-green.svg)](https://app.cucumber.pro/projects/cuke_modeler)
8
+ [![Yard Docs](http://img.shields.io/badge/Documentation-API-blue.svg)](https://www.rubydoc.info/gems/cuke_modeler)
9
+
10
+ Developer stuff:
3
11
  [![Build Status](https://travis-ci.org/enkessler/cuke_modeler.svg?branch=dev)](https://travis-ci.org/enkessler/cuke_modeler)
4
12
  [![Build status](https://ci.appveyor.com/api/projects/status/is8xqvoqn3pjh9l0/branch/dev?svg=true)](https://ci.appveyor.com/project/enkessler/cuke-modeler/branch/dev)
5
13
  [![Coverage Status](https://coveralls.io/repos/github/enkessler/cuke_modeler/badge.svg?branch=dev)](https://coveralls.io/github/enkessler/cuke_modeler?branch=dev)
6
- [![Code Quality](https://codeclimate.com/github/enkessler/cuke_modeler/badges/gpa.svg)](https://codeclimate.com/github/enkessler/cuke_modeler)
7
- [![Project License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/mit-license.php)
14
+ [![Maintainability](https://api.codeclimate.com/v1/badges/83986d8f7a918fed9707/maintainability)](https://codeclimate.com/github/enkessler/cuke_modeler/maintainability)
15
+ [![Inline docs](http://inch-ci.org/github/enkessler/cuke_modeler.svg?branch=dev)](https://inch-ci.org/github/enkessler/cuke_modeler?branch=dev)
8
16
 
17
+ ---
9
18
 
10
19
  # CukeModeler
11
20
 
@@ -18,7 +27,7 @@ the rescue by providing a modeling layer that is easier to work with.
18
27
 
19
28
  Whether you just want something that will let you easily inspect your test
20
29
  suite or you are looking for a foundation tool upon which to build something
21
- Really Neat, this gem has you covered.
30
+ [Really Neat](#projects), this gem has you covered.
22
31
 
23
32
 
24
33
  ## Installation
@@ -74,7 +83,7 @@ One could, if so inclined, use this method to dynamically edit or even create
74
83
  an entire test suite!
75
84
 
76
85
  For more information on the different models and how to use them, see the
77
- [documentation](http://www.relishapp.com/enkessler/CukeModeler/docs).
86
+ [documentation](https://app.cucumber.pro/projects/cuke_modeler).
78
87
 
79
88
  ## Modeling dialects other than English
80
89
 
@@ -108,18 +117,19 @@ that feature is ultimately run with SpecFlow (Cucumber for C#), Lettuce
108
117
  (Cucumber for Python), or some other flavor of Cucumber.
109
118
 
110
119
 
111
- ### Other gems that are (or soon will be) powered by **cuke_modeler**
120
+ ### <a id="projects"></a>Other gems that are powered by **cuke_modeler**
112
121
 
113
122
  * [cql](https://github.com/enkessler/cql)
114
123
  * [cuketagger](https://github.com/enkessler/cuketagger)
115
124
  * [cuke_cataloger](https://github.com/enkessler/cuke_cataloger)
116
125
  * [cuke_slicer](https://github.com/grange-insurance/cuke_slicer)
126
+ * [cuke_linter](https://github.com/enkessler/cuke_linter)
117
127
 
118
128
 
119
129
  ## Contributing
120
130
 
121
131
  1. Fork it
122
- 2. Create your feature branch (off of the development branch)
132
+ 2. Create your feature branch (**off of the development branch**)
123
133
  `git checkout -b my-new-feature`
124
134
  3. Commit your changes
125
135
  `git commit -am 'Add some feature'`
data/Rakefile CHANGED
@@ -1,56 +1,73 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'racatt'
2
4
  require 'coveralls/rake/task'
5
+ require 'rainbow'
3
6
 
4
- require 'racatt'
7
+
8
+ Rainbow.enabled = true
9
+
10
+ namespace 'racatt' do
11
+ Racatt.create_tasks
12
+ end
5
13
 
6
14
 
7
15
  namespace 'cuke_modeler' do
8
16
 
17
+ desc 'Removes the current code coverage data'
9
18
  task :clear_coverage do
10
19
  code_coverage_directory = "#{File.dirname(__FILE__)}/coverage"
11
20
 
12
21
  FileUtils.remove_dir(code_coverage_directory, true)
13
22
  end
14
23
 
24
+ desc 'Check documentation with RDoc'
25
+ task :check_documentation do
26
+ output = `rdoc lib -C`
27
+ puts output
15
28
 
16
- Racatt.create_tasks
17
-
18
- # Redefining the task from 'racatt' in order to clear the code coverage results
19
- task :test_everything => :clear_coverage
29
+ if output =~ /100.00% documented/
30
+ puts Rainbow('All code documented').green
31
+ else
32
+ raise Rainbow('Parts of the gem are undocumented').red
33
+ end
34
+ end
20
35
 
36
+ desc 'Run all of the tests'
37
+ task :test_everything => [:clear_coverage] do
38
+ rspec_args = '--tag ~@wip --pattern "testing/rspec/spec/**/*_spec.rb" --force-color'
21
39
 
22
- # The task that CI will use
23
- Coveralls::RakeTask.new
24
- task :ci_build => [:smart_test, 'coveralls:push']
40
+ cucumber_version = Gem.loaded_specs['cucumber'].version.version
25
41
 
26
- desc 'Test gem based on Ruby/dependency versions'
27
- task :smart_test do |t, args|
28
- rspec_args = '--tag ~@wip --pattern testing/rspec/spec/**/*_spec.rb'
29
- cucumber_args = 'testing/cucumber/features -r testing/cucumber/support -r testing/cucumber/step_definitions -f progress -t ~@wip'
42
+ if cucumber_version =~ /^[123]\./
43
+ cucumber_args = 'testing/cucumber/features -r testing/cucumber/support -r testing/cucumber/step_definitions -f progress -t ~@wip --color'
44
+ else
45
+ cucumber_args = "testing/cucumber/features -r testing/cucumber/support -r testing/cucumber/step_definitions -f progress -t 'not @wip' --color"
46
+ end
30
47
 
31
- Rake::Task['cuke_modeler:test_everything'].invoke(rspec_args, cucumber_args)
48
+ Rake::Task['racatt:test_everything'].invoke(rspec_args, cucumber_args)
32
49
  end
33
50
 
51
+ # creates coveralls:push task
52
+ Coveralls::RakeTask.new
34
53
 
35
- # The task used to publish the current feature file documentation to Relish
36
- desc 'Publish feature files to Relish'
37
- task :publish_features do
38
- # Get existing versions
39
- this_dir = File.dirname(__FILE__)
40
- output = `relish versions enkessler/CukeModeler`
41
-
42
- # Add the current version if it doesn't exist
43
- unless output =~ /#{Regexp.escape(CukeModeler::VERSION)}/
44
- output = `relish versions:add enkessler/CukeModeler:#{CukeModeler::VERSION}`
45
- puts output
54
+ desc 'The task that CI will run. Do not run locally.'
55
+ task :ci_build => ['cuke_modeler:test_everything', 'coveralls:push']
56
+
57
+ desc 'Check that things look good before trying to release'
58
+ task :prerelease_check do
59
+ begin
60
+ Rake::Task['cuke_modeler:test_everything'].invoke
61
+ Rake::Task['cuke_modeler:check_documentation'].invoke
62
+ rescue => e
63
+ puts Rainbow("Something isn't right!").red
64
+ raise e
46
65
  end
47
66
 
48
- # Publish the features
49
- output = `relish push enkessler/CukeModeler:#{CukeModeler::VERSION} path #{this_dir}/testing/cucumber`
50
- puts output
67
+ puts Rainbow('All is well. :)').green
51
68
  end
52
69
 
53
70
  end
54
71
 
55
72
 
56
- task :default => 'cuke_modeler:smart_test'
73
+ task :default => 'cuke_modeler:test_everything'
@@ -2,37 +2,77 @@ version: '1.0.{build}'
2
2
 
3
3
  environment:
4
4
  matrix:
5
- - RUBY_VERSION: 193
5
+
6
+ # Gherkin 2.x does not appear to support 32-bit Ruby 2.x and it's not worth it to investigate if this is true or not
7
+ - RUBY_VERSION: 24-x64
6
8
  BUNDLE_GEMFILE: testing/gemfiles/gherkin2.gemfile
7
- # AppVeyor does not have a 64-bit Ruby 1.9.3
8
- # Gherkin 2.x does not appear to support 32-bit Ruby 2.x and it's not worth it to investigate if this is true or not
9
- - RUBY_VERSION: 23-x64
9
+ - RUBY_VERSION: 25-x64
10
10
  BUNDLE_GEMFILE: testing/gemfiles/gherkin2.gemfile
11
11
 
12
- - RUBY_VERSION: 193
12
+ - RUBY_VERSION: 24
13
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin3.gemfile
14
+ - RUBY_VERSION: 24-x64
13
15
  BUNDLE_GEMFILE: testing/gemfiles/gherkin3.gemfile
14
- # AppVeyor does not have a 64-bit Ruby 1.9.3
15
- - RUBY_VERSION: 23
16
+ - RUBY_VERSION: 25
16
17
  BUNDLE_GEMFILE: testing/gemfiles/gherkin3.gemfile
17
- - RUBY_VERSION: 23-x64
18
+ - RUBY_VERSION: 25-x64
18
19
  BUNDLE_GEMFILE: testing/gemfiles/gherkin3.gemfile
19
20
 
20
- - RUBY_VERSION: 193
21
+ - RUBY_VERSION: 24
21
22
  BUNDLE_GEMFILE: testing/gemfiles/gherkin4.gemfile
22
- # AppVeyor does not have a 64-bit Ruby 1.9.3
23
- - RUBY_VERSION: 23
23
+ - RUBY_VERSION: 24-x64
24
24
  BUNDLE_GEMFILE: testing/gemfiles/gherkin4.gemfile
25
- - RUBY_VERSION: 23-x64
25
+ - RUBY_VERSION: 25
26
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin4.gemfile
27
+ - RUBY_VERSION: 25-x64
26
28
  BUNDLE_GEMFILE: testing/gemfiles/gherkin4.gemfile
27
29
 
28
- - RUBY_VERSION: 193
30
+ - RUBY_VERSION: 24
31
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin5.gemfile
32
+ - RUBY_VERSION: 24-x64
29
33
  BUNDLE_GEMFILE: testing/gemfiles/gherkin5.gemfile
30
- # AppVeyor does not have a 64-bit Ruby 1.9.3
31
- - RUBY_VERSION: 23
34
+ - RUBY_VERSION: 25
32
35
  BUNDLE_GEMFILE: testing/gemfiles/gherkin5.gemfile
33
- - RUBY_VERSION: 23-x64
36
+ - RUBY_VERSION: 25-x64
34
37
  BUNDLE_GEMFILE: testing/gemfiles/gherkin5.gemfile
35
38
 
39
+ # Gherkin 6.x+ requires at least Ruby 2.2
40
+ - RUBY_VERSION: 24
41
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin6.gemfile
42
+ - RUBY_VERSION: 24-x64
43
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin6.gemfile
44
+ - RUBY_VERSION: 25
45
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin6.gemfile
46
+ - RUBY_VERSION: 25-x64
47
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin6.gemfile
48
+
49
+ - RUBY_VERSION: 24
50
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin7.gemfile
51
+ - RUBY_VERSION: 24-x64
52
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin7.gemfile
53
+ - RUBY_VERSION: 25
54
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin7.gemfile
55
+ - RUBY_VERSION: 25-x64
56
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin7.gemfile
57
+
58
+ - RUBY_VERSION: 24
59
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin8.gemfile
60
+ - RUBY_VERSION: 24-x64
61
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin8.gemfile
62
+ - RUBY_VERSION: 25
63
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin8.gemfile
64
+ - RUBY_VERSION: 25-x64
65
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin8.gemfile
66
+
67
+ - RUBY_VERSION: 24
68
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin9.gemfile
69
+ - RUBY_VERSION: 24-x64
70
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin9.gemfile
71
+ - RUBY_VERSION: 25
72
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin9.gemfile
73
+ - RUBY_VERSION: 25-x64
74
+ BUNDLE_GEMFILE: testing/gemfiles/gherkin9.gemfile
75
+
36
76
  install:
37
77
  - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
38
78
  - bundle install
@@ -45,4 +85,4 @@ before_test:
45
85
  - bundle -v
46
86
 
47
87
  test_script:
48
- - bundle exec rake
88
+ - bundle exec rake cuke_modeler:ci_build
@@ -18,15 +18,18 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_runtime_dependency 'gherkin', '< 6.0'
21
+ spec.required_ruby_version = '>= 1.8.7', '< 3.0'
22
+
23
+ spec.add_runtime_dependency 'gherkin', '< 10.0'
22
24
  spec.add_runtime_dependency('json', '>= 1.0', '< 3.0')
23
25
  spec.add_runtime_dependency('multi_json', '~> 1.0')
24
26
 
25
- spec.add_development_dependency "bundler", "~> 1.5"
27
+ spec.add_development_dependency 'bundler', '< 3.0'
26
28
  spec.add_development_dependency "rake", '< 13.0.0'
27
- spec.add_development_dependency 'cucumber', '< 3.0.0'
29
+ spec.add_development_dependency 'cucumber', '< 5.0.0'
28
30
  spec.add_development_dependency 'rspec', '~> 3.0'
29
31
  spec.add_development_dependency 'simplecov', '< 1.0.0'
30
32
  spec.add_development_dependency 'racatt', '~> 1.0'
31
33
  spec.add_development_dependency 'coveralls', '< 1.0.0'
34
+ spec.add_development_dependency 'rainbow', '< 4.0.0'
32
35
  end
@@ -1,5 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
+ # NOT A PART OF THE PUBLIC API
3
4
  # An adapter that can convert the output of version 2.x of the *gherkin* gem into input that is consumable by this gem.
4
5
 
5
6
  class Gherkin2Adapter
@@ -1,5 +1,6 @@
1
1
  module CukeModeler
2
2
 
3
+ # NOT A PART OF THE PUBLIC API
3
4
  # An adapter that can convert the output of version 3.x of the *gherkin* gem into input that is consumable by this gem.
4
5
 
5
6
  class Gherkin3Adapter
@@ -1,6 +1,7 @@
1
1
  module CukeModeler
2
2
 
3
- # An adapter that can convert the output of version 4.x and 5.x of the *gherkin* gem into input that is consumable by this gem.
3
+ # NOT A PART OF THE PUBLIC API
4
+ # An adapter that can convert the output of version 4.x of the *gherkin* gem into input that is consumable by this gem.
4
5
 
5
6
  class Gherkin4Adapter
6
7
 
@@ -0,0 +1,12 @@
1
+ require_relative 'gherkin_4_adapter'
2
+
3
+ module CukeModeler
4
+
5
+ # NOT A PART OF THE PUBLIC API
6
+ # An adapter that can convert the output of version 5.x of the *gherkin* gem into input that is consumable by this gem.
7
+
8
+ class Gherkin5Adapter < Gherkin4Adapter
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,310 @@
1
+ module CukeModeler
2
+
3
+ # NOT A PART OF THE PUBLIC API
4
+ # An adapter that can convert the output of version 6.x of the *gherkin* gem into input that is consumable by this gem.
5
+
6
+ class Gherkin6Adapter
7
+
8
+ # Adapts the given AST into the shape that this gem expects
9
+ def adapt(parsed_ast)
10
+ # Saving off the original data
11
+ parsed_ast['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_ast))
12
+
13
+ # Removing parsed data for child elements in order to avoid duplicating data
14
+ parsed_ast['cuke_modeler_parsing_data'][:feature] = nil
15
+ parsed_ast['cuke_modeler_parsing_data'][:comments] = nil
16
+
17
+ # Comments are stored on the feature file in gherkin 4.x
18
+ parsed_ast['comments'] = []
19
+ parsed_ast[:comments].each do |comment|
20
+ adapt_comment!(comment)
21
+ end
22
+ parsed_ast['comments'].concat(parsed_ast.delete(:comments))
23
+
24
+ adapt_feature!(parsed_ast[:feature]) if parsed_ast[:feature]
25
+ parsed_ast['feature'] = parsed_ast.delete(:feature)
26
+
27
+ [parsed_ast]
28
+ end
29
+
30
+ # Adapts the AST sub-tree that is rooted at the given feature node.
31
+ def adapt_feature!(parsed_feature)
32
+ # Saving off the original data
33
+ parsed_feature['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_feature))
34
+
35
+ # Removing parsed data for child elements in order to avoid duplicating data
36
+ parsed_feature['cuke_modeler_parsing_data'][:tags] = nil
37
+ parsed_feature['cuke_modeler_parsing_data'][:children] = nil
38
+
39
+ parsed_feature['keyword'] = parsed_feature.delete(:keyword)
40
+ parsed_feature['name'] = parsed_feature.delete(:name)
41
+ parsed_feature['description'] = parsed_feature.delete(:description)
42
+ parsed_feature['line'] = parsed_feature.delete(:location)[:line]
43
+
44
+ parsed_feature['elements'] = []
45
+ adapt_child_elements!(parsed_feature[:children])
46
+ parsed_feature['elements'].concat(parsed_feature.delete(:children))
47
+
48
+ parsed_feature['tags'] = []
49
+ parsed_feature[:tags].each do |tag|
50
+ adapt_tag!(tag)
51
+ end
52
+ parsed_feature['tags'].concat(parsed_feature.delete(:tags))
53
+ end
54
+
55
+ # Adapts the AST sub-tree that is rooted at the given background node.
56
+ def adapt_background!(parsed_background)
57
+ # Saving off the original data
58
+ parsed_background['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_background))
59
+
60
+ # Removing parsed data for child elements in order to avoid duplicating data
61
+ parsed_background['cuke_modeler_parsing_data'][:background][:steps] = nil
62
+
63
+ parsed_background['type'] = 'Background'
64
+ parsed_background['keyword'] = parsed_background[:background].delete(:keyword)
65
+ parsed_background['name'] = parsed_background[:background].delete(:name)
66
+ parsed_background['description'] = parsed_background[:background].delete(:description)
67
+ parsed_background['line'] = parsed_background[:background].delete(:location)[:line]
68
+
69
+ parsed_background['steps'] = []
70
+ parsed_background[:background][:steps].each do |step|
71
+ adapt_step!(step)
72
+ end
73
+ parsed_background['steps'].concat(parsed_background[:background].delete(:steps))
74
+ end
75
+
76
+ # Adapts the AST sub-tree that is rooted at the given scenario node.
77
+ def adapt_scenario!(parsed_test)
78
+ # Removing parsed data for child elements in order to avoid duplicating data
79
+ parsed_test['cuke_modeler_parsing_data'][:scenario][:tags] = nil
80
+ parsed_test['cuke_modeler_parsing_data'][:scenario][:steps] = nil
81
+
82
+ parsed_test['type'] = 'Scenario'
83
+ parsed_test['keyword'] = parsed_test[:scenario].delete(:keyword)
84
+ parsed_test['name'] = parsed_test[:scenario].delete(:name)
85
+ parsed_test['description'] = parsed_test[:scenario].delete(:description)
86
+ parsed_test['line'] = parsed_test[:scenario].delete(:location)[:line]
87
+
88
+ parsed_test['tags'] = []
89
+ parsed_test[:scenario][:tags].each do |tag|
90
+ adapt_tag!(tag)
91
+ end
92
+ parsed_test['tags'].concat(parsed_test[:scenario].delete(:tags))
93
+
94
+ parsed_test['steps'] = []
95
+ parsed_test[:scenario][:steps].each do |step|
96
+ adapt_step!(step)
97
+ end
98
+ parsed_test['steps'].concat(parsed_test[:scenario].delete(:steps))
99
+ end
100
+
101
+ # Adapts the AST sub-tree that is rooted at the given outline node.
102
+ def adapt_outline!(parsed_test)
103
+ # Removing parsed data for child elements in order to avoid duplicating data
104
+ parsed_test['cuke_modeler_parsing_data'][:scenario][:tags] = nil
105
+ parsed_test['cuke_modeler_parsing_data'][:scenario][:steps] = nil
106
+ parsed_test['cuke_modeler_parsing_data'][:scenario][:examples] = nil
107
+
108
+ parsed_test['type'] = 'ScenarioOutline'
109
+ parsed_test['keyword'] = parsed_test[:scenario].delete(:keyword)
110
+ parsed_test['name'] = parsed_test[:scenario].delete(:name)
111
+ parsed_test['description'] = parsed_test[:scenario].delete(:description)
112
+ parsed_test['line'] = parsed_test[:scenario].delete(:location)[:line]
113
+
114
+ parsed_test['tags'] = []
115
+ parsed_test[:scenario][:tags].each do |tag|
116
+ adapt_tag!(tag)
117
+ end
118
+ parsed_test['tags'].concat(parsed_test[:scenario].delete(:tags))
119
+
120
+ parsed_test['steps'] = []
121
+ parsed_test[:scenario][:steps].each do |step|
122
+ adapt_step!(step)
123
+ end
124
+ parsed_test['steps'].concat(parsed_test[:scenario].delete(:steps))
125
+
126
+ parsed_test['examples'] = []
127
+ parsed_test[:scenario][:examples].each do |step|
128
+ adapt_example!(step)
129
+ end
130
+ parsed_test['examples'].concat(parsed_test[:scenario].delete(:examples))
131
+ end
132
+
133
+ # Adapts the AST sub-tree that is rooted at the given example node.
134
+ def adapt_example!(parsed_example)
135
+ # Saving off the original data
136
+ parsed_example['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_example))
137
+
138
+ # Removing parsed data for child elements in order to avoid duplicating data
139
+ parsed_example['cuke_modeler_parsing_data'][:tags] = nil
140
+ parsed_example['cuke_modeler_parsing_data'][:table_header] = nil
141
+ parsed_example['cuke_modeler_parsing_data'][:table_body] = nil
142
+
143
+ parsed_example['keyword'] = parsed_example.delete(:keyword)
144
+ parsed_example['name'] = parsed_example.delete(:name)
145
+ parsed_example['line'] = parsed_example.delete(:location)[:line]
146
+ parsed_example['description'] = parsed_example.delete(:description)
147
+
148
+ parsed_example['rows'] = []
149
+
150
+ if parsed_example[:table_header]
151
+ adapt_table_row!(parsed_example[:table_header])
152
+ parsed_example['rows'] << parsed_example.delete(:table_header)
153
+ end
154
+
155
+ if parsed_example[:table_body]
156
+
157
+ parsed_example[:table_body].each do |row|
158
+ adapt_table_row!(row)
159
+ end
160
+ parsed_example['rows'].concat(parsed_example.delete(:table_body))
161
+ end
162
+
163
+
164
+ parsed_example['tags'] = []
165
+ parsed_example[:tags].each do |tag|
166
+ adapt_tag!(tag)
167
+ end
168
+ parsed_example['tags'].concat(parsed_example.delete(:tags))
169
+ end
170
+
171
+ # Adapts the AST sub-tree that is rooted at the given tag node.
172
+ def adapt_tag!(parsed_tag)
173
+ # Saving off the original data
174
+ parsed_tag['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_tag))
175
+
176
+ parsed_tag['name'] = parsed_tag.delete(:name)
177
+ parsed_tag['line'] = parsed_tag.delete(:location)[:line]
178
+ end
179
+
180
+ # Adapts the AST sub-tree that is rooted at the given comment node.
181
+ def adapt_comment!(parsed_comment)
182
+ # Saving off the original data
183
+ parsed_comment['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_comment))
184
+
185
+ parsed_comment['text'] = parsed_comment.delete(:text)
186
+ parsed_comment['line'] = parsed_comment.delete(:location)[:line]
187
+ end
188
+
189
+ # Adapts the AST sub-tree that is rooted at the given step node.
190
+ def adapt_step!(parsed_step)
191
+ # Saving off the original data
192
+ parsed_step['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_step))
193
+
194
+ # Removing parsed data for child elements in order to avoid duplicating data
195
+ parsed_step['cuke_modeler_parsing_data'][:data_table] = nil
196
+ parsed_step['cuke_modeler_parsing_data'][:doc_string] = nil
197
+
198
+ parsed_step['keyword'] = parsed_step.delete(:keyword)
199
+ parsed_step['name'] = parsed_step.delete(:text)
200
+ parsed_step['line'] = parsed_step.delete(:location)[:line]
201
+
202
+
203
+ case
204
+ when parsed_step[:doc_string]
205
+ adapt_doc_string!(parsed_step[:doc_string])
206
+ parsed_step['doc_string'] = parsed_step.delete(:doc_string)
207
+ when parsed_step[:data_table]
208
+ adapt_step_table!(parsed_step[:data_table])
209
+ parsed_step['table'] = parsed_step.delete(:data_table)
210
+ else
211
+ # Step has no extra argument
212
+ end
213
+ end
214
+
215
+ # Adapts the AST sub-tree that is rooted at the given doc string node.
216
+ def adapt_doc_string!(parsed_doc_string)
217
+ # Saving off the original data
218
+ parsed_doc_string['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_doc_string))
219
+
220
+ parsed_doc_string['value'] = parsed_doc_string.delete(:content)
221
+ parsed_doc_string['content_type'] = parsed_doc_string.delete(:content_type).strip # TODO: fix bug in Gherkin so that this whitespace is already trimmed off
222
+ parsed_doc_string['line'] = parsed_doc_string.delete(:location)[:line]
223
+ end
224
+
225
+ # Adapts the AST sub-tree that is rooted at the given table node.
226
+ def adapt_step_table!(parsed_step_table)
227
+ # Saving off the original data
228
+ parsed_step_table['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_step_table))
229
+
230
+ # Removing parsed data for child elements in order to avoid duplicating data
231
+ parsed_step_table['cuke_modeler_parsing_data'][:rows] = nil
232
+
233
+ parsed_step_table['rows'] = []
234
+ parsed_step_table[:rows].each do |row|
235
+ adapt_table_row!(row)
236
+ end
237
+ parsed_step_table['rows'].concat(parsed_step_table.delete(:rows))
238
+ parsed_step_table['line'] = parsed_step_table.delete(:location)[:line]
239
+ end
240
+
241
+ # Adapts the AST sub-tree that is rooted at the given row node.
242
+ def adapt_table_row!(parsed_table_row)
243
+ # Saving off the original data
244
+ parsed_table_row['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_table_row))
245
+
246
+ # Removing parsed data for child elements in order to avoid duplicating data which the child elements will themselves include
247
+ parsed_table_row['cuke_modeler_parsing_data'][:cells] = nil
248
+
249
+
250
+ parsed_table_row['line'] = parsed_table_row.delete(:location)[:line]
251
+
252
+ parsed_table_row['cells'] = []
253
+ parsed_table_row[:cells].each do |row|
254
+ adapt_table_cell!(row)
255
+ end
256
+ parsed_table_row['cells'].concat(parsed_table_row.delete(:cells))
257
+ end
258
+
259
+ # Adapts the AST sub-tree that is rooted at the given cell node.
260
+ def adapt_table_cell!(parsed_cell)
261
+ # Saving off the original data
262
+ parsed_cell['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_cell))
263
+
264
+ parsed_cell['value'] = parsed_cell.delete(:value)
265
+ parsed_cell['line'] = parsed_cell.delete(:location)[:line]
266
+ end
267
+
268
+
269
+ private
270
+
271
+
272
+ def adapt_child_elements!(parsed_children)
273
+ return if parsed_children.empty?
274
+
275
+ background_child = parsed_children.find { |child| child[:background] }
276
+
277
+ if background_child
278
+ adapt_background!(background_child)
279
+
280
+ remaining_children = parsed_children.reject { |child| child[:background] }
281
+ end
282
+
283
+ adapt_tests!(remaining_children || parsed_children)
284
+ end
285
+
286
+ def adapt_tests!(parsed_tests)
287
+ return unless parsed_tests
288
+
289
+ parsed_tests.each do |test|
290
+ adapt_test!(test)
291
+ end
292
+ end
293
+
294
+ def adapt_test!(parsed_test)
295
+ # Saving off the original data
296
+ parsed_test['cuke_modeler_parsing_data'] = Marshal::load(Marshal.dump(parsed_test))
297
+
298
+
299
+ case
300
+ when parsed_test[:scenario] && parsed_test[:scenario][:examples].any?
301
+ adapt_outline!(parsed_test)
302
+ when parsed_test[:scenario]
303
+ adapt_scenario!(parsed_test)
304
+ else
305
+ raise(ArgumentError, "Unknown test type with keys: #{parsed_test.keys}")
306
+ end
307
+ end
308
+
309
+ end
310
+ end