cukedep 0.0.8 → 0.1.03

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 (36) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG.md +26 -0
  3. data/bin/cukedep +1 -1
  4. data/lib/cukedep/application.rb +7 -7
  5. data/lib/cukedep/config.rb +64 -7
  6. data/lib/cukedep/constants.rb +5 -1
  7. data/lib/cukedep/cuke-runner.rb +202 -0
  8. data/lib/cukedep/customization.rb +35 -0
  9. data/lib/cukedep/feature-rep.rb +2 -2
  10. data/lib/cukedep/file-action.rb +211 -0
  11. data/lib/cukedep/hook-dsl.rb +80 -0
  12. data/lib/cukedep/sandbox.rb +21 -0
  13. data/sample/cucumber.yml +4 -0
  14. data/sample/model/catalogue.yml +13 -0
  15. data/sample/model/members.yml +13 -0
  16. data/sample/model/model.rb +2 -2
  17. data/sample/model/rentals.yml +4 -0
  18. data/sample/model/users.yml +7 -0
  19. data/sample/result.html +472 -0
  20. data/spec/cukedep/application_spec.rb +8 -8
  21. data/spec/cukedep/cuke-runner_spec.rb +80 -0
  22. data/spec/cukedep/customization_spec.rb +36 -0
  23. data/spec/cukedep/file-action_spec.rb +374 -0
  24. data/spec/cukedep/gherkin-facade_spec.rb +54 -0
  25. data/spec/cukedep/hook-dsl_spec.rb +185 -0
  26. data/spec/cukedep/sample_features/cukedep.rake +204 -0
  27. data/spec/cukedep/sample_features/cukedep_hooks.rb +30 -0
  28. data/spec/cukedep/sample_features/dependencies.dot +38 -0
  29. data/spec/cukedep/sample_features/feature2id.csv +7 -0
  30. data/spec/cukedep/sample_features/files_to_copy/README.md +12 -0
  31. data/spec/cukedep/sample_features/files_to_copy/file1.txt +5 -0
  32. data/spec/cukedep/sample_features/files_to_copy/file2.txt +5 -0
  33. data/spec/cukedep/sample_features/files_to_copy/file3.txt +9 -0
  34. data/spec/spec_helper.rb +1 -0
  35. data/templates/rake.erb +184 -160
  36. metadata +26 -2
@@ -0,0 +1,54 @@
1
+ # File: file-actions_spec.rb
2
+
3
+ require_relative '../spec_helper'
4
+
5
+ # Load the class under testing
6
+ require_relative '../../lib/cukedep/gherkin-facade'
7
+ require_relative '../../lib/cukedep/gherkin-listener'
8
+
9
+ module Cukedep # Open module to get rid of long qualified names
10
+
11
+ describe GherkinFacade do
12
+ subject { GherkinFacade.new(false, 'UTF-8') }
13
+
14
+ context 'Creation & initialization:' do
15
+ it 'should be created with two arguments' do
16
+ expect { GherkinFacade.new(true, 'UTF-8') }.not_to raise_error
17
+ end
18
+
19
+ it 'should whether it is verbose or not' do
20
+ # Case 1: instance is verbose
21
+ expect(subject.verbose).to be_false
22
+
23
+ # Case 2: instance is silent
24
+ instance = GherkinFacade.new(true, 'UTF-8')
25
+ expect(instance.verbose).to be_true
26
+ end
27
+
28
+ it 'should know the feature file external encoding' do
29
+ expect(subject.external_encoding).to eq('UTF-8')
30
+ end
31
+
32
+ end # context
33
+
34
+
35
+
36
+ context 'Provided services:' do
37
+ let(:listener) { GherkinListener.new }
38
+ it 'should parse ASCII feature files' do
39
+ instance = GherkinFacade.new(false, 'US-ASCII')
40
+ patterns = [ 'sample_features/a_few_tests.feature' ]
41
+ expect {instance.parse_features(listener, patterns)}.not_to raise_error
42
+ end
43
+
44
+ it 'should parse feature files with other external encoding' do
45
+ patterns = [ 'sample_features/standalone.feature' ]
46
+ expect {subject.parse_features(listener, patterns)}.not_to raise_error
47
+ end
48
+ end # context
49
+
50
+ end # describe
51
+
52
+ end # module
53
+
54
+ # End of file
@@ -0,0 +1,185 @@
1
+ # File: file-action_spec.rb
2
+
3
+ require 'stringio'
4
+ require_relative '../spec_helper'
5
+
6
+ # Load the class under testing
7
+ require_relative '../../lib/cukedep/hook-dsl'
8
+
9
+ module Cukedep # Open module to get rid of long qualified names
10
+
11
+ # Let's specify the behaviour of the mix-in module
12
+ describe HookDSL do
13
+
14
+ subject do
15
+ obj = Object.new
16
+ obj.extend(HookDSL)
17
+ obj
18
+ end
19
+
20
+ context 'Hook definitions:' do
21
+ let(:code_block) do
22
+ -> { ; }
23
+ end
24
+
25
+ it 'should accept the before all hook' do
26
+ # Case 1: before all with block code
27
+ expect { subject.before_cuke(:all, &code_block) }.not_to raise_error
28
+
29
+ # Case 2: before all without block code
30
+ expect { subject.before_cuke(:all) }.not_to raise_error
31
+ end
32
+
33
+ it 'should accept the before each hook' do
34
+ # Case 1: before each with block code
35
+ expect { subject.before_cuke(:each, &code_block) }.not_to raise_error
36
+
37
+ # Case 2: before each without block code
38
+ expect { subject.before_cuke(:each) }.not_to raise_error
39
+ end
40
+
41
+
42
+ it 'should accept the after all hook' do
43
+ # Case 1: after all with block code
44
+ expect { subject.after_cuke(:all, &code_block) }.not_to raise_error
45
+
46
+ # Case 2: before all without block code
47
+ expect { subject.after_cuke(:all) }.not_to raise_error
48
+ end
49
+
50
+ it 'should accept the after each hook' do
51
+ # Case 1: after each with block code
52
+ expect { subject.after_cuke(:each, &code_block) }.not_to raise_error
53
+
54
+ # Case 2: after each without block code
55
+ expect { subject.after_cuke(:each) }.not_to raise_error
56
+ end
57
+
58
+ it 'should reject invalid scope argument' do
59
+ # Case 1: before invalid with block code
60
+ msg = "Unknown scope 'invalid' for before_cuke hook."
61
+ error = StandardError
62
+ expect { subject.before_cuke(:invalid, &code_block) }.to raise_error(error, msg)
63
+
64
+ # Case 2: after invalid with block code
65
+ msg = "Unknown scope 'invalid' for after_cuke hook."
66
+ expect { subject.after_cuke(:invalid, &code_block) }.to raise_error(error, msg)
67
+ end
68
+
69
+
70
+ it 'should register the block code with the event' do
71
+ # No block code registered yet.
72
+ expect(subject.instance_variables).not_to include(:@before_hooks)
73
+
74
+ # Case 1: No before all handler provided
75
+ subject.before_cuke(:all)
76
+ expect(subject.instance_variables).not_to include(:@before_hooks)
77
+
78
+ # Case 1: Add before all handler
79
+ subject.before_cuke(:all, &code_block)
80
+
81
+ # Check that handler code is stored in instance variable
82
+ expect(subject.instance_variables).to include(:@before_hooks)
83
+ expect(subject.before_hooks.keys).to eq([:all])
84
+ expect(subject.before_hooks[:all]).to eq(code_block)
85
+
86
+ # Case 2: No before each handler provided
87
+ subject.before_cuke(:each)
88
+ expect(subject.before_hooks.keys).to eq([:all])
89
+
90
+ # Case 3: Add before each handler
91
+ subject.before_cuke(:each, &code_block)
92
+
93
+ # Check that handler code is stored in instance variable
94
+ expect(subject.before_hooks.keys).to eq([:all, :each])
95
+ expect(subject.before_hooks[:each]).to eq(code_block)
96
+
97
+
98
+ # Case 4: No after all handler provided
99
+ subject.after_cuke(:all)
100
+ expect(subject.instance_variables).not_to include(:@after_hooks)
101
+
102
+ # Case 5: Add after all handler
103
+ subject.after_cuke(:all, &code_block)
104
+
105
+ # Check that handler code is stored in instance variable
106
+ expect(subject.instance_variables).to include(:@after_hooks)
107
+ expect(subject.after_hooks.keys).to eq([:all])
108
+ expect(subject.after_hooks[:all]).to eq(code_block)
109
+
110
+ # Case 6: No after each handler provided
111
+ subject.after_cuke(:each)
112
+ expect(subject.after_hooks.keys).to eq([:all])
113
+
114
+ # Case 7: Add after each handler
115
+ subject.after_cuke(:each, &code_block)
116
+
117
+ # Check that handler code is stored in instance variable
118
+ expect(subject.after_hooks.keys).to eq([:all, :each])
119
+ expect(subject.after_hooks[:each]).to eq(code_block)
120
+ end
121
+
122
+ end # context
123
+ =begin
124
+ context 'Executing handler code:' do
125
+ let(:ostream) { StringIO.new('', 'w') }
126
+
127
+ it 'should ignore missing handler' do
128
+ expect { subject.execute_hook(:before, :all) }.not_to raise_error
129
+ end
130
+
131
+ it 'should execute the before all handler' do
132
+ text = 'before all'
133
+ # Let's create the hook
134
+ subject.before_cuke(:all) { ostream.print text }
135
+
136
+ # Let's execute it...
137
+ subject.execute_hook(:before, :all)
138
+
139
+ expect(ostream.string).to eq(text)
140
+ end
141
+
142
+
143
+ it 'should execute the before all handler' do
144
+ text = 'before each'
145
+ # Let's create the hook
146
+ subject.before_cuke(:each) { ostream.print text }
147
+
148
+ # Let's execute it...
149
+ subject.execute_hook(:before, :each)
150
+
151
+ expect(ostream.string).to eq(text)
152
+ end
153
+
154
+
155
+ it 'should execute the after all handler' do
156
+ text = 'after all'
157
+ # Let's create the hook
158
+ subject.after_cuke(:all) { ostream.print text }
159
+
160
+ # Let's execute it...
161
+ subject.execute_hook(:after, :all)
162
+
163
+ expect(ostream.string).to eq(text)
164
+ end
165
+
166
+
167
+ it 'should execute the after each handler' do
168
+ text = 'after each'
169
+ # Let's create the hook
170
+ subject.after_cuke(:each) { ostream.print text }
171
+
172
+ # Let's execute it...
173
+ subject.execute_hook(:after, :each)
174
+
175
+ expect(ostream.string).to eq(text)
176
+ end
177
+
178
+ end # context
179
+ =end
180
+
181
+ end # describe
182
+
183
+ end # module
184
+
185
+ # End of file
@@ -0,0 +1,204 @@
1
+ # File: cukedep.rake
2
+ # Generated by Cukedep 0.1.01 on 27/11/2013 23:12:50
3
+
4
+ require 'rake'
5
+ require 'cukedep/file-action'
6
+
7
+ # Run Cucumber via specialized Rake task
8
+ require 'cucumber/rake/task'
9
+ # UGLY workaround for bug in Cucumber's rake task
10
+ if Gem::VERSION[0].to_i >= 2 && Cucumber::VERSION <= '1.3.2'
11
+ # Monkey-patch a buggy method
12
+ class Cucumber::Rake::Task::ForkedCucumberRunner
13
+ def gem_available?(gemname)
14
+ if Gem::VERSION[0].to_i >= 2
15
+ gem_available_new_rubygems?(gemname)
16
+ else
17
+ gem_available_old_rubygems?(gemname)
18
+ end
19
+ end
20
+ end # class
21
+ end
22
+
23
+ # Create a task called cucumber
24
+ Cucumber::Rake::Task.new do |t|
25
+ end
26
+
27
+ #######################################
28
+ # Retrieving state at end of Cukedep::Application#run! method
29
+ #######################################
30
+
31
+ # Constant holding the location of the original feature files
32
+ SOURCE_DIR = 'C:/Ruby193/lib/ruby/site_ruby/Cukedep/spec/cukedep/sample_features'
33
+
34
+ # Constant holding the location of the Cucumber project
35
+ CUKE_PROJECT = 'C:/Ruby193/lib/ruby/site_ruby/Cukedep/sample'
36
+
37
+ # The list of all "legacy" feature file (feature files without the @feature: tag)
38
+ AllUnidentifiedFeatures = [
39
+ 'standalone.feature'
40
+ ]
41
+
42
+ # The list of all encountered feature ids
43
+ AllFeatureIdentifiers = [
44
+ :qux,
45
+ :quux,
46
+ :corge,
47
+ :foo,
48
+ :baz,
49
+ :bar
50
+ ]
51
+
52
+
53
+ def run_builtin_actions(anEvent)
54
+ actions = Cukedep::ActionTriplet.builtin(anEvent)
55
+ actions.run!(SOURCE_DIR, CUKE_PROJECT) unless actions.nil?
56
+ end
57
+
58
+ # Helper method. Calculate the filepath of a file with given name
59
+ # if it is located in the source dir.
60
+ def source_path_of(aFilename)
61
+ SOURCE_DIR + '/' + aFilename
62
+ end
63
+
64
+ # Helper method. Calculate the filepath of a file with given name
65
+ # if it is located in the project features dir.
66
+ def project_path_of(aFilename)
67
+ CUKE_PROJECT + '/features/' + aFilename
68
+ end
69
+
70
+ # Helper method. Given the name of files in the source dir, copy them
71
+ # into the project dir.
72
+ def copy_to_project(filenames)
73
+ filenames.each do |fname|
74
+ source_path = source_path_of(fname)
75
+ dest_path = project_path_of(fname)
76
+ FileUtils.copy_file(source_path, dest_path)
77
+ end
78
+ end
79
+
80
+
81
+ # Helper method. Given the name of files in the features dir of the project,
82
+ # copy them into the source dir.
83
+ def copy_from_project(*filenames)
84
+ filenames.each do |fname|
85
+ source_path = project_path_of(fname)
86
+ dest_path = source_path_of(fname)
87
+ FileUtils.copy_file(source_path, dest_path)
88
+ end
89
+ end
90
+
91
+ # Helper method. Delete all the files in the
92
+ # the project's features dir that match one of
93
+ # the file name pattern
94
+ def clean_project_dir(fname_patterns)
95
+ curr_dir = Dir.getwd()
96
+ begin
97
+ Dir.chdir(CUKE_PROJECT + '/features')
98
+ fname_patterns.each do |patt|
99
+ filenames = Dir.glob(patt)
100
+ filenames.each { |fn| FileUtils.remove_file(fn) }
101
+ end
102
+ ensure #Always restore previous working dir.
103
+ Dir.chdir(curr_dir)
104
+ end
105
+ end
106
+
107
+
108
+ # Helper method. Invoke Cucumber with the given project root dir.
109
+ # Assumption: all features files to execute are placed
110
+ # in the appropriate folder.
111
+ def invoke_cuke(projectDir)
112
+ curr_dir = Dir.getwd()
113
+ Dir.chdir(projectDir)
114
+ begin
115
+ do_cuke = Rake::Task[:cucumber]
116
+ do_cuke.reenable
117
+ do_cuke.invoke
118
+ ensure
119
+ Dir.chdir(curr_dir)
120
+ end
121
+ end
122
+
123
+
124
+ def process_files(filenames)
125
+ run_builtin_actions(:before_each)
126
+ copy_to_project(filenames)
127
+ invoke_cuke(CUKE_PROJECT)
128
+ run_builtin_actions(:after_each)
129
+ #del_from_project(filenames)
130
+ end
131
+
132
+ def process_a_feature(filename)
133
+ process_files([filename])
134
+ end
135
+
136
+
137
+ # Default rake task is also top-level task
138
+ task :default => :run_all_features
139
+
140
+
141
+ desc 'Run all features'
142
+ task :run_all_features => [:before_all, :all_features, :after_all] do
143
+ ; # Do nothing
144
+ end
145
+
146
+
147
+ desc 'Before all'
148
+ task :before_all do
149
+ run_builtin_actions(:before_all)
150
+ end
151
+
152
+ desc 'After_all'
153
+ task :after_all do
154
+ run_builtin_actions(:after_all)
155
+ end
156
+
157
+
158
+ task :unidentified do
159
+ process_files(AllUnidentifiedFeatures)
160
+ end
161
+
162
+ # Tasks for feature files involved in dependencies
163
+
164
+
165
+ desc "qux: run a_few_tests.feature"
166
+ task :qux do
167
+ process_a_feature('a_few_tests.feature')
168
+ end
169
+
170
+
171
+ desc "quux: run more_tests.feature"
172
+ task :quux do
173
+ process_a_feature('more_tests.feature')
174
+ end
175
+
176
+
177
+ desc "corge: run other_tests.feature"
178
+ task :corge => [:foo] do
179
+ process_a_feature('other_tests.feature')
180
+ end
181
+
182
+
183
+ desc "foo: run some_tests.feature"
184
+ task :foo => [:bar, :qux] do
185
+ process_a_feature('some_tests.feature')
186
+ end
187
+
188
+
189
+ desc "baz: run still_other_tests.feature"
190
+ task :baz do
191
+ process_a_feature('still_other_tests.feature')
192
+ end
193
+
194
+
195
+ desc "bar: run yet_other_tests.feature"
196
+ task :bar => [:baz, :qux, :quux] do
197
+ process_a_feature('yet_other_tests.feature')
198
+ end
199
+
200
+
201
+ task :all_features => ([:unidentified] + AllFeatureIdentifiers) do
202
+ end
203
+
204
+ # End of file
@@ -0,0 +1,30 @@
1
+ # File: cukedep_hooks.rb
2
+ # This Ruby file specifies the custom code
3
+ # associated with Cukedep hooks.
4
+
5
+ # The code block will be executed before
6
+ # the very first Cucumber invocation.
7
+ before_cuke(:all) do
8
+ puts 'before all'
9
+ end
10
+
11
+ # The code block will be executed just before
12
+ # a Cucumber invocation.
13
+ # The argument is a frozen Array of feature file names
14
+ before_cuke(:each) do |filenames|
15
+ puts 'before each'
16
+ end
17
+
18
+ # The code block will be executed just after
19
+ # a Cucumber invocation.
20
+ after_cuke(:each) do
21
+ puts 'after each'
22
+ end
23
+
24
+ # The code block will be executed just after
25
+ # the last Cucumber invocation.
26
+ after_cuke(:all) do
27
+ puts 'after all'
28
+ end
29
+
30
+ # End of file