cucumber-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.travis.yml +16 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE +20 -0
  8. data/README.md +9 -0
  9. data/Rakefile +24 -0
  10. data/cucumber-core.gemspec +32 -0
  11. data/lib/cucumber/core.rb +37 -0
  12. data/lib/cucumber/core/ast.rb +13 -0
  13. data/lib/cucumber/core/ast/background.rb +33 -0
  14. data/lib/cucumber/core/ast/comment.rb +17 -0
  15. data/lib/cucumber/core/ast/data_table.rb +326 -0
  16. data/lib/cucumber/core/ast/describes_itself.rb +16 -0
  17. data/lib/cucumber/core/ast/doc_string.rb +83 -0
  18. data/lib/cucumber/core/ast/empty_background.rb +12 -0
  19. data/lib/cucumber/core/ast/examples_table.rb +95 -0
  20. data/lib/cucumber/core/ast/feature.rb +62 -0
  21. data/lib/cucumber/core/ast/location.rb +140 -0
  22. data/lib/cucumber/core/ast/multiline_argument.rb +33 -0
  23. data/lib/cucumber/core/ast/names.rb +19 -0
  24. data/lib/cucumber/core/ast/outline_step.rb +51 -0
  25. data/lib/cucumber/core/ast/scenario.rb +43 -0
  26. data/lib/cucumber/core/ast/scenario_outline.rb +44 -0
  27. data/lib/cucumber/core/ast/step.rb +38 -0
  28. data/lib/cucumber/core/ast/tag.rb +14 -0
  29. data/lib/cucumber/core/compiler.rb +136 -0
  30. data/lib/cucumber/core/gherkin/ast_builder.rb +315 -0
  31. data/lib/cucumber/core/gherkin/document.rb +20 -0
  32. data/lib/cucumber/core/gherkin/parser.rb +45 -0
  33. data/lib/cucumber/core/gherkin/writer.rb +220 -0
  34. data/lib/cucumber/core/gherkin/writer/helpers.rb +178 -0
  35. data/lib/cucumber/core/platform.rb +30 -0
  36. data/lib/cucumber/core/test/case.rb +143 -0
  37. data/lib/cucumber/core/test/filters.rb +48 -0
  38. data/lib/cucumber/core/test/filters/tag_filter.rb +110 -0
  39. data/lib/cucumber/core/test/hook_compiler.rb +109 -0
  40. data/lib/cucumber/core/test/mapper.rb +56 -0
  41. data/lib/cucumber/core/test/mapping.rb +67 -0
  42. data/lib/cucumber/core/test/result.rb +191 -0
  43. data/lib/cucumber/core/test/runner.rb +149 -0
  44. data/lib/cucumber/core/test/step.rb +69 -0
  45. data/lib/cucumber/core/test/timer.rb +31 -0
  46. data/lib/cucumber/core/version.rb +9 -0
  47. data/lib/cucumber/initializer.rb +18 -0
  48. data/spec/capture_warnings.rb +68 -0
  49. data/spec/coverage.rb +10 -0
  50. data/spec/cucumber/core/ast/data_table_spec.rb +139 -0
  51. data/spec/cucumber/core/ast/doc_string_spec.rb +77 -0
  52. data/spec/cucumber/core/ast/examples_table_spec.rb +87 -0
  53. data/spec/cucumber/core/ast/location_spec.rb +105 -0
  54. data/spec/cucumber/core/ast/outline_step_spec.rb +77 -0
  55. data/spec/cucumber/core/ast/step_spec.rb +44 -0
  56. data/spec/cucumber/core/compiler_spec.rb +249 -0
  57. data/spec/cucumber/core/gherkin/parser_spec.rb +182 -0
  58. data/spec/cucumber/core/gherkin/writer_spec.rb +332 -0
  59. data/spec/cucumber/core/test/case_spec.rb +416 -0
  60. data/spec/cucumber/core/test/hook_compiler_spec.rb +78 -0
  61. data/spec/cucumber/core/test/mapper_spec.rb +68 -0
  62. data/spec/cucumber/core/test/mapping_spec.rb +103 -0
  63. data/spec/cucumber/core/test/result_spec.rb +178 -0
  64. data/spec/cucumber/core/test/runner_spec.rb +265 -0
  65. data/spec/cucumber/core/test/step_spec.rb +58 -0
  66. data/spec/cucumber/core/test/timer_spec.rb +13 -0
  67. data/spec/cucumber/core_spec.rb +419 -0
  68. data/spec/cucumber/initializer_spec.rb +49 -0
  69. metadata +221 -0
@@ -0,0 +1,105 @@
1
+ require 'cucumber/core/ast/location'
2
+
3
+ module Cucumber::Core::Ast
4
+ describe Location do
5
+ let(:line) { 12 }
6
+ let(:file) { "foo.feature" }
7
+
8
+ describe "equality" do
9
+ it "is equal to another Location on the same line of the same file" do
10
+ one_location = Location.new(file, line)
11
+ another_location = Location.new(file, line)
12
+ expect( one_location ).to eq another_location
13
+ end
14
+
15
+ it "is not equal to a wild card of the same file" do
16
+ expect( Location.new(file, line) ).not_to eq Location.new(file)
17
+ end
18
+ end
19
+
20
+ describe "to_s" do
21
+ it "is file:line for a precise location" do
22
+ expect( Location.new("foo.feature", 12).to_s ).to eq "foo.feature:12"
23
+ end
24
+
25
+ it "is file for a wildcard location" do
26
+ expect( Location.new("foo.feature").to_s ).to eq "foo.feature"
27
+ end
28
+
29
+ it "is file:first_line..last_line for a ranged location" do
30
+ expect( Location.new("foo.feature", 13..19).to_s ).to eq "foo.feature:13..19"
31
+ end
32
+ end
33
+
34
+ describe "matches" do
35
+ let(:matching) { Location.new(file, line) }
36
+ let(:same_file_other_line) { Location.new(file, double) }
37
+ let(:not_matching) { Location.new(other_file, line) }
38
+ let(:other_file) { double }
39
+
40
+ context 'a precise location' do
41
+ let(:precise) { Location.new(file, line) }
42
+
43
+ it "matches a precise location of the same file and line" do
44
+ expect( matching ).to be_match(precise)
45
+ end
46
+
47
+ it "does not match a precise location on a differnt line in the same file" do
48
+ expect( matching ).not_to be_match(same_file_other_line)
49
+ end
50
+
51
+ end
52
+
53
+ context 'a wildcard' do
54
+ let(:wildcard) { Location.new(file) }
55
+
56
+ it "matches any location with the same filename" do
57
+ expect( wildcard ).to be_match(matching)
58
+ end
59
+
60
+ it "is matched by any location of the same file" do
61
+ expect( matching ).to be_match(wildcard)
62
+ end
63
+
64
+ it "does not match a location in a different file" do
65
+ expect( wildcard ).not_to be_match(not_matching)
66
+ end
67
+ end
68
+
69
+ context 'a range wildcard' do
70
+ let(:range) { Location.new("foo.feature", 13..17) }
71
+
72
+ it "matches the first line in the same file" do
73
+ other = Location.new("foo.feature", 13)
74
+ expect( range ).to be_match(other)
75
+ end
76
+
77
+ it "matches a line within the docstring in the same file" do
78
+ other = Location.new("foo.feature", 15)
79
+ expect( range ).to be_match(other)
80
+ end
81
+
82
+ it "is matched by a line within the docstring in the same file" do
83
+ other = Location.new("foo.feature", 15)
84
+ expect( other ).to be_match(range)
85
+ end
86
+
87
+ it "matches a wildcard in the same file" do
88
+ wildcard = Location.new("foo.feature")
89
+ expect( range ).to be_match(wildcard)
90
+ end
91
+
92
+ it "does not match a location outside of the range" do
93
+ other = Location.new("foo.feature", 18)
94
+ expect( range ).not_to be_match(other)
95
+ end
96
+
97
+ it "does not match a location in another file" do
98
+ other = Location.new("bar.feature", 13)
99
+ expect( range ).not_to be_match(other)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+
@@ -0,0 +1,77 @@
1
+ require 'cucumber/core/ast/outline_step'
2
+ require 'cucumber/core/ast/examples_table'
3
+ require 'cucumber/core/ast/data_table'
4
+ require 'cucumber/core/ast/doc_string'
5
+
6
+ module Cucumber
7
+ module Core
8
+ module Ast
9
+ describe OutlineStep do
10
+ let(:outline_step) { OutlineStep.new(language, location, keyword, name) }
11
+ let(:language) { double }
12
+ let(:location) { double }
13
+ let(:keyword) { double }
14
+ let(:name) { 'anything' }
15
+
16
+ describe 'location' do
17
+ it "has a location" do
18
+ expect( outline_step ).to respond_to(:location)
19
+ end
20
+
21
+ it 'knows the file and line' do
22
+ location.stub(:to_s) { 'file_name:8' }
23
+ expect( outline_step.file_colon_line ).to eq 'file_name:8'
24
+ end
25
+ end
26
+
27
+ describe "converting to a Step" do
28
+ context "a single argument in the name" do
29
+ let(:name) { 'a <color> cucumber' }
30
+
31
+ it "replaces the argument" do
32
+ row = ExamplesTable::Row.new({'color' => 'green'}, 1, location)
33
+ expect( outline_step.to_step(row).name ).to eq 'a green cucumber'
34
+ end
35
+
36
+ end
37
+
38
+ context "when the step has a DataTable" do
39
+ let(:outline_step) { OutlineStep.new(language, location, keyword, name, table) }
40
+ let(:name) { "anything" }
41
+ let(:table) { DataTable.new([['x', 'y'],['a', 'a <arg>']], Location.new('foo.feature', 23)) }
42
+
43
+ it "replaces the arguments in the DataTable" do
44
+ visitor = double
45
+ visitor.stub(:step).and_yield
46
+ expect( visitor ).to receive(:table) do |data_table| # TODO: rename this message to :data_table
47
+ expect( data_table.raw ).to eq [['x', 'y'], ['a', 'a replacement']]
48
+ end
49
+ row = ExamplesTable::Row.new({'arg' => 'replacement'}, 1, location)
50
+ step = outline_step.to_step(row)
51
+ step.describe_to(visitor)
52
+ end
53
+ end
54
+
55
+ context "when the step has a DocString" do
56
+ let(:location) { double }
57
+ let(:outline_step) { OutlineStep.new(language, location, keyword, name, doc_string) }
58
+ let(:doc_string) { DocString.new('a <arg> that needs replacing', '', location) }
59
+ let(:name) { 'anything' }
60
+
61
+ it "replaces the arguments in the DocString" do
62
+ visitor = double
63
+ visitor.stub(:step).and_yield
64
+ expect( visitor ).to receive(:doc_string) do |doc_string|
65
+ expect( doc_string.content ).to eq "a replacement that needs replacing"
66
+ end
67
+ row = ExamplesTable::Row.new({'arg' => 'replacement'}, 1, location)
68
+ step = outline_step.to_step(row)
69
+ step.describe_to(visitor)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+
@@ -0,0 +1,44 @@
1
+ require 'cucumber/core/ast/step'
2
+
3
+ module Cucumber
4
+ module Core
5
+ module Ast
6
+ describe Step do
7
+ let(:step) do
8
+ language, location, keyword, name = double, double, double, double
9
+ Step.new(language, location, keyword, name)
10
+ end
11
+
12
+ describe "describing itself" do
13
+ let(:visitor) { double }
14
+
15
+ it "describes itself as a step" do
16
+ expect( visitor ).to receive(:step).with(step)
17
+ step.describe_to(visitor)
18
+ end
19
+
20
+ context "with no multiline argument" do
21
+ it "does not try to describe any children" do
22
+ visitor.stub(:step).with(step).and_yield
23
+ step.describe_to(visitor)
24
+ end
25
+ end
26
+
27
+ context "with a multiline argument" do
28
+ let(:step) { Step.new(double, double, double, double, multiline_arg) }
29
+ let(:multiline_arg) { double }
30
+
31
+ it "tells its multiline argument to describe itself" do
32
+ visitor.stub(:step).with(step).and_yield
33
+ expect( multiline_arg ).to receive(:describe_to).with(visitor)
34
+ step.describe_to(visitor)
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -0,0 +1,249 @@
1
+ require 'cucumber/core'
2
+ require 'cucumber/core/compiler'
3
+ require 'cucumber/core/gherkin/writer'
4
+
5
+ module Cucumber::Core
6
+ describe Compiler do
7
+ include Gherkin::Writer
8
+ include Cucumber::Core
9
+
10
+ def self.stubs(*names)
11
+ names.each do |name|
12
+ let(name) { double(name.to_s) }
13
+ end
14
+ end
15
+
16
+ it "compiles a feature with a single scenario" do
17
+ gherkin_documents = [
18
+ gherkin do
19
+ feature do
20
+ scenario do
21
+ step 'passing'
22
+ end
23
+ end
24
+ end
25
+ ]
26
+ compile(gherkin_documents) do |visitor|
27
+ expect( visitor ).to receive(:test_case).once.ordered.and_yield
28
+ expect( visitor ).to receive(:test_step).once.ordered
29
+ expect( visitor ).to receive(:done).once.ordered
30
+ end
31
+ end
32
+
33
+ it "compiles a feature with a background" do
34
+ gherkin_documents = [
35
+ gherkin do
36
+ feature do
37
+ background do
38
+ step 'passing'
39
+ end
40
+
41
+ scenario do
42
+ step 'passing'
43
+ end
44
+ end
45
+ end
46
+ ]
47
+ compile(gherkin_documents) do |visitor|
48
+ expect( visitor ).to receive(:test_case).once.ordered.and_yield
49
+ expect( visitor ).to receive(:test_step).exactly(2).times.ordered
50
+ expect( visitor ).to receive(:done).once.ordered
51
+ end
52
+ end
53
+
54
+ it "compiles multiple features" do
55
+ gherkin_documents = [
56
+ gherkin do
57
+ feature do
58
+ background do
59
+ step 'passing'
60
+ end
61
+ scenario do
62
+ step 'passing'
63
+ end
64
+ end
65
+ end,
66
+ gherkin do
67
+ feature do
68
+ background do
69
+ step 'passing'
70
+ end
71
+ scenario do
72
+ step 'passing'
73
+ end
74
+ end
75
+ end
76
+ ]
77
+ compile(gherkin_documents) do |visitor|
78
+ expect( visitor ).to receive(:test_case).once.ordered
79
+ expect( visitor ).to receive(:test_step).twice.ordered
80
+ expect( visitor ).to receive(:test_case).once.ordered
81
+ expect( visitor ).to receive(:test_step).twice.ordered
82
+ expect( visitor ).to receive(:done).once
83
+ end
84
+ end
85
+
86
+ context "compiling scenario outlines" do
87
+ it "compiles a scenario outline to test cases" do
88
+ gherkin_documents = [
89
+ gherkin do
90
+ feature do
91
+ background do
92
+ step 'passing'
93
+ end
94
+
95
+ scenario_outline do
96
+ step 'passing <arg>'
97
+ step 'passing'
98
+
99
+ examples 'examples 1' do
100
+ row 'arg'
101
+ row '1'
102
+ row '2'
103
+ end
104
+
105
+ examples 'examples 2' do
106
+ row 'arg'
107
+ row 'a'
108
+ end
109
+ end
110
+ end
111
+ end
112
+ ]
113
+ compile(gherkin_documents) do |visitor|
114
+ expect( visitor ).to receive(:test_case).exactly(3).times.and_yield
115
+ expect( visitor ).to receive(:test_step).exactly(9).times
116
+ expect( visitor ).to receive(:done).once
117
+ end
118
+ end
119
+
120
+ it 'replaces arguments correctly when generating test steps' do
121
+ gherkin_documents = [
122
+ gherkin do
123
+ feature do
124
+ scenario_outline do
125
+ step 'passing <arg1> with <arg2>'
126
+ step 'as well as <arg3>'
127
+
128
+ examples do
129
+ row 'arg1', 'arg2', 'arg3'
130
+ row '1', '2', '3'
131
+ end
132
+ end
133
+ end
134
+ end
135
+ ]
136
+
137
+ compile(gherkin_documents) do |visitor|
138
+ expect( visitor ).to receive(:test_step) do |test_step|
139
+ visit_source(test_step) do |source_visitor|
140
+ expect( source_visitor ).to receive(:step) do |step|
141
+ expect(step.name).to eq 'passing 1 with 2'
142
+ end
143
+ end
144
+ end.once.ordered
145
+
146
+ expect( visitor ).to receive(:test_step) do |test_step|
147
+ visit_source(test_step) do |source_visitor|
148
+ expect( source_visitor ).to receive(:step) do |step|
149
+ expect(step.name).to eq 'as well as 3'
150
+ end
151
+ end
152
+ end.once.ordered
153
+
154
+ expect( visitor ).to receive(:done).once.ordered
155
+ end
156
+ end
157
+ end
158
+
159
+ describe Compiler::FeatureCompiler do
160
+ let(:receiver) { double('receiver') }
161
+ let(:compiler) { Compiler::FeatureCompiler.new(receiver) }
162
+
163
+ context "a scenario with a background" do
164
+ stubs(:feature,
165
+ :background,
166
+ :background_step,
167
+ :scenario,
168
+ :scenario_step)
169
+
170
+ it "sets the source correctly on the test steps" do
171
+ expect( receiver ).to receive(:on_background_step).with(
172
+ [feature, background, background_step]
173
+ )
174
+ expect( receiver ).to receive(:on_step).with(
175
+ [feature, scenario, scenario_step]
176
+ )
177
+ expect( receiver ).to receive(:on_test_case).with(
178
+ [feature, scenario]
179
+ )
180
+ compiler.feature(feature) do |f|
181
+ f.background(background) do |b|
182
+ b.step background_step
183
+ end
184
+ f.scenario(scenario) do |s|
185
+ s.step scenario_step
186
+ end
187
+ end
188
+ end
189
+ end
190
+
191
+ context "a scenario outline" do
192
+ stubs(:feature,
193
+ :background,
194
+ :background_step,
195
+ :scenario_outline,
196
+ :outline_step,
197
+ :examples_table_1,
198
+ :examples_table_1_row_1,
199
+ :outline_ast_step,
200
+ :examples_table_2,
201
+ :examples_table_2_row_1,
202
+ )
203
+
204
+ it "sets the source correctly on the test steps" do
205
+ outline_step.stub(to_step: outline_ast_step)
206
+ expect( receiver ).to receive(:on_step).with(
207
+ [feature, scenario_outline, examples_table_1, examples_table_1_row_1, outline_ast_step]
208
+ ).ordered
209
+ expect( receiver ).to receive(:on_test_case).with(
210
+ [feature, scenario_outline, examples_table_1, examples_table_1_row_1]
211
+ ).ordered
212
+ expect( receiver ).to receive(:on_step).with(
213
+ [feature, scenario_outline, examples_table_2, examples_table_2_row_1, outline_ast_step]
214
+ ).ordered
215
+ expect( receiver ).to receive(:on_test_case).with(
216
+ [feature, scenario_outline, examples_table_2, examples_table_2_row_1]
217
+ ).ordered
218
+ compiler.feature(feature) do |f|
219
+ f.scenario_outline(scenario_outline) do |o|
220
+ o.outline_step outline_step
221
+ o.examples_table(examples_table_1) do |t|
222
+ t.examples_table_row(examples_table_1_row_1)
223
+ end
224
+ o.examples_table(examples_table_2) do |t|
225
+ t.examples_table_row(examples_table_2_row_1)
226
+ end
227
+ end
228
+ end
229
+ end
230
+ end
231
+ end
232
+
233
+ def visit_source(node)
234
+ visitor = double.as_null_object
235
+ yield visitor
236
+ node.describe_source_to(visitor)
237
+ end
238
+
239
+ def compile(gherkin_documents)
240
+ visitor = double
241
+ visitor.stub(:test_suite).and_yield
242
+ visitor.stub(:test_case).and_yield
243
+ yield visitor
244
+ super(gherkin_documents, visitor)
245
+ end
246
+
247
+ end
248
+ end
249
+