cukedep 0.1.11 → 0.2.00
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/.ruby-version +1 -1
- data/.travis.yml +10 -10
- data/CHANGELOG.md +6 -0
- data/Gemfile +5 -5
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/Rakefile +30 -30
- data/bin/cukedep +15 -15
- data/lib/cukedep/application.rb +105 -112
- data/lib/cukedep/cli/cmd-line.rb +11 -13
- data/lib/cukedep/config.rb +85 -89
- data/lib/cukedep/constants.rb +5 -5
- data/lib/cukedep/cuke-runner.rb +191 -198
- data/lib/cukedep/customization.rb +30 -30
- data/lib/cukedep/feature-model.rb +43 -46
- data/lib/cukedep/feature-rep.rb +9 -11
- data/lib/cukedep/file-action.rb +11 -18
- data/lib/cukedep/gherkin-facade.rb +11 -6
- data/lib/cukedep/gherkin-listener.rb +12 -42
- data/lib/cukedep/hook-dsl.rb +78 -78
- data/lib/cukedep/sandbox.rb +15 -16
- data/lib/cukedep.rb +1 -2
- data/sample/features/step_definitions/steps.rb +2 -2
- data/sample/model/model.rb +19 -20
- data/spec/cukedep/application_spec.rb +80 -80
- data/spec/cukedep/cli/cmd-line_spec.rb +88 -88
- data/spec/cukedep/cuke-runner_spec.rb +74 -74
- data/spec/cukedep/customization_spec.rb +31 -31
- data/spec/cukedep/debug-file-action.rb +29 -29
- data/spec/cukedep/feature-model_spec.rb +100 -100
- data/spec/cukedep/feature-rep_spec.rb +2 -1
- data/spec/cukedep/file-action_spec.rb +365 -366
- data/spec/cukedep/file-parsing.rb +39 -41
- data/spec/cukedep/gherkin-facade_spec.rb +48 -49
- data/spec/cukedep/gherkin-listener_spec.rb +55 -57
- data/spec/cukedep/hook-dsl_spec.rb +182 -182
- data/spec/cukedep/sample_features/cukedep_hooks.rb +30 -30
- data/spec/cukedep/sample_features/standalone.feature +1 -1
- data/templates/rake.erb +12 -21
- metadata +80 -58
- data/sample/result.html +0 -472
- data/spec/cukedep/sample_features/cukedep.rake +0 -215
- data/spec/cukedep/sample_features/dependencies.dot +0 -38
- data/spec/cukedep/sample_features/feature2id.csv +0 -7
@@ -18,19 +18,19 @@ class FeatureModel
|
|
18
18
|
# topological sort of the nodes.
|
19
19
|
class DepGraph
|
20
20
|
include TSort # Mix-in module for topological sorting
|
21
|
-
|
21
|
+
|
22
22
|
attr_reader(:dependencies)
|
23
|
-
|
23
|
+
|
24
24
|
# Inverse lookup: from the feature file => FeatureDependencies
|
25
25
|
attr_reader(:lookup)
|
26
|
-
|
26
|
+
|
27
27
|
def initialize(theDependencies)
|
28
28
|
@dependencies = theDependencies
|
29
29
|
@lookup = dependencies.each_with_object({}) do |f_deps, subresult|
|
30
30
|
subresult[f_deps.dependee] = f_deps
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# Method required by TSort module.
|
35
35
|
# It is used to iterate over all the nodes of the dependency graph
|
36
36
|
def tsort_each_node(&aBlock)
|
@@ -48,7 +48,7 @@ class FeatureModel
|
|
48
48
|
|
49
49
|
|
50
50
|
attr_reader(:feature_files)
|
51
|
-
|
51
|
+
|
52
52
|
# An Array of FeatureDependencies
|
53
53
|
attr_reader(:dependencies)
|
54
54
|
|
@@ -63,35 +63,34 @@ class FeatureModel
|
|
63
63
|
selection = theIds.each_with_object([]) do |an_id, sub_result|
|
64
64
|
found_feature = features_by_ids[an_id]
|
65
65
|
if found_feature.nil?
|
66
|
-
|
66
|
+
raise StandardError, "No feature file with identifier '#{an_id}'."
|
67
67
|
end
|
68
68
|
sub_result << found_feature
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
return selection
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
# The list of feature files without identifiers
|
75
|
-
def anonymous_features
|
75
|
+
def anonymous_features
|
76
76
|
feature_files.select { |ff| ff.feature.anonymous? }
|
77
77
|
end
|
78
78
|
|
79
79
|
# Build an array of FileDependencies objects.
|
80
|
-
def dependency_links
|
80
|
+
def dependency_links
|
81
81
|
if @dependencies.nil?
|
82
82
|
# Build the mapping: feature identifier => feature
|
83
83
|
features_by_id = id2features
|
84
|
-
|
84
|
+
|
85
85
|
# Resolve the dependency tags
|
86
86
|
resolve_dependencies(features_by_id)
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
return @dependencies
|
90
90
|
end
|
91
91
|
|
92
|
-
|
93
92
|
# Sort the feature files by dependency order.
|
94
|
-
def sort_features_by_dep
|
93
|
+
def sort_features_by_dep
|
95
94
|
dep_links = dependency_links
|
96
95
|
graph = DepGraph.new(dep_links)
|
97
96
|
sorted_deps = graph.tsort
|
@@ -99,7 +98,7 @@ class FeatureModel
|
|
99
98
|
all_sorted = sorted_deps.map(&:dependee)
|
100
99
|
@sorted_features = all_sorted.reject { |f| f.feature.anonymous? }
|
101
100
|
end
|
102
|
-
|
101
|
+
|
103
102
|
# Generate CSV files detailing the feature to identifier mapping
|
104
103
|
# and vise versa
|
105
104
|
def mapping_reports(fileFeature2id, fileId2Feature, isVerbose = false)
|
@@ -113,7 +112,7 @@ class FeatureModel
|
|
113
112
|
f << [filename, identifier.nil? ? 'nil' : identifier]
|
114
113
|
end
|
115
114
|
end
|
116
|
-
|
115
|
+
|
117
116
|
# Generate the feature file name => feature identifier report
|
118
117
|
puts " #{fileId2Feature}" if isVerbose
|
119
118
|
CSV.open(fileId2Feature, 'wb') do |f|
|
@@ -123,7 +122,7 @@ class FeatureModel
|
|
123
122
|
filename = File.basename(ff.filepath)
|
124
123
|
f << [identifier, filename] unless identifier.nil?
|
125
124
|
end
|
126
|
-
end
|
125
|
+
end
|
127
126
|
end
|
128
127
|
|
129
128
|
# Create a graphical representation of the dependencies.
|
@@ -136,11 +135,10 @@ class FeatureModel
|
|
136
135
|
emit_body(dot_file)
|
137
136
|
emit_trailing(dot_file)
|
138
137
|
end
|
139
|
-
|
140
|
-
|
138
|
+
|
141
139
|
def emit_heading(anIO)
|
142
140
|
dir = File.dirname(File.absolute_path(feature_files[0].filepath))
|
143
|
-
heading = <<-
|
141
|
+
heading = <<-DOT
|
144
142
|
// Graph of dependencies of feature files in directory:
|
145
143
|
// '#{dir}'
|
146
144
|
// This file uses the DOT syntax, a free utility from the Graphviz toolset.
|
@@ -149,49 +147,49 @@ class FeatureModel
|
|
149
147
|
|
150
148
|
digraph g {
|
151
149
|
size = "7, 11"; // Dimensions in inches...
|
152
|
-
center = true;
|
150
|
+
center = true;
|
153
151
|
rankdir = BT; // Draw from bottom to top
|
154
|
-
label = "\\nDependency graph of '#{dir}'";
|
155
|
-
|
152
|
+
label = "\\nDependency graph of '#{dir}'";
|
153
|
+
|
156
154
|
// Nodes represent feature files
|
157
|
-
|
155
|
+
DOT
|
158
156
|
anIO.write heading
|
159
157
|
end
|
160
|
-
|
158
|
+
|
161
159
|
# Output the nodes as graph vertices + their edges with parent node
|
162
160
|
def emit_body(anIO)
|
163
|
-
anIO.puts <<-
|
161
|
+
anIO.puts <<-DOT
|
164
162
|
subgraph island {
|
165
163
|
node [shape = box, style=filled, color=lightgray];
|
166
|
-
|
164
|
+
DOT
|
167
165
|
feature_files.each_with_index do |ff, i|
|
168
166
|
draw_node(anIO, ff, i) if ff.feature.anonymous?
|
169
167
|
end
|
170
|
-
|
171
|
-
anIO.puts <<-
|
168
|
+
|
169
|
+
anIO.puts <<-DOT
|
172
170
|
label = "Isolated features";
|
173
171
|
}
|
174
172
|
|
175
173
|
subgraph dependencies {
|
176
174
|
node [shape = box, fillcolor = none];
|
177
|
-
|
178
|
-
feature_files.each_with_index do |ff, i|
|
175
|
+
DOT
|
176
|
+
feature_files.each_with_index do |ff, i|
|
179
177
|
draw_node(anIO, ff, i) unless ff.feature.anonymous?
|
180
178
|
end
|
181
|
-
anIO.puts <<-
|
179
|
+
anIO.puts <<-DOT
|
182
180
|
label = "Dependencies";
|
183
181
|
}
|
184
182
|
|
185
183
|
// The edges represent dependencies
|
186
|
-
|
184
|
+
DOT
|
187
185
|
dependencies.each { |a_dep| draw_edge(anIO, a_dep) }
|
188
186
|
end
|
189
|
-
|
187
|
+
|
190
188
|
# Output the closing part of the graph drawing
|
191
189
|
def emit_trailing(anIO)
|
192
190
|
anIO.puts '} // End of graph'
|
193
191
|
end
|
194
|
-
|
192
|
+
|
195
193
|
# Draw a refinement node in DOT format
|
196
194
|
def draw_node(anIO, aFeatureFile, anIndex)
|
197
195
|
basename = File.basename(aFeatureFile.filepath, '.feature')
|
@@ -203,7 +201,7 @@ EOS
|
|
203
201
|
end
|
204
202
|
anIO.puts %Q( node_#{anIndex} [label = "#{basename}#{id_suffix}"];)
|
205
203
|
end
|
206
|
-
|
204
|
+
|
207
205
|
# Draw an edge between feature files having dependencies.
|
208
206
|
def draw_edge(anIO, aDependency)
|
209
207
|
source_id = feature_files.find_index(aDependency.dependee)
|
@@ -216,13 +214,12 @@ EOS
|
|
216
214
|
end
|
217
215
|
end
|
218
216
|
|
219
|
-
|
220
217
|
def generate_rake_tasks(rakefile, theProjDir)
|
221
218
|
puts " #{rakefile}"
|
222
219
|
grandparent_path = Pathname.new(File.dirname(__FILE__)).parent.parent
|
223
220
|
template_source = File.read(grandparent_path + './templates/rake.erb')
|
224
221
|
|
225
|
-
# Create one template engine instance
|
222
|
+
# Create one template engine instance
|
226
223
|
engine = ERB.new(template_source)
|
227
224
|
|
228
225
|
source_dir = File.absolute_path(Dir.getwd)
|
@@ -245,7 +242,7 @@ EOS
|
|
245
242
|
end
|
246
243
|
|
247
244
|
# Build the mapping: feature identifier => feature
|
248
|
-
def id2features
|
245
|
+
def id2features
|
249
246
|
mapping = feature_files.each_with_object({}) do |file, mp|
|
250
247
|
feature_id = file.feature.identifier
|
251
248
|
mp[feature_id] = file unless feature_id.nil?
|
@@ -253,14 +250,14 @@ EOS
|
|
253
250
|
|
254
251
|
return mapping
|
255
252
|
end
|
256
|
-
|
253
|
+
|
257
254
|
# Given a feature identifier => feature mapping,
|
258
255
|
# resolve the dependency tags; that is,
|
259
256
|
# Establish links between a feature file object and its
|
260
257
|
# dependent feature file objects.
|
261
258
|
def resolve_dependencies(aMapping)
|
262
259
|
@dependencies = []
|
263
|
-
|
260
|
+
|
264
261
|
feature_files.each do |feature_file|
|
265
262
|
feature = feature_file.feature
|
266
263
|
its_id = feature.identifier
|
@@ -268,22 +265,22 @@ EOS
|
|
268
265
|
# Complain when self dependency detected
|
269
266
|
if dep_tags.include?(its_id)
|
270
267
|
msg = "Feature with identifier #{its_id} depends on itself!"
|
271
|
-
|
268
|
+
raise StandardError, msg
|
272
269
|
end
|
273
|
-
|
270
|
+
|
274
271
|
# Complain when dependency tag refers to an unknown feature
|
275
272
|
dependents = dep_tags.map do |a_tag|
|
276
273
|
unless aMapping.include?(a_tag)
|
277
274
|
msg_p1 = "Feature with identifier '#{its_id}'"
|
278
275
|
msg_p2 = " depends on unknown feature '#{a_tag}'"
|
279
|
-
|
276
|
+
raise StandardError, msg_p1 + msg_p2
|
280
277
|
end
|
281
278
|
aMapping[a_tag]
|
282
279
|
end
|
283
|
-
|
280
|
+
|
284
281
|
@dependencies << FeatureDependencies.new(feature_file, dependents)
|
285
282
|
end
|
286
|
-
|
283
|
+
|
287
284
|
return @dependencies
|
288
285
|
end
|
289
286
|
end # class
|
data/lib/cukedep/feature-rep.rb
CHANGED
@@ -5,39 +5,37 @@ module Cukedep # This module is used as a namespace
|
|
5
5
|
class FeatureRep
|
6
6
|
# Constant that specifies how feature identifier tags should begin
|
7
7
|
FeatureIdPrefix = /^feature:/
|
8
|
-
|
8
|
+
|
9
9
|
# Constant that specifies how dependency tags should begin
|
10
10
|
DependencyPrefix = /^depends_on:/
|
11
|
-
|
11
|
+
|
12
12
|
# The sorted list of all tags of the feature.
|
13
13
|
# The @ prefix is stripped from each tag text.
|
14
14
|
attr_reader(:tags)
|
15
|
-
|
16
|
-
# The identifier of the feature.
|
15
|
+
|
16
|
+
# The identifier of the feature.
|
17
17
|
# It comes from a tag with the following syntax '@feature:' + identifier.
|
18
18
|
# Note that the @feature: prefix is removed.
|
19
19
|
attr_reader(:identifier)
|
20
20
|
|
21
21
|
|
22
|
-
# theTags the tags objects from the Gherkin parser
|
22
|
+
# @param theTags [Array<String>] the tags objects from the Gherkin parser
|
23
23
|
def initialize(theTags)
|
24
24
|
# Strip first character of tag literal.
|
25
25
|
@tags = theTags.map { |t| t[1..-1] }
|
26
|
-
|
26
|
+
|
27
27
|
@identifier = tags.find { |tg| tg =~ FeatureIdPrefix }
|
28
28
|
@identifier = @identifier.sub(FeatureIdPrefix, '') unless identifier.nil?
|
29
29
|
end
|
30
|
-
|
31
|
-
public
|
32
30
|
|
33
31
|
# The list of all feature identifiers retrieved from the dependency tags
|
34
|
-
def dependency_tags
|
32
|
+
def dependency_tags
|
35
33
|
dep_tags = tags.select { |t| t =~ DependencyPrefix }
|
36
34
|
return dep_tags.map { |t| t.sub(DependencyPrefix, '') }
|
37
35
|
end
|
38
|
-
|
36
|
+
|
39
37
|
# Return true iff the identifier of the feature is nil.
|
40
|
-
def anonymous?
|
38
|
+
def anonymous?
|
41
39
|
return identifier.nil?
|
42
40
|
end
|
43
41
|
end # class
|
data/lib/cukedep/file-action.rb
CHANGED
@@ -5,23 +5,22 @@ require 'fileutils'
|
|
5
5
|
|
6
6
|
module Cukedep # This module is used as a namespace
|
7
7
|
class FileAction
|
8
|
-
|
8
|
+
attr_accessor(:patterns)
|
9
9
|
attr_reader(:delta)
|
10
10
|
|
11
11
|
# Constructor.
|
12
12
|
# [thePatterns] An array of file patterns.
|
13
13
|
def initialize(thePatterns, aDelta = nil)
|
14
14
|
@patterns = validate_file_patterns(thePatterns)
|
15
|
-
@delta
|
15
|
+
@delta = validate_delta(aDelta)
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
18
|
# Datavalue semantic: FileActions don't have identity
|
20
19
|
def ==(other)
|
21
20
|
return true if object_id == other.object_id
|
22
21
|
return false if self.class != other.class
|
23
22
|
|
24
|
-
attrs = [
|
23
|
+
attrs = %I[patterns delta]
|
25
24
|
equality = true
|
26
25
|
|
27
26
|
attrs.each do |accessor|
|
@@ -32,15 +31,14 @@ module Cukedep # This module is used as a namespace
|
|
32
31
|
return equality
|
33
32
|
end
|
34
33
|
|
35
|
-
|
36
34
|
protected
|
37
35
|
|
38
36
|
def validate_file_patterns(filePatterns)
|
39
37
|
err_msg = 'Expecting a list of file patterns'
|
40
|
-
|
41
|
-
filePatterns.each do |
|
42
|
-
err_msg = "Invalid value in list of file patterns: #{
|
43
|
-
|
38
|
+
raise StandardError, err_msg unless filePatterns.is_a?(Array)
|
39
|
+
filePatterns.each do |file_patt|
|
40
|
+
err_msg = "Invalid value in list of file patterns: #{file_patt}"
|
41
|
+
raise StandardError, err_msg unless file_patt.is_a?(String)
|
44
42
|
end
|
45
43
|
|
46
44
|
return filePatterns
|
@@ -52,7 +50,7 @@ module Cukedep # This module is used as a namespace
|
|
52
50
|
when String
|
53
51
|
validated = aDelta.empty? ? nil : aDelta
|
54
52
|
else
|
55
|
-
|
53
|
+
raise StandardError, "Invalid relative path #{aDelta}"
|
56
54
|
end
|
57
55
|
|
58
56
|
return validated
|
@@ -74,7 +72,6 @@ module Cukedep # This module is used as a namespace
|
|
74
72
|
end # class
|
75
73
|
|
76
74
|
|
77
|
-
|
78
75
|
# A delete action object has for purpose to
|
79
76
|
# delete files matching one of its file patterns.
|
80
77
|
# These file are deleted from (a subdir of) a given 'target' directory.
|
@@ -87,7 +84,7 @@ module Cukedep # This module is used as a namespace
|
|
87
84
|
|
88
85
|
def run!(targetDir)
|
89
86
|
return if patterns.empty?
|
90
|
-
orig_dir = Dir.getwd
|
87
|
+
orig_dir = Dir.getwd # Store current work directory
|
91
88
|
# pp orig_dir
|
92
89
|
|
93
90
|
begin
|
@@ -109,7 +106,6 @@ module Cukedep # This module is used as a namespace
|
|
109
106
|
end # class
|
110
107
|
|
111
108
|
|
112
|
-
|
113
109
|
# A copy action object has for purpose to
|
114
110
|
# copy files matching one of its file patterns.
|
115
111
|
# These file are copied from a given 'source' directory
|
@@ -161,16 +157,14 @@ module Cukedep # This module is used as a namespace
|
|
161
157
|
theActionSettings[:copy_subdir])
|
162
158
|
end
|
163
159
|
|
164
|
-
|
165
160
|
def ==(other)
|
166
161
|
return true if object_id == other.object_id
|
167
162
|
|
168
163
|
return (save_action == other.save_action) &&
|
169
|
-
|
170
|
-
|
164
|
+
(delete_action == other.delete_action) &&
|
165
|
+
(copy_action == other.copy_action)
|
171
166
|
end
|
172
167
|
|
173
|
-
|
174
168
|
# Launch the file actions in sequence.
|
175
169
|
def run!(currentDir, projectDir)
|
176
170
|
save_action.run!(projectDir, currentDir)
|
@@ -178,7 +172,6 @@ module Cukedep # This module is used as a namespace
|
|
178
172
|
copy_action.run!(currentDir, projectDir)
|
179
173
|
end
|
180
174
|
|
181
|
-
|
182
175
|
# Retrieve the 'built-in' action triplet associated with the given event.
|
183
176
|
# Return nil if no triplet was found for the event.
|
184
177
|
def self.builtin(anEvent)
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# File: gherkin-facade.rb
|
2
|
+
require 'gherkin/parser'
|
2
3
|
|
3
|
-
require 'gherkin'
|
4
|
-
require 'gherkin/lexer/encoding'
|
5
4
|
|
6
5
|
module Cukedep # This module is used as a namespace
|
7
6
|
# Facade design pattern: A facade is an object that provides
|
@@ -16,7 +15,6 @@ module Cukedep # This module is used as a namespace
|
|
16
15
|
# as expected by the mode argument of the IO#new method
|
17
16
|
attr_reader(:external_encoding)
|
18
17
|
|
19
|
-
|
20
18
|
def initialize(isVerbose, anExternalEncoding)
|
21
19
|
@verbose = isVerbose
|
22
20
|
@external_encoding = anExternalEncoding
|
@@ -27,25 +25,32 @@ module Cukedep # This module is used as a namespace
|
|
27
25
|
# Parse events are sent to the passed listener object.
|
28
26
|
def parse_features(aListener, file_patterns)
|
29
27
|
# Create a Gherkin parser
|
30
|
-
parser = Gherkin::Parser
|
28
|
+
parser = Gherkin::Parser.new
|
31
29
|
|
32
30
|
puts "\nParsing:" if verbose
|
33
31
|
# List all .feature files in work directory that match the pattern
|
34
32
|
filenames = []
|
35
33
|
file_patterns.each { |patt| filenames.concat(Dir.glob(patt)) }
|
36
|
-
|
37
34
|
# Parse them
|
38
35
|
filenames.each do |fname|
|
39
36
|
puts " #{fname}" if verbose
|
40
37
|
# To prevent encoding issue, open the file
|
41
38
|
# with an explicit external encoding
|
42
39
|
File.open(fname, "r:#{external_encoding}") do |f|
|
43
|
-
parser.parse(f.read
|
40
|
+
raw = parser.parse(f.read)
|
41
|
+
parse_raw_feature(raw[:feature], fname, aListener) if raw[:feature]
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
47
45
|
return aListener
|
48
46
|
end
|
47
|
+
|
48
|
+
def parse_raw_feature(raw_feature, file_name, listener)
|
49
|
+
listener.uri(file_name)
|
50
|
+
raw_tags = raw_feature[:tags]
|
51
|
+
tag_names = raw_tags.map { |raw_tag| raw_tag[:name] }
|
52
|
+
listener.feature_tags(tag_names)
|
53
|
+
end
|
49
54
|
end # class
|
50
55
|
end # module
|
51
56
|
|
@@ -4,15 +4,15 @@ require_relative 'feature-rep'
|
|
4
4
|
|
5
5
|
|
6
6
|
module Cukedep # This module is used as a namespace
|
7
|
-
class FeatureFileRep
|
7
|
+
class FeatureFileRep
|
8
8
|
attr_reader(:filepath)
|
9
|
-
|
10
|
-
|
9
|
+
attr_accessor(:feature)
|
10
|
+
|
11
11
|
def initialize(aFilepath)
|
12
12
|
@filepath = aFilepath
|
13
13
|
end
|
14
|
-
|
15
|
-
def basename
|
14
|
+
|
15
|
+
def basename
|
16
16
|
File.basename(filepath)
|
17
17
|
end
|
18
18
|
end # class
|
@@ -27,12 +27,13 @@ module Cukedep # This module is used as a namespace
|
|
27
27
|
attr_reader(:feature_files)
|
28
28
|
|
29
29
|
# Internal representation of the feature being parsed
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
attr_accessor(:current_feature)
|
31
|
+
|
32
|
+
# Constructor
|
33
|
+
def initialize
|
33
34
|
@feature_files = []
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
######################################
|
37
38
|
# Event listening methods
|
38
39
|
######################################
|
@@ -45,44 +46,13 @@ module Cukedep # This module is used as a namespace
|
|
45
46
|
end
|
46
47
|
|
47
48
|
# aFeature is a Gherkin::Formatter::Model::Feature instance
|
48
|
-
def
|
49
|
-
tag_names = aFeature.tags.map(&:name)
|
49
|
+
def feature_tags(tag_names)
|
50
50
|
@current_feature = feature_files.last.feature = FeatureRep.new(tag_names)
|
51
51
|
end
|
52
52
|
|
53
|
-
# aBackground is a Gherkin::Formatter::Model::Background instance
|
54
|
-
def background(_aBackground)
|
55
|
-
; # Do nothing
|
56
|
-
end
|
57
|
-
|
58
|
-
# aScenario is a Gherkin::Formatter::Model::Scenario instance
|
59
|
-
def scenario(_aScenario)
|
60
|
-
; # Do nothing
|
61
|
-
end
|
62
|
-
|
63
|
-
# aScenarioOutline is a Gherkin::Formatter::Model::ScenarioOutline instance
|
64
|
-
def scenario_outline(_aScenarioOutline)
|
65
|
-
; # Do nothing
|
66
|
-
end
|
67
|
-
|
68
|
-
# theExamples is a Gherkin::Formatter::Model::Examples instance
|
69
|
-
def examples(_theExamples)
|
70
|
-
; # Do nothing
|
71
|
-
end
|
72
|
-
|
73
|
-
# aStep is a Gherkin::Formatter::Model::Step instance
|
74
|
-
def step(_aStep)
|
75
|
-
; # Do nothing
|
76
|
-
end
|
77
|
-
|
78
|
-
# End of feature file notification.
|
79
|
-
def eof()
|
80
|
-
; # Do nothing
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
53
|
# Catch all method
|
85
54
|
def method_missing(message, *_args)
|
55
|
+
puts caller(1, 5).join("\n")
|
86
56
|
puts "Method #{message} is not implemented (yet)."
|
87
57
|
end
|
88
58
|
end # class
|