cuke_modeler 0.4.1 → 1.0.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.
- checksums.yaml +4 -4
- data/.gitignore +17 -17
- data/.travis.yml +1 -1
- data/Gemfile +4 -0
- data/History.rdoc +71 -3
- data/LICENSE.txt +22 -22
- data/README.md +24 -10
- data/Rakefile +2 -12
- data/cuke_modeler.gemspec +1 -1
- data/features/analysis/test_comparison.feature +37 -122
- data/features/modeling/background_modeling.feature +77 -0
- data/features/modeling/background_output.feature +42 -0
- data/features/modeling/cell_modeling.feature +23 -0
- data/features/modeling/cell_output.feature +22 -0
- data/features/modeling/directory_modeling.feature +65 -0
- data/features/modeling/directory_output.feature +12 -0
- data/features/modeling/doc_string_modeling.feature +61 -0
- data/features/modeling/doc_string_output.feature +32 -0
- data/features/modeling/example_modeling.feature +125 -0
- data/features/modeling/example_output.feature +39 -0
- data/features/modeling/feature_file_modeling.feature +40 -0
- data/features/modeling/feature_file_output.feature +12 -0
- data/features/modeling/feature_modeling.feature +109 -0
- data/features/modeling/feature_output.feature +104 -0
- data/features/modeling/model_output.feature +22 -0
- data/features/modeling/model_structure.feature +48 -0
- data/features/modeling/outline_modeling.feature +144 -0
- data/features/modeling/outline_output.feature +69 -0
- data/features/modeling/row_modeling.feature +48 -0
- data/features/modeling/row_output.feature +22 -0
- data/features/modeling/scenario_modeling.feature +118 -0
- data/features/modeling/scenario_output.feature +45 -0
- data/features/modeling/step_modeling.feature +84 -0
- data/features/modeling/step_output.feature +29 -0
- data/features/modeling/table_modeling.feature +50 -0
- data/features/modeling/table_output.feature +24 -0
- data/features/modeling/tag_modeling.feature +43 -0
- data/features/modeling/tag_output.feature +22 -0
- data/features/step_definitions/action_steps.rb +11 -1
- data/features/step_definitions/background_steps.rb +1 -85
- data/features/step_definitions/directory_steps.rb +2 -48
- data/features/step_definitions/doc_string_steps.rb +1 -67
- data/features/step_definitions/feature_file_steps.rb +2 -37
- data/features/step_definitions/feature_steps.rb +4 -100
- data/features/step_definitions/modeling_steps.rb +44 -0
- data/features/step_definitions/setup_steps.rb +19 -41
- data/features/step_definitions/step_steps.rb +2 -166
- data/features/step_definitions/table_steps.rb +1 -58
- data/features/step_definitions/tag_steps.rb +2 -72
- data/features/step_definitions/verification_steps.rb +152 -4
- data/features/support/env.rb +4 -6
- data/gemfiles/{gherkin.gemfile → gherkin2.gemfile} +4 -0
- data/gemfiles/gherkin3.gemfile +4 -0
- data/gemfiles/gherkin4.gemfile +4 -0
- data/lib/cuke_modeler.rb +24 -22
- data/lib/cuke_modeler/adapters/gherkin_2_adapter.rb +103 -31
- data/lib/cuke_modeler/adapters/gherkin_3_adapter.rb +103 -40
- data/lib/cuke_modeler/adapters/gherkin_4_adapter.rb +111 -50
- data/lib/cuke_modeler/containing.rb +255 -4
- data/lib/cuke_modeler/described.rb +28 -0
- data/lib/cuke_modeler/models/background.rb +66 -0
- data/lib/cuke_modeler/models/cell.rb +48 -0
- data/lib/cuke_modeler/models/directory.rb +95 -0
- data/lib/cuke_modeler/models/doc_string.rb +59 -0
- data/lib/cuke_modeler/models/example.rb +167 -0
- data/lib/cuke_modeler/models/feature.rb +106 -0
- data/lib/cuke_modeler/models/feature_file.rb +64 -0
- data/lib/cuke_modeler/models/model.rb +32 -0
- data/lib/cuke_modeler/models/outline.rb +79 -0
- data/lib/cuke_modeler/models/row.rb +49 -0
- data/lib/cuke_modeler/models/scenario.rb +69 -0
- data/lib/cuke_modeler/models/step.rb +68 -0
- data/lib/cuke_modeler/models/table.rb +67 -0
- data/lib/cuke_modeler/models/tag.rb +46 -0
- data/lib/cuke_modeler/named.rb +19 -0
- data/lib/cuke_modeler/nested.rb +22 -15
- data/lib/cuke_modeler/parsed.rb +11 -0
- data/lib/cuke_modeler/parsing.rb +66 -83
- data/lib/cuke_modeler/sourceable.rb +3 -11
- data/lib/cuke_modeler/stepped.rb +24 -0
- data/lib/cuke_modeler/taggable.rb +6 -29
- data/lib/cuke_modeler/version.rb +2 -1
- data/spec/integration/background_integration_spec.rb +332 -7
- data/spec/integration/cell_integration_spec.rb +321 -0
- data/spec/integration/directory_integration_spec.rb +175 -9
- data/spec/integration/doc_string_integration_spec.rb +318 -7
- data/spec/integration/example_integration_spec.rb +602 -19
- data/spec/integration/feature_file_integration_spec.rb +98 -3
- data/spec/integration/feature_integration_spec.rb +445 -27
- data/spec/integration/gherkin_2_adapter_spec.rb +122 -0
- data/spec/integration/gherkin_3_adapter_spec.rb +125 -0
- data/spec/integration/gherkin_4_adapter_spec.rb +123 -0
- data/spec/integration/model_integration_spec.rb +15 -0
- data/spec/integration/nested_integration_spec.rb +91 -0
- data/spec/integration/outline_integration_spec.rb +485 -12
- data/spec/integration/parsing_integration_spec.rb +85 -0
- data/spec/integration/row_integration_spec.rb +221 -18
- data/spec/integration/scenario_integration_spec.rb +368 -14
- data/spec/integration/shared/models_integration_specs.rb +18 -0
- data/spec/integration/step_integration_spec.rb +328 -77
- data/spec/integration/table_integration_spec.rb +242 -20
- data/spec/integration/tag_integration_spec.rb +178 -13
- data/spec/spec_helper.rb +32 -18
- data/spec/unit/background_unit_spec.rb +24 -44
- data/spec/unit/cell_unit_spec.rb +73 -0
- data/spec/unit/described_unit_spec.rb +23 -0
- data/spec/unit/directory_unit_spec.rb +52 -62
- data/spec/unit/doc_string_unit_spec.rb +47 -100
- data/spec/unit/example_unit_spec.rb +50 -296
- data/spec/unit/feature_file_unit_spec.rb +53 -52
- data/spec/unit/feature_unit_spec.rb +39 -83
- data/spec/unit/model_unit_spec.rb +15 -0
- data/spec/unit/named_unit_spec.rb +23 -0
- data/spec/unit/nested_unit_spec.rb +24 -21
- data/spec/unit/outline_unit_spec.rb +46 -69
- data/spec/unit/parsed_unit_spec.rb +27 -0
- data/spec/unit/parsing_unit_spec.rb +2 -70
- data/spec/unit/row_unit_spec.rb +22 -51
- data/spec/unit/scenario_unit_spec.rb +27 -59
- data/spec/unit/{bare_bones_unit_specs.rb → shared/bare_bones_models_unit_specs.rb} +2 -2
- data/spec/unit/shared/containing_models_unit_specs.rb +18 -0
- data/spec/unit/shared/described_models_unit_specs.rb +38 -0
- data/spec/unit/shared/models_unit_specs.rb +15 -0
- data/spec/unit/shared/named_models_unit_specs.rb +39 -0
- data/spec/unit/shared/nested_models_unit_specs.rb +51 -0
- data/spec/unit/shared/parsed_models_unit_specs.rb +39 -0
- data/spec/unit/shared/prepopulated_models_unit_specs.rb +18 -0
- data/spec/unit/shared/sourced_models_unit_specs.rb +39 -0
- data/spec/unit/shared/stepped_models_unit_specs.rb +46 -0
- data/spec/unit/shared/stringifiable_models_unit_specs.rb +18 -0
- data/spec/unit/shared/tagged_models_unit_specs.rb +72 -0
- data/spec/unit/sourceable_unit_spec.rb +12 -4
- data/spec/unit/step_unit_spec.rb +40 -231
- data/spec/unit/stepped_unit_spec.rb +23 -0
- data/spec/unit/table_unit_spec.rb +27 -89
- data/spec/unit/tag_unit_spec.rb +30 -53
- data/spec/unit/taggable_unit_spec.rb +26 -42
- data/todo.txt +32 -0
- metadata +135 -217
- data/features/analysis/test_manipulation.feature +0 -37
- data/features/modeling/gherkin/background_modeling.feature +0 -65
- data/features/modeling/gherkin/background_output.feature +0 -131
- data/features/modeling/gherkin/directory_modeling.feature +0 -110
- data/features/modeling/gherkin/directory_output.feature +0 -14
- data/features/modeling/gherkin/doc_string_modeling.feature +0 -53
- data/features/modeling/gherkin/doc_string_output.feature +0 -72
- data/features/modeling/gherkin/example_modeling.feature +0 -101
- data/features/modeling/gherkin/example_output.feature +0 -193
- data/features/modeling/gherkin/feature_file_modeling.feature +0 -54
- data/features/modeling/gherkin/feature_file_output.feature +0 -14
- data/features/modeling/gherkin/feature_modeling.feature +0 -154
- data/features/modeling/gherkin/feature_output.feature +0 -245
- data/features/modeling/gherkin/outline_modeling.feature +0 -90
- data/features/modeling/gherkin/outline_output.feature +0 -198
- data/features/modeling/gherkin/row_modeling.feature +0 -68
- data/features/modeling/gherkin/row_output.feature +0 -28
- data/features/modeling/gherkin/scenario_modeling.feature +0 -79
- data/features/modeling/gherkin/scenario_output.feature +0 -148
- data/features/modeling/gherkin/step_modeling.feature +0 -75
- data/features/modeling/gherkin/step_output.feature +0 -53
- data/features/modeling/gherkin/table_modeling.feature +0 -42
- data/features/modeling/gherkin/table_output.feature +0 -43
- data/features/modeling/gherkin/table_row_modeling.feature +0 -57
- data/features/modeling/gherkin/table_row_output.feature +0 -28
- data/features/modeling/gherkin/tag_modeling.feature +0 -48
- data/features/modeling/gherkin/tag_output.feature +0 -17
- data/features/modeling/gherkin3/background_modeling.feature +0 -64
- data/features/modeling/gherkin3/background_output.feature +0 -131
- data/features/modeling/gherkin3/directory_modeling.feature +0 -110
- data/features/modeling/gherkin3/directory_output.feature +0 -14
- data/features/modeling/gherkin3/doc_string_modeling.feature +0 -53
- data/features/modeling/gherkin3/doc_string_output.feature +0 -72
- data/features/modeling/gherkin3/example_modeling.feature +0 -100
- data/features/modeling/gherkin3/example_output.feature +0 -207
- data/features/modeling/gherkin3/feature_file_modeling.feature +0 -54
- data/features/modeling/gherkin3/feature_file_output.feature +0 -14
- data/features/modeling/gherkin3/feature_modeling.feature +0 -155
- data/features/modeling/gherkin3/feature_output.feature +0 -249
- data/features/modeling/gherkin3/outline_modeling.feature +0 -89
- data/features/modeling/gherkin3/outline_output.feature +0 -255
- data/features/modeling/gherkin3/row_modeling.feature +0 -68
- data/features/modeling/gherkin3/row_output.feature +0 -28
- data/features/modeling/gherkin3/scenario_modeling.feature +0 -78
- data/features/modeling/gherkin3/scenario_output.feature +0 -148
- data/features/modeling/gherkin3/step_modeling.feature +0 -75
- data/features/modeling/gherkin3/step_output.feature +0 -53
- data/features/modeling/gherkin3/table_modeling.feature +0 -42
- data/features/modeling/gherkin3/table_output.feature +0 -43
- data/features/modeling/gherkin3/table_row_modeling.feature +0 -57
- data/features/modeling/gherkin3/table_row_output.feature +0 -28
- data/features/modeling/gherkin3/tag_modeling.feature +0 -49
- data/features/modeling/gherkin3/tag_output.feature +0 -17
- data/features/modeling/gherkin4/background_modeling.feature +0 -64
- data/features/modeling/gherkin4/background_output.feature +0 -131
- data/features/modeling/gherkin4/directory_modeling.feature +0 -110
- data/features/modeling/gherkin4/directory_output.feature +0 -14
- data/features/modeling/gherkin4/doc_string_modeling.feature +0 -53
- data/features/modeling/gherkin4/doc_string_output.feature +0 -72
- data/features/modeling/gherkin4/example_modeling.feature +0 -100
- data/features/modeling/gherkin4/example_output.feature +0 -193
- data/features/modeling/gherkin4/feature_file_modeling.feature +0 -54
- data/features/modeling/gherkin4/feature_file_output.feature +0 -14
- data/features/modeling/gherkin4/feature_modeling.feature +0 -153
- data/features/modeling/gherkin4/feature_output.feature +0 -245
- data/features/modeling/gherkin4/outline_modeling.feature +0 -89
- data/features/modeling/gherkin4/outline_output.feature +0 -198
- data/features/modeling/gherkin4/row_modeling.feature +0 -68
- data/features/modeling/gherkin4/row_output.feature +0 -28
- data/features/modeling/gherkin4/scenario_modeling.feature +0 -78
- data/features/modeling/gherkin4/scenario_output.feature +0 -148
- data/features/modeling/gherkin4/step_modeling.feature +0 -75
- data/features/modeling/gherkin4/step_output.feature +0 -53
- data/features/modeling/gherkin4/table_modeling.feature +0 -42
- data/features/modeling/gherkin4/table_output.feature +0 -43
- data/features/modeling/gherkin4/table_row_modeling.feature +0 -57
- data/features/modeling/gherkin4/table_row_output.feature +0 -28
- data/features/modeling/gherkin4/tag_modeling.feature +0 -48
- data/features/modeling/gherkin4/tag_output.feature +0 -17
- data/features/step_definitions/outline_steps.rb +0 -258
- data/features/step_definitions/test_steps.rb +0 -123
- data/lib/cuke_modeler/background.rb +0 -38
- data/lib/cuke_modeler/directory.rb +0 -83
- data/lib/cuke_modeler/doc_string.rb +0 -87
- data/lib/cuke_modeler/example.rb +0 -195
- data/lib/cuke_modeler/feature.rb +0 -147
- data/lib/cuke_modeler/feature_element.rb +0 -73
- data/lib/cuke_modeler/feature_file.rb +0 -77
- data/lib/cuke_modeler/outline.rb +0 -68
- data/lib/cuke_modeler/raw.rb +0 -20
- data/lib/cuke_modeler/row.rb +0 -64
- data/lib/cuke_modeler/scenario.rb +0 -45
- data/lib/cuke_modeler/step.rb +0 -216
- data/lib/cuke_modeler/table.rb +0 -90
- data/lib/cuke_modeler/table_row.rb +0 -64
- data/lib/cuke_modeler/tag.rb +0 -62
- data/lib/cuke_modeler/test_element.rb +0 -79
- data/lib/cuke_modeler/world.rb +0 -113
- data/spec/integration/table_row_integration_spec.rb +0 -76
- data/spec/integration/world_integration_spec.rb +0 -14
- data/spec/unit/containing_element_unit_specs.rb +0 -18
- data/spec/unit/feature_element_unit_spec.rb +0 -19
- data/spec/unit/feature_element_unit_specs.rb +0 -52
- data/spec/unit/nested_element_unit_specs.rb +0 -39
- data/spec/unit/prepopulated_unit_specs.rb +0 -14
- data/spec/unit/raw_element_unit_specs.rb +0 -27
- data/spec/unit/raw_unit_spec.rb +0 -28
- data/spec/unit/sourced_element_unit_specs.rb +0 -18
- data/spec/unit/table_row_unit_spec.rb +0 -102
- data/spec/unit/tagged_element_unit_specs.rb +0 -67
- data/spec/unit/test_element_unit_spec.rb +0 -54
- data/spec/unit/test_element_unit_specs.rb +0 -34
- data/spec/unit/world_unit_spec.rb +0 -140
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module CukeModeler
|
|
2
|
+
|
|
3
|
+
# A mix-in module containing methods used by models that represent an element that has a description.
|
|
4
|
+
|
|
5
|
+
module Described
|
|
6
|
+
|
|
7
|
+
# The description of the element
|
|
8
|
+
attr_accessor :description
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def description_output_string
|
|
15
|
+
text = ''
|
|
16
|
+
|
|
17
|
+
unless description.empty?
|
|
18
|
+
description_lines = description.split("\n")
|
|
19
|
+
|
|
20
|
+
text << "\n" if description_lines.first =~ /\S/
|
|
21
|
+
text << description_lines.collect { |line| "#{line}" }.join("\n")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
text
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module CukeModeler
|
|
2
|
+
|
|
3
|
+
# A class modeling a feature's background.
|
|
4
|
+
|
|
5
|
+
class Background < Model
|
|
6
|
+
|
|
7
|
+
include Parsed
|
|
8
|
+
include Named
|
|
9
|
+
include Described
|
|
10
|
+
include Stepped
|
|
11
|
+
include Sourceable
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Creates a new Background object and, if *source_text* is provided, populates
|
|
15
|
+
# the object.
|
|
16
|
+
def initialize(source_text = nil)
|
|
17
|
+
@steps = []
|
|
18
|
+
|
|
19
|
+
super(source_text)
|
|
20
|
+
|
|
21
|
+
if source_text
|
|
22
|
+
parsed_background_data = parse_source(source_text)
|
|
23
|
+
populate_background(self, parsed_background_data)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Returns *true* if the two models have equivalent steps and *false* otherwise.
|
|
28
|
+
def ==(other_model)
|
|
29
|
+
return false unless other_model.respond_to?(:steps)
|
|
30
|
+
|
|
31
|
+
steps == other_model.steps
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns the model objects that belong to this model.
|
|
35
|
+
def children
|
|
36
|
+
steps
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns a string representation of this model. For a background model,
|
|
40
|
+
# this will be Gherkin text that is equivalent to the background being modeled.
|
|
41
|
+
def to_s
|
|
42
|
+
text = ''
|
|
43
|
+
|
|
44
|
+
text << "Background:#{name_output_string}"
|
|
45
|
+
text << "\n" + description_output_string unless (description.nil? || description.empty?)
|
|
46
|
+
text << "\n" unless (steps.empty? || description.nil? || description.empty?)
|
|
47
|
+
text << "\n" + steps_output_string unless steps.empty?
|
|
48
|
+
|
|
49
|
+
text
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def parse_source(source_text)
|
|
57
|
+
base_file_string = "Feature: Fake feature to parse\n"
|
|
58
|
+
source_text = base_file_string + source_text
|
|
59
|
+
|
|
60
|
+
parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_background.feature')
|
|
61
|
+
|
|
62
|
+
parsed_file.first['elements'].first
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module CukeModeler
|
|
2
|
+
|
|
3
|
+
# A class modeling a single cell of a row.
|
|
4
|
+
|
|
5
|
+
class Cell < Model
|
|
6
|
+
|
|
7
|
+
include Sourceable
|
|
8
|
+
include Parsed
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# The value of the cell
|
|
12
|
+
attr_accessor :value
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Creates a new Cell object and, if *source_text* is provided, populates
|
|
16
|
+
# the object.
|
|
17
|
+
def initialize(source_text = nil)
|
|
18
|
+
super(source_text)
|
|
19
|
+
|
|
20
|
+
if source_text
|
|
21
|
+
parsed_cell_data = parse_source(source_text)
|
|
22
|
+
populate_cell(self, parsed_cell_data)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Returns a string representation of this model. For a cell model,
|
|
27
|
+
# this will be Gherkin text that is equivalent to the cell being modeled.
|
|
28
|
+
def to_s
|
|
29
|
+
# Vertical bars and backslashes are special characters that need to be escaped
|
|
30
|
+
@value ? @value.gsub('\\', '\\\\\\').gsub('|', '\|') : ''
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def parse_source(source_text)
|
|
38
|
+
base_file_string = "Feature: Fake feature to parse\nScenario:\n* fake step\n"
|
|
39
|
+
source_text = base_file_string + '|' + source_text + '|'
|
|
40
|
+
|
|
41
|
+
parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_cell.feature')
|
|
42
|
+
|
|
43
|
+
parsed_file.first['elements'].first['steps'].first['table']['rows'].first['cells'].first
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
module CukeModeler
|
|
2
|
+
|
|
3
|
+
# A class modeling a directory in a Cucumber suite.
|
|
4
|
+
|
|
5
|
+
class Directory < Model
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# The feature file models contained by the modeled directory
|
|
9
|
+
attr_accessor :feature_files
|
|
10
|
+
|
|
11
|
+
# The directory models contained by the modeled directory
|
|
12
|
+
attr_accessor :directories
|
|
13
|
+
|
|
14
|
+
# The file path of the modeled directory
|
|
15
|
+
attr_accessor :path
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Creates a new Directory object and, if *directory_path* is provided,
|
|
19
|
+
# populates the object.
|
|
20
|
+
def initialize(directory_path = nil)
|
|
21
|
+
@path = directory_path
|
|
22
|
+
@feature_files = []
|
|
23
|
+
@directories = []
|
|
24
|
+
|
|
25
|
+
super(directory_path)
|
|
26
|
+
|
|
27
|
+
if directory_path
|
|
28
|
+
raise(ArgumentError, "Unknown directory: #{directory_path.inspect}") unless File.exists?(directory_path)
|
|
29
|
+
|
|
30
|
+
processed_directory_data = process_directory(directory_path)
|
|
31
|
+
populate_directory(self, processed_directory_data)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns the name of the modeled directory.
|
|
36
|
+
def name
|
|
37
|
+
File.basename(@path.gsub('\\', '/')) if @path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns the model objects that belong to this model.
|
|
41
|
+
def children
|
|
42
|
+
@feature_files + @directories
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns a string representation of this model. For a directory
|
|
46
|
+
# model, this will be the path of the modeled directory.
|
|
47
|
+
def to_s
|
|
48
|
+
path.to_s
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def process_directory(directory_path)
|
|
56
|
+
directory_data = {'path' => directory_path,
|
|
57
|
+
'directories' => [],
|
|
58
|
+
'feature_files' => []
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
entries = Dir.entries(directory_path)
|
|
62
|
+
entries.delete '.'
|
|
63
|
+
entries.delete '..'
|
|
64
|
+
|
|
65
|
+
entries.each do |entry|
|
|
66
|
+
entry = "#{directory_path}/#{entry}"
|
|
67
|
+
|
|
68
|
+
case
|
|
69
|
+
when File.directory?(entry)
|
|
70
|
+
directory_data['directories'] << process_directory(entry)
|
|
71
|
+
when entry =~ /\.feature$/
|
|
72
|
+
directory_data['feature_files'] << process_feature_file(entry)
|
|
73
|
+
else
|
|
74
|
+
# Ignore anything that isn't a directory or a feature file
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
directory_data
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def process_feature_file(file_path)
|
|
83
|
+
feature_file_data = {'path' => file_path}
|
|
84
|
+
|
|
85
|
+
source_text = IO.read(file_path)
|
|
86
|
+
feature = Parsing::parse_text(source_text, file_path).first
|
|
87
|
+
|
|
88
|
+
feature_file_data['feature'] = feature
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
feature_file_data
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module CukeModeler
|
|
2
|
+
|
|
3
|
+
# A class modeling a step's doc string.
|
|
4
|
+
|
|
5
|
+
class DocString < Model
|
|
6
|
+
|
|
7
|
+
include Parsed
|
|
8
|
+
include Sourceable
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# The content type associated with the doc string
|
|
12
|
+
attr_accessor :content_type
|
|
13
|
+
|
|
14
|
+
# The content of the doc string
|
|
15
|
+
attr_accessor :content
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Creates a new DocString object and, if *source_text* is provided, populates
|
|
19
|
+
# the object.
|
|
20
|
+
def initialize(source_text = nil)
|
|
21
|
+
super(source_text)
|
|
22
|
+
|
|
23
|
+
if source_text
|
|
24
|
+
parsed_doc_string_data = parse_source(source_text)
|
|
25
|
+
populate_docstring(self, parsed_doc_string_data)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns a string representation of this model. For a doc string model,
|
|
30
|
+
# this will be Gherkin text that is equivalent to the doc string being modeled.
|
|
31
|
+
def to_s
|
|
32
|
+
text = "\"\"\"#{content_type_output_string}\n"
|
|
33
|
+
text << content_output_string
|
|
34
|
+
text << '"""'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def parse_source(source_text)
|
|
42
|
+
base_file_string = "Feature:\nScenario:\n* step\n"
|
|
43
|
+
source_text = base_file_string + source_text
|
|
44
|
+
|
|
45
|
+
parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_doc_string.feature')
|
|
46
|
+
|
|
47
|
+
parsed_file.first['elements'].first['steps'].first['doc_string']
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def content_type_output_string
|
|
51
|
+
content_type ? " #{content_type}" : ''
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def content_output_string
|
|
55
|
+
(content.nil? || content.empty?) ? '' : content.gsub('"""', '\"\"\"') + "\n"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
module CukeModeler
|
|
2
|
+
|
|
3
|
+
# A class modeling an example table of an outline.
|
|
4
|
+
|
|
5
|
+
class Example < Model
|
|
6
|
+
|
|
7
|
+
include Parsed
|
|
8
|
+
include Named
|
|
9
|
+
include Described
|
|
10
|
+
include Sourceable
|
|
11
|
+
include Taggable
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# The row models in the example table
|
|
15
|
+
attr_accessor :rows
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Creates a new Example object and, if *source_text* is provided,
|
|
19
|
+
# populates the object.
|
|
20
|
+
def initialize(source_text = nil)
|
|
21
|
+
@tags = []
|
|
22
|
+
@rows = []
|
|
23
|
+
|
|
24
|
+
super(source_text)
|
|
25
|
+
|
|
26
|
+
if source_text
|
|
27
|
+
parsed_example_data = parse_source(source_text)
|
|
28
|
+
populate_example(self, parsed_example_data)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Adds a row to the example table. The row can be given as a Hash of
|
|
33
|
+
# parameters and their corresponding values or as an Array of values which
|
|
34
|
+
# will be assigned in order.
|
|
35
|
+
def add_row(row)
|
|
36
|
+
raise('Cannot add a row. No parameters have been set.') if rows.empty?
|
|
37
|
+
|
|
38
|
+
# A quick 'deep clone' so that the input isn't modified
|
|
39
|
+
row = Marshal::load(Marshal.dump(row))
|
|
40
|
+
|
|
41
|
+
case
|
|
42
|
+
when row.is_a?(Array)
|
|
43
|
+
# 'stringify' input
|
|
44
|
+
row.collect! { |value| value.to_s }
|
|
45
|
+
|
|
46
|
+
@rows << Row.new("|#{row.join('|')}|")
|
|
47
|
+
when row.is_a?(Hash)
|
|
48
|
+
# 'stringify' input
|
|
49
|
+
row = row.inject({}) { |hash, (key, value)| hash[key.to_s] = value.to_s; hash }
|
|
50
|
+
|
|
51
|
+
@rows << Row.new("|#{ordered_row_values(row).join('|')}|")
|
|
52
|
+
else
|
|
53
|
+
raise(ArgumentError, "Can only add row from a Hash or an Array but received #{row.class}")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Removes a row from the example table. The row can be given as a Hash of
|
|
58
|
+
# parameters and their corresponding values or as an Array of values
|
|
59
|
+
# which will be assigned in order.
|
|
60
|
+
def remove_row(row_removed)
|
|
61
|
+
return unless argument_rows
|
|
62
|
+
|
|
63
|
+
case
|
|
64
|
+
when row_removed.is_a?(Array)
|
|
65
|
+
location = argument_rows.index { |row| row.cells.collect { |cell| cell.value } == row_removed.collect { |value| value.strip } }
|
|
66
|
+
when row_removed.is_a?(Hash)
|
|
67
|
+
# Note: the hash value order has to be manually calculated because Ruby 1.8.7 does not have ordered
|
|
68
|
+
# hash keys. Alternatively, the hash may have simply been built up 'willy nilly' by the user instead
|
|
69
|
+
# of being built up in order according to the parameter order.
|
|
70
|
+
location = argument_rows.index { |row| row.cells.collect { |cell| cell.value } == ordered_row_values(row_removed.each_value { |value| value.strip! }) }
|
|
71
|
+
else
|
|
72
|
+
raise(ArgumentError, "Can only remove row from a Hash or an Array but received #{row_removed.class}")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
@rows.delete_at(location + 1) if location
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# The argument rows in the example table
|
|
79
|
+
def argument_rows
|
|
80
|
+
rows[1..rows.count] || []
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# The parameter row for the example table
|
|
84
|
+
def parameter_row
|
|
85
|
+
rows.first
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Returns the parameters of the example table
|
|
89
|
+
def parameters
|
|
90
|
+
parameter_row ? parameter_row.cells.collect { |cell| cell.value } : []
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Returns the model objects that belong to this model.
|
|
94
|
+
def children
|
|
95
|
+
rows + tags
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Returns a string representation of this model. For an example model,
|
|
99
|
+
# this will be Gherkin text that is equivalent to the example being modeled.
|
|
100
|
+
def to_s
|
|
101
|
+
text = ''
|
|
102
|
+
|
|
103
|
+
text << tag_output_string + "\n" unless tags.empty?
|
|
104
|
+
text << "Examples:#{name_output_string}"
|
|
105
|
+
text << "\n" + description_output_string unless (description.nil? || description.empty?)
|
|
106
|
+
text << "\n" unless (description.nil? || description.empty?)
|
|
107
|
+
text << "\n" + parameters_output_string
|
|
108
|
+
text << "\n" + rows_output_string unless argument_rows.empty?
|
|
109
|
+
|
|
110
|
+
text
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
private
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def parse_source(source_text)
|
|
118
|
+
base_file_string = "Feature: Fake feature to parse\nScenario Outline:\n* fake step\n"
|
|
119
|
+
source_text = base_file_string + source_text
|
|
120
|
+
|
|
121
|
+
parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_example.feature')
|
|
122
|
+
|
|
123
|
+
parsed_file.first['elements'].first['examples'].first
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def determine_buffer_size(index)
|
|
127
|
+
rows.collect { |row| row.cells[index].to_s.length }.max || 0
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def parameters_output_string
|
|
131
|
+
text = ''
|
|
132
|
+
|
|
133
|
+
unless parameter_row.nil?
|
|
134
|
+
text << " |"
|
|
135
|
+
parameter_row.cells.count.times { |index| text << " #{string_for(parameter_row.cells, index)} |" }
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
text
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def rows_output_string
|
|
142
|
+
text = ''
|
|
143
|
+
|
|
144
|
+
unless argument_rows.empty?
|
|
145
|
+
|
|
146
|
+
argument_rows.each do |row|
|
|
147
|
+
text << " |"
|
|
148
|
+
row.cells.count.times { |index| text << " #{string_for(row.cells, index)} |" }
|
|
149
|
+
text << "\n"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
text.chomp!
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
text
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def string_for(cells, index)
|
|
159
|
+
cells[index] ? cells[index].to_s.ljust(determine_buffer_size(index)) : ''
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def ordered_row_values(row_hash)
|
|
163
|
+
parameter_row.cells.collect { |cell| cell.value }.collect { |parameter| row_hash[parameter] }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
end
|
|
167
|
+
end
|