cucumber_analytics 0.0.5 → 0.0.6

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.
data/History.rdoc CHANGED
@@ -1,3 +1,16 @@
1
+ === Version 0.0.6 / 2013-01-07
2
+
3
+ * Improved support for example blocks in outlines.
4
+ * Modeling of empty feature files is now possible.
5
+ * Modeling of inherited tags has been added.
6
+
7
+
8
+ === Version 0.0.5 / 2012-12-16
9
+
10
+ * Bug fix: a missing 'require' statement that was causing loading erros has
11
+ been fixed.
12
+
13
+
1
14
  === Version 0.0.4 / 2012-12-13
2
15
 
3
16
  * Removed an unintentional gem dependency
@@ -0,0 +1,37 @@
1
+ Feature: Tests can be manipulated in various ways.
2
+
3
+
4
+ Acceptance criteria
5
+
6
+ Tests can be manipulated:
7
+ 1. outlines can have rows added and removed
8
+
9
+
10
+ Background: Test file setup.
11
+ Given the following feature file:
12
+ """
13
+ Feature: A feature containing our starting outline.
14
+
15
+ Scenario Outline:
16
+ Given this *parameterized* step takes a table:
17
+ | <param1> |
18
+ | <param2> |
19
+ Then I don't really need another step
20
+ Examples: Only one row to start with
21
+ | param1 | param2 |
22
+ | x | y |
23
+ """
24
+ And parameter delimiters of "*" and "*"
25
+ And the file is read
26
+
27
+ Scenario: Rows can be added to an outline
28
+ When the test example block has the following rows added to it:
29
+ | 1,2 |
30
+ Then the test example block rows are as follows:
31
+ | x,y |
32
+ | 1,2 |
33
+
34
+ Scenario: Rows can be removed from an outline
35
+ When the test example block has the following rows removed from it:
36
+ | x,y |
37
+ Then the test example block has no rows
@@ -0,0 +1,100 @@
1
+ Feature: Example elements can be modeled.
2
+
3
+
4
+ Acceptance criteria
5
+
6
+ All conceptual pieces of an Examples block can be modeled:
7
+ 1. the examples' name
8
+ 2. the examples' description
9
+ 3. the examples' parameters
10
+ 4. the examples' rows
11
+ 5. the examples' tags
12
+ 6. the examples's applied tags
13
+
14
+
15
+ Background: Test file setup.
16
+ Given the following feature file:
17
+ """
18
+ @a_feature_level_tag
19
+ Feature: The test feature name.
20
+
21
+ @outline_tag
22
+ Scenario Outline: The scenario outline's name.
23
+ Given this *parameterized* step takes a table:
24
+ | <param1> |
25
+ | <param2> |
26
+ Then I don't really need another step
27
+
28
+ Examples: text describing the significance of the examples
29
+ Anything besides the | that starts a row should be valid
30
+ description at this point in the test. YMMV
31
+ | param1 | param2 | extra param |
32
+ #A more random comment
33
+ | x | y | ? |
34
+ | 1 | 2 | 3 |
35
+ @example_tag @another_one
36
+ Examples: some examples with different significance and a tag
37
+
38
+ Words, words, words, words,
39
+
40
+ why so many words?
41
+ #
42
+
43
+ | param1 |
44
+ #
45
+
46
+ #
47
+ | a |
48
+ Examples:
49
+ """
50
+ And parameter delimiters of "*" and "*"
51
+ When the file is read
52
+
53
+
54
+ Scenario: The examples' name is modeled.
55
+ Then the test example block "1" is found to have the following properties:
56
+ | name | text describing the significance of the examples |
57
+ And the test example block "2" is found to have the following properties:
58
+ | name | some examples with different significance and a tag |
59
+ And the test example block "3" is found to have the following properties:
60
+ | name | |
61
+
62
+
63
+ Scenario: The examples' description is modeled.
64
+ Then the test example block "1" descriptive lines are as follows:
65
+ | Anything besides the \| that starts a row should be valid |
66
+ | description at this point in the test. YMMV |
67
+ And the test example block "2" descriptive lines are as follows:
68
+ | Words, words, words, words, |
69
+ | why so many words? |
70
+ And the test example block "3" has no descriptive lines
71
+
72
+ Scenario: The examples' tags are modeled.
73
+ Then the test example block "1" has no tags
74
+ And the test example block "2" is found to have the following tags:
75
+ | @example_tag |
76
+ | @another_one |
77
+ And the test example block "3" has no tags
78
+
79
+ Scenario: The examples' applied tags are modeled.
80
+ Then the test example block "2" is found to have the following applied tags:
81
+ | @a_feature_level_tag |
82
+ | @outline_tag |
83
+
84
+ Scenario: The examples' parameters are modeled.
85
+ Then the test example block "1" parameters are as follows:
86
+ | param1 |
87
+ | param2 |
88
+ | extra param |
89
+ And the test example block "2" parameters are as follows:
90
+ | param1 |
91
+ And the test example block "3" has no parameters
92
+
93
+
94
+ Scenario: The examples' rows are modeled.
95
+ Then the test example block "1" rows are as follows:
96
+ | x,y,? |
97
+ | 1,2,3 |
98
+ And the test example block "2" rows are as follows:
99
+ | a |
100
+ And the test example block "3" has no rows
@@ -6,7 +6,7 @@ Feature: Feature files can be modeled.
6
6
  All conceptual pieces of a .feature file can be modeled:
7
7
  1. the files's name
8
8
  2. the file's full path
9
- 3. the file's features (only one per file)
9
+ 3. the file's features (one or zero per file)
10
10
 
11
11
 
12
12
  Background: Test file setup.
@@ -20,18 +20,29 @@ Feature: Feature files can be modeled.
20
20
  Feature: The second test feature
21
21
  Just a dummy feature.
22
22
  """
23
+ And the following feature file "why_would_you_make_an_empty_file.feature":
24
+ """
25
+ """
23
26
  When the file "test_file_1.feature" is read
24
27
  And the file "test_file_2.feature" is read
28
+ And the file "why_would_you_make_an_empty_file.feature" is read
25
29
 
26
30
 
27
31
  Scenario: The file's feature is modeled.
28
32
  Then file "1" is found to have the following properties:
29
33
  | name | test_file_1.feature |
30
34
  | path | path_to/test_file_1.feature |
35
+ | feature_count | 1 |
31
36
  And file "1" features are as follows:
32
37
  | The first test feature |
33
38
  Then file "2" is found to have the following properties:
34
39
  | name | test_file_2.feature |
35
40
  | path | path_to/test_file_2.feature |
41
+ | feature_count | 1 |
36
42
  And file "2" features are as follows:
37
43
  | The second test feature |
44
+ Then file "3" is found to have the following properties:
45
+ | name | why_would_you_make_an_empty_file.feature |
46
+ | path | path_to/why_would_you_make_an_empty_file.feature |
47
+ | feature_count | 0 |
48
+ And file "3" has no features
@@ -8,7 +8,8 @@ Feature: Scenario Outline elements can be modeled.
8
8
  2. the outline's description
9
9
  3. the outline's steps
10
10
  4. the outline's tags
11
- 5. the outline's example rows
11
+ 5. the outline's applied tags
12
+ 6. the outline's example blocks
12
13
 
13
14
 
14
15
  Background: Test file setup.
@@ -196,18 +197,11 @@ Feature: Scenario Outline elements can be modeled.
196
197
  Then the test is found to have the following tags:
197
198
  | @outline_tag |
198
199
 
199
- Scenario Outline: The outline examples are modeled.
200
- Then "<outline>" example "<set>" has a "<name>"
201
- And "<outline>" example "<set>" descriptive lines are as follows:
202
- | <description1> |
203
- | <description2> |
204
- And "<outline>" example "<set>" tags are as follows:
205
- | <tag1> |
206
- | <tag2> |
207
- And "<outline>" example "<set>" rows are as follows:
208
- | <row1> |
209
- | <row2> |
210
- Examples:
211
- | outline | set | name | description1 | description2 | tag1 | tag2 | row1 | row2 |
212
- | 1 | 1 | text describing the significance of the examples | Anything besides the \| that starts a row should be valid | description at this point in the test. YMMV | | | \| param1 \| param2 \| | \| x \| y \| |
213
- | 1 | 2 | some examples with different significance and a tag | Words, words, words, words, | why so many words? | @example_tag | @another_one | \| param1 \| param2 \| | \| a \| b \| |
200
+ Scenario: The outline applied tags are modeled.
201
+ Then the test is found to have the following applied tags:
202
+ | @a_feature_level_tag |
203
+
204
+ Scenario: The outline example blocks are modeled.
205
+ And the test example blocks are as follows:
206
+ | text describing the significance of the examples |
207
+ | some examples with different significance and a tag |
@@ -8,6 +8,7 @@ Feature: Scenario elements can be modeled.
8
8
  2. the scenario's description
9
9
  3. the scenario's steps
10
10
  4. the scenario's tags
11
+ 5. the scenario's applied tags
11
12
 
12
13
 
13
14
  Background: Test file setup.
@@ -177,3 +178,7 @@ Feature: Scenario elements can be modeled.
177
178
  | @a_tag |
178
179
  | @another_tag |
179
180
  | @yet_another_tag |
181
+
182
+ Scenario: The scenario applied tags are modeled.
183
+ Then the test is found to have the following applied tags:
184
+ | @a_feature_level_tag |
@@ -3,7 +3,10 @@ Then /^(?:the )?feature(?: "([^"]*)")? is found to have the following properties
3
3
  properties = properties.rows_hash
4
4
 
5
5
  properties.each do |property, expected_value|
6
- assert expected_value == @parsed_files[file - 1].feature.send(property.to_sym).to_s
6
+ expected = expected_value
7
+ actual = @parsed_files[file - 1].feature.send(property.to_sym).to_s
8
+
9
+ assert(actual == expected, "Expected: #{expected}\n but was: #{actual}")
7
10
  end
8
11
  end
9
12
 
@@ -16,3 +16,9 @@ When /^(?:the )?file(?: "([^"]*)")? features are as follows:$/ do |file, feature
16
16
 
17
17
  assert @parsed_files[file - 1].feature.name == feature.raw.flatten.first
18
18
  end
19
+
20
+ When /^(?:the )?file(?: "([^"]*)")? has no features$/ do |file|
21
+ file ||= 1
22
+
23
+ assert @parsed_files[file - 1].feature.nil?
24
+ end
@@ -1,26 +1,141 @@
1
- Then /^(?:feature "([^"]*)" )?"([^"]*)" example "([^"]*)" has a "([^"]*)"$/ do |file, test, example, name|
1
+ When /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example blocks are as follows:$/ do |file, test, names|
2
2
  file ||= 1
3
+ test ||= 1
3
4
 
4
- assert @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].name == name
5
+ names = names.raw.flatten
6
+
7
+ assert @parsed_files[file - 1].feature.tests[test - 1].examples.collect { |example| example.name } == names
5
8
  end
6
9
 
7
- When /^(?:feature "([^"]*)" )?"([^"]*)" example "([^"]*)" descriptive lines are as follows:$/ do |file, test, example, lines|
10
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? is found to have the following properties:$/ do |file, test, example, properties|
8
11
  file ||= 1
9
- lines = lines.raw.flatten.delete_if { |line| line == '' }
12
+ test ||= 1
13
+ example ||= 1
14
+
15
+ properties = properties.rows_hash
16
+
17
+ properties.each do |property, value|
18
+ assert value == @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].send(property.to_sym).to_s
19
+ end
20
+ end
21
+
22
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? descriptive lines are as follows:$/ do |file, test, example, lines|
23
+ file ||= 1
24
+ test ||= 1
25
+ example ||= 1
26
+
27
+ lines = lines.raw.flatten
10
28
 
11
29
  assert @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].description == lines
12
30
  end
13
31
 
14
- When /^(?:feature "([^"]*)" )?"([^"]*)" example "([^"]*)" tags are as follows:$/ do |file, test, example, tags|
32
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? is found to have the following tags:$/ do |file, test, example, tags|
15
33
  file ||= 1
16
- tags = tags.raw.flatten.delete_if { |line| line == '' }
34
+ test ||= 1
35
+ example ||= 1
36
+
37
+ tags = tags.raw.flatten
17
38
 
18
39
  assert @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].tags == tags
19
40
  end
20
41
 
21
- When /^(?:feature "([^"]*)" )?"([^"]*)" example "([^"]*)" rows are as follows:$/ do |file, test, example, rows|
42
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? is found to have the following applied tags:$/ do |file, test, example, tags|
43
+ file ||= 1
44
+ test ||= 1
45
+ example ||= 1
46
+
47
+ tags = tags.raw.flatten
48
+
49
+ expected = tags.sort
50
+ actual = @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].applied_tags.sort
51
+
52
+ assert(actual == expected, "Expected: #{expected}\n but was: #{actual}")
53
+ end
54
+
55
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? has no tags$/ do |file, test, example|
22
56
  file ||= 1
57
+ test ||= 1
58
+ example ||= 1
59
+
60
+ assert @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].tags == []
61
+ end
62
+
63
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? rows are as follows:$/ do |file, test, example, rows|
64
+ file ||= 1
65
+ test ||= 1
66
+ example ||= 1
67
+
68
+ rows = rows.raw.flatten
69
+ examples = @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1]
70
+
71
+ expected = rows.collect { |row| row.split(',') }.collect { |row| Hash[examples.parameters.zip(row)] }
72
+ actual = examples.rows
73
+
74
+ assert(actual == expected, "Expected: #{expected}\n but was: #{actual}")
75
+ end
76
+
77
+ When /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? has the following rows added to it:$/ do |file, test, example, rows|
78
+ file ||= 1
79
+ test ||= 1
80
+ example ||= 1
81
+
23
82
  rows = rows.raw.flatten
24
83
 
25
- assert @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].rows == rows
84
+ rows.each do |row|
85
+ row = row.split(',')
86
+ @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].add_row(row)
87
+ end
88
+ end
89
+
90
+ When /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? has the following rows removed from it:$/ do |file, test, example, rows|
91
+ file ||= 1
92
+ test ||= 1
93
+ example ||= 1
94
+
95
+ rows = rows.raw.flatten
96
+
97
+ rows.each do |row|
98
+ row = row.split(',')
99
+ @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].remove_row(row)
100
+ end
101
+ end
102
+
103
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? parameters are as follows:$/ do |file, test, example, parameters|
104
+ file ||= 1
105
+ test ||= 1
106
+ example ||= 1
107
+
108
+ parameters = parameters.raw.flatten
109
+
110
+ expected = parameters
111
+ actual =@parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].parameters
112
+
113
+ assert(actual == expected, "Expected: #{expected}\n but was: #{actual}")
114
+ end
115
+
116
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? has no descriptive lines$/ do |file, test, example|
117
+ file ||= 1
118
+ test ||= 1
119
+ example ||= 1
120
+
121
+ assert @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].description == []
122
+ end
123
+
124
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? has no parameters$/ do |file, test, example|
125
+ file ||= 1
126
+ test ||= 1
127
+ example ||= 1
128
+
129
+ assert @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].parameters == []
130
+ end
131
+
132
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? example block(?: "([^"]*)")? has no rows$/ do |file, test, example|
133
+ file ||= 1
134
+ test ||= 1
135
+ example ||= 1
136
+
137
+ expected = []
138
+ actual = @parsed_files[file - 1].feature.tests[test - 1].examples[example - 1].rows
139
+
140
+ assert(actual == expected, "Expected: #{expected}\n but was: #{actual}")
26
141
  end
@@ -52,6 +52,16 @@ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? is found to have the
52
52
  assert @parsed_files[file - 1].feature.tests[test - 1].tags == tags.raw.flatten
53
53
  end
54
54
 
55
+ Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? is found to have the following applied tags:$/ do |file, test, tags|
56
+ file ||= 1
57
+ test ||= 1
58
+
59
+ expected = tags.raw.flatten
60
+ actual = @parsed_files[file - 1].feature.tests[test - 1].applied_tags
61
+
62
+ assert(actual == expected, "Expected: #{expected}\n but was: #{actual}")
63
+ end
64
+
55
65
  Then /^(?:the )?(?:feature "([^"]*)" )?test(?: "([^"]*)")? step "([^"]*)" has the following block:$/ do |file, test, step, block|
56
66
  file ||= 1
57
67
  test ||= 1
@@ -4,6 +4,8 @@ module CucumberAnalytics
4
4
 
5
5
  attr_accessor :tags
6
6
  attr_accessor :rows
7
+ attr_accessor :parameters
8
+ attr_accessor :parent_element
7
9
 
8
10
 
9
11
  # Creates a new OutlineExample object and, if *source_lines* is provided,
@@ -19,10 +21,43 @@ module CucumberAnalytics
19
21
 
20
22
  @tags = []
21
23
  @rows = []
24
+ @parameters = []
22
25
 
23
26
  parse_example(source_lines) if source_lines
24
27
  end
25
28
 
29
+ # Adds a row to the example block. The row can be given as a Hash of column
30
+ # headers and their corresponding values or as an Array of values which
31
+ # will be assigned in order.
32
+ def add_row(row)
33
+ if row.is_a?(Array)
34
+ @rows << Hash[@parameters.zip(row.collect { |value| value.strip })]
35
+ else
36
+ @rows << row
37
+ end
38
+ end
39
+
40
+ # Removes a row from the example block. The row can be given as a Hash of
41
+ # column headers and their corresponding values or as an Array of values
42
+ # which will be assigned in order.
43
+ def remove_row(row)
44
+ if row.is_a?(Array)
45
+ location = @rows.index { |row_hash| row_hash.values_at(*@parameters) == row }
46
+ else
47
+ location = @rows.index { |row_hash| row_hash == row }
48
+ end
49
+ @rows.delete_at(location) if location
50
+ end
51
+
52
+ # Returns tags which are applicable to the example block which have been
53
+ # inherited from the outline level.
54
+ def applied_tags
55
+ additional_tags = @parent_element.tags
56
+ additional_tags.concat(@parent_element.applied_tags) if @parent_element.respond_to?(:applied_tags)
57
+
58
+ additional_tags
59
+ end
60
+
26
61
 
27
62
  private
28
63
 
@@ -33,8 +68,24 @@ module CucumberAnalytics
33
68
  parse_feature_element_tags(source_lines)
34
69
  parse_feature_element(source_lines)
35
70
 
36
- source_lines.delete_if { |line| World.ignored_line?(line)}
37
- rows.concat source_lines.collect { |line| line.strip }
71
+ source_lines.delete_if { |line| World.ignored_line?(line) }
72
+
73
+ unless source_lines.empty?
74
+ @parameters = source_lines.shift.split('|')
75
+ @parameters.shift
76
+ @parameters.pop
77
+
78
+ @parameters.collect! { |param| param.strip }
79
+ end
80
+
81
+ unless source_lines.empty?
82
+ @rows = source_lines.collect { |row| row.split('|') }.collect do |row|
83
+ row.shift
84
+ row.collect { |value| value.strip }
85
+ end
86
+
87
+ @rows.collect! { |row| Hash[@parameters.zip(row)] }
88
+ end
38
89
  end
39
90
 
40
91
  def parse_feature_element_description(source_lines)
@@ -34,6 +34,8 @@ module CucumberAnalytics
34
34
  @feature_files.count
35
35
  end
36
36
 
37
+ # Returns the immediate child elements of the directory (i.e. its .feature
38
+ # files and .feature file containing sub-directories).
37
39
  def contains
38
40
  @feature_files + @feature_directories
39
41
  end
@@ -54,11 +54,13 @@ module CucumberAnalytics
54
54
  def test_case_count
55
55
  scenario_count + outlines.reduce(0) { |outline_sum, outline|
56
56
  outline_sum += outline.examples.reduce(0) { |example_sum, example|
57
- example_sum += example.rows.count - 1
57
+ example_sum += example.rows.count
58
58
  }
59
59
  }
60
60
  end
61
61
 
62
+ # Returns the immediate child elements of the feature (i.e. its background
63
+ # and tests).
62
64
  def contains
63
65
  [@background] + @tests
64
66
  end
@@ -81,7 +83,7 @@ module CucumberAnalytics
81
83
  CucumberAnalytics::Logging.logger.debug(line.chomp)
82
84
  end
83
85
 
84
- source_lines.delete_if { |line| World.ignored_line?(line)}
86
+ source_lines.delete_if { |line| World.ignored_line?(line) }
85
87
 
86
88
  until source_lines.first =~ /^\s*(?:(?:Scenario: )|(?:Scenario Outline: )|(?:Background: )|(?:@ ))/ or
87
89
  source_lines.empty?
@@ -23,16 +23,24 @@ module CucumberAnalytics
23
23
  @file
24
24
  end
25
25
 
26
+ # Returns the immediate child elements of the feature file(i.e. its
27
+ # feature).
26
28
  def contains
27
29
  [@feature]
28
30
  end
29
31
 
32
+ # Returns the number of features contained in the file.
33
+ def feature_count
34
+ @feature.nil? ? 0 : 1
35
+ end
36
+
30
37
 
31
38
  private
32
39
 
33
40
 
34
41
  def parse_file(file_parsed)
35
42
  CucumberAnalytics::Logging.logger.info('ParsedFile#parse_file')
43
+ CucumberAnalytics::Logging.logger.debug("Parsing file: #{file_parsed}")
36
44
 
37
45
  @file = file_parsed
38
46
 
@@ -43,7 +51,9 @@ module CucumberAnalytics
43
51
  File.open(@file, 'r') { |file| file_lines = file.readlines }
44
52
 
45
53
  # collect feature tag lines
46
- until file_lines.first =~ /^s*Feature:/
54
+ until file_lines.first =~ /^s*Feature:/ or
55
+ file_lines.empty?
56
+
47
57
  feature_lines << file_lines.first
48
58
  file_lines.shift
49
59
  end
@@ -57,7 +67,7 @@ module CucumberAnalytics
57
67
  end
58
68
 
59
69
  # create a new feature bases on the collected lines
60
- @feature = ParsedFeature.new(feature_lines)
70
+ @feature = feature_lines.empty? ? nil : ParsedFeature.new(feature_lines)
61
71
 
62
72
  if file_lines.first =~ /^\s*Background:/
63
73
 
@@ -71,7 +81,7 @@ module CucumberAnalytics
71
81
 
72
82
  # collect everything else up to the first test
73
83
  until file_lines.first =~ /^\s*(?:@|Scenario:|(?:Scenario Outline:))/ or
74
- file_lines.empty?
84
+ file_lines.empty?
75
85
 
76
86
  if file_lines.first =~ /^\s*"""/
77
87
  background_lines.concat(extract_doc_string!(file_lines))
@@ -145,6 +155,7 @@ module CucumberAnalytics
145
155
  next_test = ParsedScenario.new(test_lines)
146
156
  end
147
157
 
158
+ next_test.parent_element = @feature
148
159
  @feature.tests << next_test
149
160
  end
150
161
  end
@@ -3,6 +3,7 @@ module CucumberAnalytics
3
3
 
4
4
 
5
5
  attr_accessor :tags
6
+ attr_accessor :parent_element
6
7
 
7
8
 
8
9
  # Creates a new ParsedScenario object and, if *source_lines* is provided,
@@ -21,6 +22,15 @@ module CucumberAnalytics
21
22
  parse_scenario(source_lines) if source_lines
22
23
  end
23
24
 
25
+ # Returns tags which are applicable to the scenario which have been
26
+ # inherited from the feature level.
27
+ def applied_tags
28
+ additional_tags = @parent_element.tags
29
+ additional_tags.concat(@parent_element.applied_tags) if @parent_element.respond_to?(:applied_tags)
30
+
31
+ additional_tags
32
+ end
33
+
24
34
 
25
35
  private
26
36
 
@@ -4,6 +4,8 @@ module CucumberAnalytics
4
4
 
5
5
  attr_accessor :tags
6
6
  attr_accessor :examples
7
+ attr_accessor :parent_element
8
+
7
9
 
8
10
  # Creates a new ParsedScenarioOutline object and, if *source_lines* is
9
11
  # provided, populates the object.
@@ -22,10 +24,21 @@ module CucumberAnalytics
22
24
  parse_outline(source_lines) if source_lines
23
25
  end
24
26
 
27
+ # Returns the immediate child elements of the outline (i.e. its example
28
+ # blocks).
25
29
  def contains
26
30
  @examples
27
31
  end
28
32
 
33
+ # Returns tags which are applicable to the outline which have been
34
+ # inherited from the feature level.
35
+ def applied_tags
36
+ additional_tags = @parent_element.tags
37
+ additional_tags.concat(@parent_element.applied_tags) if @parent_element.respond_to?(:applied_tags)
38
+
39
+ additional_tags
40
+ end
41
+
29
42
 
30
43
  private
31
44
 
@@ -97,7 +110,10 @@ module CucumberAnalytics
97
110
  end
98
111
 
99
112
  # use the collected lines to create an example
100
- @examples << OutlineExample.new(example_lines)
113
+ example = OutlineExample.new(example_lines)
114
+ example.parent_element = self
115
+
116
+ @examples << example
101
117
  end
102
118
  end
103
119
 
@@ -1,3 +1,3 @@
1
1
  module CucumberAnalytics
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber_analytics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-16 00:00:00.000000000 Z
12
+ date: 2013-01-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -79,8 +79,10 @@ files:
79
79
  - features/analysis/tag_collection.feature
80
80
  - features/analysis/test_collection.feature
81
81
  - features/analysis/test_comparison.feature
82
+ - features/analysis/test_manipulation.feature
82
83
  - features/modeling/background_modeling.feature
83
84
  - features/modeling/directory_modeling.feature
85
+ - features/modeling/example_modeling.feature
84
86
  - features/modeling/feature_file_modeling.feature
85
87
  - features/modeling/feature_modeling.feature
86
88
  - features/modeling/outline_modeling.feature
@@ -141,8 +143,10 @@ test_files:
141
143
  - features/analysis/tag_collection.feature
142
144
  - features/analysis/test_collection.feature
143
145
  - features/analysis/test_comparison.feature
146
+ - features/analysis/test_manipulation.feature
144
147
  - features/modeling/background_modeling.feature
145
148
  - features/modeling/directory_modeling.feature
149
+ - features/modeling/example_modeling.feature
146
150
  - features/modeling/feature_file_modeling.feature
147
151
  - features/modeling/feature_modeling.feature
148
152
  - features/modeling/outline_modeling.feature