cuke_modeler 3.27.0 → 3.28.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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +579 -572
  3. data/LICENSE.txt +22 -22
  4. data/README.md +135 -135
  5. data/cuke_modeler.gemspec +59 -59
  6. data/lib/cuke_modeler/adapters/gherkin_10_adapter.rb +13 -13
  7. data/lib/cuke_modeler/adapters/gherkin_11_adapter.rb +13 -13
  8. data/lib/cuke_modeler/adapters/gherkin_12_adapter.rb +13 -13
  9. data/lib/cuke_modeler/adapters/gherkin_13_adapter.rb +13 -13
  10. data/lib/cuke_modeler/adapters/gherkin_14_adapter.rb +13 -13
  11. data/lib/cuke_modeler/adapters/gherkin_15_adapter.rb +13 -13
  12. data/lib/cuke_modeler/adapters/gherkin_16_adapter.rb +13 -13
  13. data/lib/cuke_modeler/adapters/gherkin_17_adapter.rb +13 -13
  14. data/lib/cuke_modeler/adapters/gherkin_18_adapter.rb +27 -27
  15. data/lib/cuke_modeler/adapters/gherkin_19_adapter.rb +64 -64
  16. data/lib/cuke_modeler/adapters/gherkin_20_adapter.rb +359 -359
  17. data/lib/cuke_modeler/adapters/gherkin_21_adapter.rb +13 -13
  18. data/lib/cuke_modeler/adapters/gherkin_22_adapter.rb +13 -13
  19. data/lib/cuke_modeler/adapters/gherkin_23_adapter.rb +13 -13
  20. data/lib/cuke_modeler/adapters/gherkin_24_adapter.rb +13 -13
  21. data/lib/cuke_modeler/adapters/gherkin_25_adapter.rb +13 -13
  22. data/lib/cuke_modeler/adapters/gherkin_26_adapter.rb +13 -13
  23. data/lib/cuke_modeler/adapters/gherkin_27_adapter.rb +13 -13
  24. data/lib/cuke_modeler/adapters/gherkin_28_adapter.rb +13 -13
  25. data/lib/cuke_modeler/adapters/gherkin_29_adapter.rb +13 -13
  26. data/lib/cuke_modeler/adapters/gherkin_30_adapter.rb +13 -13
  27. data/lib/cuke_modeler/adapters/gherkin_31_adapter.rb +13 -13
  28. data/lib/cuke_modeler/adapters/gherkin_32_adapter.rb +13 -13
  29. data/lib/cuke_modeler/adapters/gherkin_33_adapter.rb +13 -13
  30. data/lib/cuke_modeler/adapters/gherkin_34_adapter.rb +13 -13
  31. data/lib/cuke_modeler/adapters/gherkin_35_adapter.rb +13 -13
  32. data/lib/cuke_modeler/adapters/gherkin_36_adapter.rb +13 -13
  33. data/lib/cuke_modeler/adapters/gherkin_37_adapter.rb +13 -13
  34. data/lib/cuke_modeler/adapters/gherkin_38_adapter.rb +13 -0
  35. data/lib/cuke_modeler/adapters/gherkin_9_adapter.rb +375 -375
  36. data/lib/cuke_modeler/adapters/gherkin_base_adapter.rb +17 -17
  37. data/lib/cuke_modeler/containing.rb +105 -105
  38. data/lib/cuke_modeler/described.rb +71 -71
  39. data/lib/cuke_modeler/models/background.rb +122 -122
  40. data/lib/cuke_modeler/models/cell.rb +88 -88
  41. data/lib/cuke_modeler/models/comment.rb +82 -82
  42. data/lib/cuke_modeler/models/directory.rb +143 -143
  43. data/lib/cuke_modeler/models/doc_string.rb +104 -104
  44. data/lib/cuke_modeler/models/example.rb +274 -274
  45. data/lib/cuke_modeler/models/feature.rb +200 -200
  46. data/lib/cuke_modeler/models/feature_file.rb +116 -116
  47. data/lib/cuke_modeler/models/model.rb +87 -87
  48. data/lib/cuke_modeler/models/outline.rb +145 -145
  49. data/lib/cuke_modeler/models/row.rb +104 -104
  50. data/lib/cuke_modeler/models/rule.rb +162 -162
  51. data/lib/cuke_modeler/models/scenario.rb +128 -128
  52. data/lib/cuke_modeler/models/step.rb +178 -178
  53. data/lib/cuke_modeler/models/table.rb +117 -117
  54. data/lib/cuke_modeler/models/tag.rb +75 -75
  55. data/lib/cuke_modeler/named.rb +26 -26
  56. data/lib/cuke_modeler/nested.rb +61 -61
  57. data/lib/cuke_modeler/parsed.rb +24 -24
  58. data/lib/cuke_modeler/parsing.rb +208 -208
  59. data/lib/cuke_modeler/sourceable.rb +29 -29
  60. data/lib/cuke_modeler/stepped.rb +34 -34
  61. data/lib/cuke_modeler/taggable.rb +57 -57
  62. data/lib/cuke_modeler/version.rb +4 -4
  63. data/lib/cuke_modeler.rb +32 -32
  64. data/testing/cucumber/features/analysis/step_comparison.feature +25 -25
  65. data/testing/cucumber/features/analysis/test_comparison.feature +35 -35
  66. data/testing/cucumber/features/modeling/background_modeling.feature +105 -105
  67. data/testing/cucumber/features/modeling/background_output.feature +60 -60
  68. data/testing/cucumber/features/modeling/cell_modeling.feature +68 -68
  69. data/testing/cucumber/features/modeling/cell_output.feature +36 -36
  70. data/testing/cucumber/features/modeling/comment_modeling.feature +62 -62
  71. data/testing/cucumber/features/modeling/comment_output.feature +40 -40
  72. data/testing/cucumber/features/modeling/directory_modeling.feature +62 -62
  73. data/testing/cucumber/features/modeling/directory_output.feature +33 -33
  74. data/testing/cucumber/features/modeling/doc_string_modeling.feature +85 -85
  75. data/testing/cucumber/features/modeling/doc_string_output.feature +50 -50
  76. data/testing/cucumber/features/modeling/example_modeling.feature +155 -155
  77. data/testing/cucumber/features/modeling/example_output.feature +57 -57
  78. data/testing/cucumber/features/modeling/feature_file_modeling.feature +49 -49
  79. data/testing/cucumber/features/modeling/feature_file_output.feature +33 -33
  80. data/testing/cucumber/features/modeling/feature_modeling.feature +149 -149
  81. data/testing/cucumber/features/modeling/feature_output.feature +144 -144
  82. data/testing/cucumber/features/modeling/model_output.feature +61 -61
  83. data/testing/cucumber/features/modeling/model_structure.feature +42 -42
  84. data/testing/cucumber/features/modeling/outline_modeling.feature +175 -175
  85. data/testing/cucumber/features/modeling/outline_output.feature +87 -87
  86. data/testing/cucumber/features/modeling/row_modeling.feature +70 -70
  87. data/testing/cucumber/features/modeling/row_output.feature +40 -40
  88. data/testing/cucumber/features/modeling/rule_modeling.feature +171 -171
  89. data/testing/cucumber/features/modeling/rule_output.feature +136 -136
  90. data/testing/cucumber/features/modeling/scenario_modeling.feature +146 -146
  91. data/testing/cucumber/features/modeling/scenario_output.feature +63 -63
  92. data/testing/cucumber/features/modeling/step_modeling.feature +105 -105
  93. data/testing/cucumber/features/modeling/step_output.feature +47 -47
  94. data/testing/cucumber/features/modeling/table_modeling.feature +73 -73
  95. data/testing/cucumber/features/modeling/table_output.feature +42 -42
  96. data/testing/cucumber/features/modeling/tag_modeling.feature +62 -62
  97. data/testing/cucumber/features/modeling/tag_output.feature +40 -40
  98. metadata +6 -8
@@ -1,88 +1,88 @@
1
- module CukeModeler
2
-
3
- # A class modeling a single cell of a row.
4
- class Cell < Model
5
-
6
- include Sourceable
7
- include Parsing
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
- #
18
- # @example
19
- # Cell.new
20
- # Cell.new('some value')
21
- #
22
- # @param source_text [String] The Gherkin text that will be used to populate the model
23
- # @raise [ArgumentError] If *source_text* is not a String
24
- # @return [Cell] A new Cell instance
25
- def initialize(source_text = nil)
26
- super
27
- end
28
-
29
- # Returns a string representation of this model. For a Cell model,
30
- # this will be Gherkin text that is equivalent to the cell being modeled.
31
- #
32
- # @example
33
- # cell.to_s
34
- #
35
- # @return [String] A string representation of this model
36
- def to_s
37
- # Vertical bars and backslashes are special characters that need to be escaped
38
- @value ? @value.gsub('\\', '\\\\\\').gsub('|', '\|') : ''
39
- end
40
-
41
- # See `Object#inspect`. Returns some basic information about the
42
- # object, including its class, object ID, and its most meaningful
43
- # attribute. For a Cell model, this will be the value of the
44
- # cell. If *verbose* is true, provides default Ruby inspection
45
- # behavior instead.
46
- #
47
- # @example
48
- # cell.inspect
49
- # cell.inspect(verbose: true)
50
- #
51
- # @param verbose [Boolean] Whether or not to return the full details of
52
- # the object. Defaults to false.
53
- # @return [String] A string representation of this model
54
- def inspect(verbose: false)
55
- return super if verbose
56
-
57
- "#{super.chop} @value: #{value.inspect}>"
58
- end
59
-
60
-
61
- private
62
-
63
-
64
- def process_source(source_text)
65
- base_file_string = "# language: #{Parsing.dialect}
66
- #{dialect_feature_keyword}: Fake feature to parse
67
- #{dialect_scenario_keyword}:
68
- #{dialect_step_keyword} fake step\n"
69
- source_text = "#{base_file_string}|#{source_text}|"
70
-
71
- parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_cell.feature')
72
-
73
- parsed_file['feature']['elements'].first['steps'].first['table']['rows'].first['cells'].first
74
- end
75
-
76
- def populate_model(parsed_cell_data)
77
- populate_cell_value(parsed_cell_data)
78
- populate_source_location(parsed_cell_data)
79
- populate_parsing_data(parsed_cell_data)
80
- end
81
-
82
- def populate_cell_value(parsed_cell_data)
83
- @value = parsed_cell_data['value']
84
- end
85
-
86
- end
87
-
88
- end
1
+ module CukeModeler
2
+
3
+ # A class modeling a single cell of a row.
4
+ class Cell < Model
5
+
6
+ include Sourceable
7
+ include Parsing
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
+ #
18
+ # @example
19
+ # Cell.new
20
+ # Cell.new('some value')
21
+ #
22
+ # @param source_text [String] The Gherkin text that will be used to populate the model
23
+ # @raise [ArgumentError] If *source_text* is not a String
24
+ # @return [Cell] A new Cell instance
25
+ def initialize(source_text = nil)
26
+ super
27
+ end
28
+
29
+ # Returns a string representation of this model. For a Cell model,
30
+ # this will be Gherkin text that is equivalent to the cell being modeled.
31
+ #
32
+ # @example
33
+ # cell.to_s
34
+ #
35
+ # @return [String] A string representation of this model
36
+ def to_s
37
+ # Vertical bars and backslashes are special characters that need to be escaped
38
+ @value ? @value.gsub('\\', '\\\\\\').gsub('|', '\|') : ''
39
+ end
40
+
41
+ # See `Object#inspect`. Returns some basic information about the
42
+ # object, including its class, object ID, and its most meaningful
43
+ # attribute. For a Cell model, this will be the value of the
44
+ # cell. If *verbose* is true, provides default Ruby inspection
45
+ # behavior instead.
46
+ #
47
+ # @example
48
+ # cell.inspect
49
+ # cell.inspect(verbose: true)
50
+ #
51
+ # @param verbose [Boolean] Whether or not to return the full details of
52
+ # the object. Defaults to false.
53
+ # @return [String] A string representation of this model
54
+ def inspect(verbose: false)
55
+ return super if verbose
56
+
57
+ "#{super.chop} @value: #{value.inspect}>"
58
+ end
59
+
60
+
61
+ private
62
+
63
+
64
+ def process_source(source_text)
65
+ base_file_string = "# language: #{Parsing.dialect}
66
+ #{dialect_feature_keyword}: Fake feature to parse
67
+ #{dialect_scenario_keyword}:
68
+ #{dialect_step_keyword} fake step\n"
69
+ source_text = "#{base_file_string}|#{source_text}|"
70
+
71
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_cell.feature')
72
+
73
+ parsed_file['feature']['elements'].first['steps'].first['table']['rows'].first['cells'].first
74
+ end
75
+
76
+ def populate_model(parsed_cell_data)
77
+ populate_cell_value(parsed_cell_data)
78
+ populate_source_location(parsed_cell_data)
79
+ populate_parsing_data(parsed_cell_data)
80
+ end
81
+
82
+ def populate_cell_value(parsed_cell_data)
83
+ @value = parsed_cell_data['value']
84
+ end
85
+
86
+ end
87
+
88
+ end
@@ -1,82 +1,82 @@
1
- module CukeModeler
2
-
3
- # A class modeling a comment in a feature file.
4
- class Comment < Model
5
-
6
- include Parsing
7
- include Parsed
8
- include Sourceable
9
-
10
-
11
- # The text of the comment
12
- attr_accessor :text
13
-
14
-
15
- # Creates a new Comment object and, if *source_text* is provided, populates the
16
- # object.
17
- #
18
- # @example
19
- # Comment.new
20
- # Comment.new('# A comment')
21
- #
22
- # @param source_text [String] The Gherkin text that will be used to populate the model
23
- # @raise [ArgumentError] If *source_text* is not a String
24
- # @return [Comment] A new Comment instance
25
- def initialize(source_text = nil)
26
- super
27
- end
28
-
29
- # Returns a string representation of this model. For a Comment model,
30
- # this will be Gherkin text that is equivalent to the comment being modeled.
31
- #
32
- # @example
33
- # comment.to_s
34
- #
35
- # @return [String] A string representation of this model
36
- def to_s
37
- text || ''
38
- end
39
-
40
- # See `Object#inspect`. Returns some basic information about the
41
- # object, including its class, object ID, and its most meaningful
42
- # attribute. For a Comment model, this will be the text of the comment.
43
- # If *verbose* is true, provides default Ruby inspection behavior instead.
44
- #
45
- # @example
46
- # comment.inspect
47
- # comment.inspect(verbose: true)
48
- #
49
- # @param verbose [Boolean] Whether or not to return the full details of
50
- # the object. Defaults to false.
51
- # @return [String] A string representation of this model
52
- def inspect(verbose: false)
53
- return super if verbose
54
-
55
- "#{super.chop} @text: #{text.inspect}>"
56
- end
57
-
58
-
59
- private
60
-
61
-
62
- def process_source(source_text)
63
- base_file_string = "\n#{dialect_feature_keyword}: Fake feature to parse"
64
- source_text = "# language: #{Parsing.dialect}\n" + source_text + base_file_string
65
-
66
- parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_comment.feature')
67
-
68
- parsed_file['comments'].last
69
- end
70
-
71
- def populate_model(processed_comment_data)
72
- populate_comment_text(processed_comment_data)
73
- populate_parsing_data(processed_comment_data)
74
- populate_source_location(processed_comment_data)
75
- end
76
-
77
- def populate_comment_text(parsed_comment_data)
78
- @text = parsed_comment_data['text'].strip
79
- end
80
-
81
- end
82
- end
1
+ module CukeModeler
2
+
3
+ # A class modeling a comment in a feature file.
4
+ class Comment < Model
5
+
6
+ include Parsing
7
+ include Parsed
8
+ include Sourceable
9
+
10
+
11
+ # The text of the comment
12
+ attr_accessor :text
13
+
14
+
15
+ # Creates a new Comment object and, if *source_text* is provided, populates the
16
+ # object.
17
+ #
18
+ # @example
19
+ # Comment.new
20
+ # Comment.new('# A comment')
21
+ #
22
+ # @param source_text [String] The Gherkin text that will be used to populate the model
23
+ # @raise [ArgumentError] If *source_text* is not a String
24
+ # @return [Comment] A new Comment instance
25
+ def initialize(source_text = nil)
26
+ super
27
+ end
28
+
29
+ # Returns a string representation of this model. For a Comment model,
30
+ # this will be Gherkin text that is equivalent to the comment being modeled.
31
+ #
32
+ # @example
33
+ # comment.to_s
34
+ #
35
+ # @return [String] A string representation of this model
36
+ def to_s
37
+ text || ''
38
+ end
39
+
40
+ # See `Object#inspect`. Returns some basic information about the
41
+ # object, including its class, object ID, and its most meaningful
42
+ # attribute. For a Comment model, this will be the text of the comment.
43
+ # If *verbose* is true, provides default Ruby inspection behavior instead.
44
+ #
45
+ # @example
46
+ # comment.inspect
47
+ # comment.inspect(verbose: true)
48
+ #
49
+ # @param verbose [Boolean] Whether or not to return the full details of
50
+ # the object. Defaults to false.
51
+ # @return [String] A string representation of this model
52
+ def inspect(verbose: false)
53
+ return super if verbose
54
+
55
+ "#{super.chop} @text: #{text.inspect}>"
56
+ end
57
+
58
+
59
+ private
60
+
61
+
62
+ def process_source(source_text)
63
+ base_file_string = "\n#{dialect_feature_keyword}: Fake feature to parse"
64
+ source_text = "# language: #{Parsing.dialect}\n" + source_text + base_file_string
65
+
66
+ parsed_file = Parsing.parse_text(source_text, 'cuke_modeler_stand_alone_comment.feature')
67
+
68
+ parsed_file['comments'].last
69
+ end
70
+
71
+ def populate_model(processed_comment_data)
72
+ populate_comment_text(processed_comment_data)
73
+ populate_parsing_data(processed_comment_data)
74
+ populate_source_location(processed_comment_data)
75
+ end
76
+
77
+ def populate_comment_text(parsed_comment_data)
78
+ @text = parsed_comment_data['text'].strip
79
+ end
80
+
81
+ end
82
+ end
@@ -1,143 +1,143 @@
1
- module CukeModeler
2
-
3
- # A class modeling a directory in a Cucumber suite.
4
- class Directory < Model
5
-
6
-
7
- # The feature file models contained by the modeled directory
8
- attr_accessor :feature_files
9
-
10
- # The directory models contained by the modeled directory
11
- attr_accessor :directories
12
-
13
- # The file path of the modeled directory
14
- attr_accessor :path
15
-
16
-
17
- # Creates a new Directory object and, if *directory_path* is provided,
18
- # populates the object.
19
- #
20
- # @example
21
- # Directory.new
22
- # Directory.new('some/directory/path')
23
- #
24
- # @param directory_path [String] The directory path that will be used to populate the model
25
- # @raise [ArgumentError] If *directory_path* is not a String
26
- # @raise [ArgumentError] If the directory path does not exist
27
- # @return [Directory] A new Directory instance
28
- def initialize(directory_path = nil)
29
- @path = directory_path
30
- @feature_files = []
31
- @directories = []
32
-
33
- super
34
- end
35
-
36
- # Returns the name of the modeled directory.
37
- #
38
- # @example
39
- # d = Directory.new('some/directory/foo')
40
- # d.name #=> 'foo'
41
- #
42
- # @return [String, nil] The name of the directory
43
- def name
44
- File.basename(@path.gsub('\\', '/')) if @path
45
- end
46
-
47
- # Returns the model objects that are children of this model. For a
48
- # Directory model, these would be any associated Directory and FeatureFile
49
- # models.
50
- #
51
- # @example
52
- # directory.children
53
- #
54
- # @return [Array<Directory, FeatureFile>] A collection of child models
55
- def children
56
- @feature_files + @directories
57
- end
58
-
59
- # Returns a string representation of this model. For a Directory
60
- # model, this will be the path of the modeled directory.
61
- #
62
- # @example
63
- # directory.to_s #=> 'some/directory/path'
64
- #
65
- # @return [String] A string representation of this model
66
- def to_s
67
- path.to_s
68
- end
69
-
70
- # See `Object#inspect`. Returns some basic information about the
71
- # object, including its class, object ID, and its most meaningful
72
- # attribute. For a Directory model, this will be the path of the
73
- # directory. If *verbose* is true, provides default Ruby inspection
74
- # behavior instead.
75
- #
76
- # @example
77
- # directory.inspect
78
- # directory.inspect(verbose: true)
79
- #
80
- # @param verbose [Boolean] Whether or not to return the full details of
81
- # the object. Defaults to false.
82
- # @return [String] A string representation of this model
83
- def inspect(verbose: false)
84
- return super if verbose
85
-
86
- "#{super.chop} @path: #{@path.inspect}>"
87
- end
88
-
89
-
90
- private
91
-
92
-
93
- def process_source(directory_path)
94
- raise(ArgumentError, "Unknown directory: #{directory_path.inspect}") unless File.exist?(directory_path)
95
-
96
- process_directory(directory_path)
97
- end
98
-
99
- def process_directory(directory_path)
100
- directory_data = { 'path' => directory_path,
101
- 'directories' => [],
102
- 'feature_files' => [] }
103
-
104
- entries = Dir.entries(directory_path)
105
- entries.delete '.'
106
- entries.delete '..'
107
-
108
- entries.each do |entry|
109
- entry = "#{directory_path}/#{entry}"
110
-
111
- # Ignore anything that isn't a directory or a feature file
112
- if File.directory?(entry)
113
- directory_data['directories'] << process_directory(entry)
114
- elsif entry =~ /\.feature$/
115
- directory_data['feature_files'] << process_feature_file(entry)
116
- end
117
- end
118
-
119
-
120
- directory_data
121
- end
122
-
123
- def process_feature_file(file_path)
124
- source_text = File.read(file_path)
125
- feature_file_data = Parsing.parse_text(source_text, file_path)
126
-
127
- feature_file_data.merge({ 'path' => file_path })
128
- end
129
-
130
- def populate_model(processed_directory_data)
131
- @path = processed_directory_data['path']
132
-
133
- processed_directory_data['directories'].each do |directory_data|
134
- @directories << build_child_model(Directory, directory_data)
135
- end
136
-
137
- processed_directory_data['feature_files'].each do |feature_file_data|
138
- @feature_files << build_child_model(FeatureFile, feature_file_data)
139
- end
140
- end
141
-
142
- end
143
- end
1
+ module CukeModeler
2
+
3
+ # A class modeling a directory in a Cucumber suite.
4
+ class Directory < Model
5
+
6
+
7
+ # The feature file models contained by the modeled directory
8
+ attr_accessor :feature_files
9
+
10
+ # The directory models contained by the modeled directory
11
+ attr_accessor :directories
12
+
13
+ # The file path of the modeled directory
14
+ attr_accessor :path
15
+
16
+
17
+ # Creates a new Directory object and, if *directory_path* is provided,
18
+ # populates the object.
19
+ #
20
+ # @example
21
+ # Directory.new
22
+ # Directory.new('some/directory/path')
23
+ #
24
+ # @param directory_path [String] The directory path that will be used to populate the model
25
+ # @raise [ArgumentError] If *directory_path* is not a String
26
+ # @raise [ArgumentError] If the directory path does not exist
27
+ # @return [Directory] A new Directory instance
28
+ def initialize(directory_path = nil)
29
+ @path = directory_path
30
+ @feature_files = []
31
+ @directories = []
32
+
33
+ super
34
+ end
35
+
36
+ # Returns the name of the modeled directory.
37
+ #
38
+ # @example
39
+ # d = Directory.new('some/directory/foo')
40
+ # d.name #=> 'foo'
41
+ #
42
+ # @return [String, nil] The name of the directory
43
+ def name
44
+ File.basename(@path.gsub('\\', '/')) if @path
45
+ end
46
+
47
+ # Returns the model objects that are children of this model. For a
48
+ # Directory model, these would be any associated Directory and FeatureFile
49
+ # models.
50
+ #
51
+ # @example
52
+ # directory.children
53
+ #
54
+ # @return [Array<Directory, FeatureFile>] A collection of child models
55
+ def children
56
+ @feature_files + @directories
57
+ end
58
+
59
+ # Returns a string representation of this model. For a Directory
60
+ # model, this will be the path of the modeled directory.
61
+ #
62
+ # @example
63
+ # directory.to_s #=> 'some/directory/path'
64
+ #
65
+ # @return [String] A string representation of this model
66
+ def to_s
67
+ path.to_s
68
+ end
69
+
70
+ # See `Object#inspect`. Returns some basic information about the
71
+ # object, including its class, object ID, and its most meaningful
72
+ # attribute. For a Directory model, this will be the path of the
73
+ # directory. If *verbose* is true, provides default Ruby inspection
74
+ # behavior instead.
75
+ #
76
+ # @example
77
+ # directory.inspect
78
+ # directory.inspect(verbose: true)
79
+ #
80
+ # @param verbose [Boolean] Whether or not to return the full details of
81
+ # the object. Defaults to false.
82
+ # @return [String] A string representation of this model
83
+ def inspect(verbose: false)
84
+ return super if verbose
85
+
86
+ "#{super.chop} @path: #{@path.inspect}>"
87
+ end
88
+
89
+
90
+ private
91
+
92
+
93
+ def process_source(directory_path)
94
+ raise(ArgumentError, "Unknown directory: #{directory_path.inspect}") unless File.exist?(directory_path)
95
+
96
+ process_directory(directory_path)
97
+ end
98
+
99
+ def process_directory(directory_path)
100
+ directory_data = { 'path' => directory_path,
101
+ 'directories' => [],
102
+ 'feature_files' => [] }
103
+
104
+ entries = Dir.entries(directory_path)
105
+ entries.delete '.'
106
+ entries.delete '..'
107
+
108
+ entries.each do |entry|
109
+ entry = "#{directory_path}/#{entry}"
110
+
111
+ # Ignore anything that isn't a directory or a feature file
112
+ if File.directory?(entry)
113
+ directory_data['directories'] << process_directory(entry)
114
+ elsif entry =~ /\.feature$/
115
+ directory_data['feature_files'] << process_feature_file(entry)
116
+ end
117
+ end
118
+
119
+
120
+ directory_data
121
+ end
122
+
123
+ def process_feature_file(file_path)
124
+ source_text = File.read(file_path)
125
+ feature_file_data = Parsing.parse_text(source_text, file_path)
126
+
127
+ feature_file_data.merge({ 'path' => file_path })
128
+ end
129
+
130
+ def populate_model(processed_directory_data)
131
+ @path = processed_directory_data['path']
132
+
133
+ processed_directory_data['directories'].each do |directory_data|
134
+ @directories << build_child_model(Directory, directory_data)
135
+ end
136
+
137
+ processed_directory_data['feature_files'].each do |feature_file_data|
138
+ @feature_files << build_child_model(FeatureFile, feature_file_data)
139
+ end
140
+ end
141
+
142
+ end
143
+ end