cuke_modeler 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ === Version 0.1.0 / 2016-02-21
2
+
3
+ * Better error feedback when parsing errors are encountered.
4
+
5
+
1
6
  === Version 0.1.0 / 2016-02-10
2
7
 
3
8
  * Support for version 3.0 of the 'gherkin' gem added.
@@ -7,7 +7,7 @@ module CukeModeler
7
7
  # Creates a new Background object and, if *source* is provided, populates
8
8
  # the object.
9
9
  def initialize(source = nil)
10
- parsed_background = process_source(source)
10
+ parsed_background = process_source(source, 'cuke_modeler_stand_alone_background.feature')
11
11
 
12
12
  super(parsed_background)
13
13
 
@@ -55,7 +55,7 @@ module CukeModeler
55
55
  base_file_string = "Feature:\nScenario:\n* step\n"
56
56
  source_text = base_file_string + source_text
57
57
 
58
- parsed_file = Parsing::parse_text(source_text)
58
+ parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_doc_string.feature')
59
59
 
60
60
  parsed_file.first['elements'].first['steps'].first['doc_string']
61
61
  end
@@ -110,7 +110,7 @@ module CukeModeler
110
110
  base_file_string = "Feature: Fake feature to parse\nScenario Outline:\n* fake step\n"
111
111
  source_text = base_file_string + source_text
112
112
 
113
- parsed_file = Parsing::parse_text(source_text)
113
+ parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_example.feature')
114
114
 
115
115
  parsed_file.first['elements'].first['examples'].first
116
116
  end
@@ -102,7 +102,7 @@ module CukeModeler
102
102
  end
103
103
 
104
104
  def parse_feature(source_text)
105
- parsed_file = Parsing::parse_text(source_text)
105
+ parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_feature.feature')
106
106
 
107
107
  parsed_file.first
108
108
  end
@@ -64,7 +64,7 @@ module CukeModeler
64
64
  def parse_file(file_to_parse)
65
65
  source_text = IO.read(file_to_parse)
66
66
 
67
- Parsing::parse_text(source_text)
67
+ Parsing::parse_text(source_text, file_to_parse)
68
68
  end
69
69
 
70
70
  def build_file(parsed_file)
@@ -14,7 +14,7 @@ module CukeModeler
14
14
  # Creates a new Outline object and, if *source* is provided, populates the
15
15
  # object.
16
16
  def initialize(source = nil)
17
- parsed_outline = process_source(source)
17
+ parsed_outline = process_source(source, 'cuke_modeler_stand_alone_outline.feature')
18
18
 
19
19
  super(parsed_outline)
20
20
 
@@ -17,10 +17,15 @@ if Gem.loaded_specs['gherkin'].version.version[/^3/]
17
17
  module Parsing
18
18
  class << self
19
19
 
20
- def parse_text(source_text)
20
+ def parse_text(source_text, filename = 'cuke_modeler_fake_file.feature')
21
21
  raise(ArgumentError, "Cannot parse #{source_text.class} objects. Strings only.") unless source_text.is_a?(String)
22
22
 
23
- parsed_result = Gherkin::Parser.new.parse(source_text)
23
+ begin
24
+ parsed_result = Gherkin::Parser.new.parse(source_text)
25
+ rescue => e
26
+ raise(ArgumentError, "Error encountered while parsing '#{filename}'\n#{e.class} - #{e.message}")
27
+ end
28
+
24
29
  adapted_result = CukeModeler::Gherkin3Adapter.new.adapt(parsed_result)
25
30
 
26
31
  adapted_result
@@ -49,13 +54,19 @@ else
49
54
 
50
55
  # Parses the Cucumber feature given in *source_text* and returns an array
51
56
  # containing the hash representation of its logical structure.
52
- def parse_text(source_text)
57
+ def parse_text(source_text, filename = 'cuke_modeler_fake_file.feature')
53
58
  raise(ArgumentError, "Cannot parse #{source_text.class} objects. Strings only.") unless source_text.is_a?(String)
54
59
 
55
60
  io = StringIO.new
56
61
  formatter = Gherkin::Formatter::JSONFormatter.new(io)
57
62
  parser = Gherkin::Parser::Parser.new(formatter)
58
- parser.parse(source_text, 'fake_file.txt', 0)
63
+
64
+ begin
65
+ parser.parse(source_text, filename, 0)
66
+ rescue => e
67
+ raise(ArgumentError, "Error encountered while parsing '#{filename}'\n#{e.class} - #{e.message}")
68
+ end
69
+
59
70
  formatter.done
60
71
 
61
72
 
@@ -45,7 +45,7 @@ module CukeModeler
45
45
  base_file_string = "Feature: Fake feature to parse\nScenario Outline:\n* fake step\nExamples: fake examples\n#{source_text}\n"
46
46
  source_text = base_file_string + source_text
47
47
 
48
- parsed_file = Parsing::parse_text(source_text)
48
+ parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_row.feature')
49
49
 
50
50
  parsed_file.first['elements'].first['examples'].first['rows'].last
51
51
  end
@@ -10,7 +10,7 @@ module CukeModeler
10
10
  # Creates a new Scenario object and, if *source* is provided, populates the
11
11
  # object.
12
12
  def initialize(source = nil)
13
- parsed_scenario = process_source(source)
13
+ parsed_scenario = process_source(source, 'cuke_modeler_stand_alone_scenario.feature')
14
14
 
15
15
  super(parsed_scenario)
16
16
 
@@ -158,7 +158,7 @@ module CukeModeler
158
158
  base_file_string = "Feature: Fake feature to parse\nScenario:\n"
159
159
  source_text = base_file_string + source_text
160
160
 
161
- parsed_file = Parsing::parse_text(source_text)
161
+ parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_step.feature')
162
162
 
163
163
  parsed_file.first['elements'].first['steps'].first
164
164
  end
@@ -51,7 +51,7 @@ module CukeModeler
51
51
  base_file_string = "Feature:\nScenario:\n* step\n"
52
52
  source_text = base_file_string + source_text
53
53
 
54
- parsed_file = Parsing::parse_text(source_text)
54
+ parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_table.feature')
55
55
 
56
56
  parsed_file.first['elements'].first['steps'].first['rows']
57
57
  end
@@ -45,7 +45,7 @@ module CukeModeler
45
45
  base_file_string = "Feature: Fake feature to parse\nScenario:\n* fake step\n"
46
46
  source_text = base_file_string + source_text
47
47
 
48
- parsed_file = Parsing::parse_text(source_text)
48
+ parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_table_row.feature')
49
49
 
50
50
  parsed_file.first['elements'].first['steps'].first['rows']['rows'].first
51
51
  end
@@ -43,7 +43,7 @@ module CukeModeler
43
43
  base_file_string = "\nFeature: Fake feature to parse"
44
44
  source_text = source_text + base_file_string
45
45
 
46
- parsed_file = Parsing::parse_text(source_text)
46
+ parsed_file = Parsing::parse_text(source_text, 'cuke_modeler_stand_alone_tag.feature')
47
47
 
48
48
  parsed_file.first['tags'].first
49
49
  end
@@ -37,20 +37,20 @@ module CukeModeler
37
37
  private
38
38
 
39
39
 
40
- def process_source(source)
40
+ def process_source(source, file_name = nil)
41
41
  case
42
42
  when source.is_a?(String)
43
- parse_test_element(source)
43
+ parse_test_element(source, file_name)
44
44
  else
45
45
  source
46
46
  end
47
47
  end
48
48
 
49
- def parse_test_element(source_text)
49
+ def parse_test_element(source_text, file_name = nil)
50
50
  base_file_string = "Feature: Fake feature to parse\n"
51
51
  source_text = base_file_string + source_text
52
52
 
53
- parsed_file = Parsing::parse_text(source_text)
53
+ parsed_file = Parsing::parse_text(source_text, file_name)
54
54
 
55
55
  parsed_file.first['elements'].first
56
56
  end
@@ -1,3 +1,3 @@
1
1
  module CukeModeler
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -26,6 +26,8 @@ RSpec.configure do |config|
26
26
  end
27
27
 
28
28
  config.before(:each) do
29
+ FileUtils.remove_dir(@default_file_directory, true) if File.exists?(@default_file_directory)
30
+
29
31
  FileUtils.mkdir(@default_file_directory)
30
32
  end
31
33
 
@@ -24,6 +24,12 @@ describe 'Background, Unit' do
24
24
  @element.name.should == 'test background'
25
25
  end
26
26
 
27
+ it 'provides a descriptive filename when being parsed from stand alone text' do
28
+ source = "bad background text \n Background:\n And a step\n @foo "
29
+
30
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_background\.feature'/)
31
+ end
32
+
27
33
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
28
34
  background = clazz.new('Background: test background')
29
35
  raw_data = background.raw_element
@@ -22,6 +22,12 @@ describe 'DocString, Unit' do
22
22
  @element.contents.should == ["some doc string"]
23
23
  end
24
24
 
25
+ it 'provides a descriptive filename when being parsed from stand alone text' do
26
+ source = 'bad doc string text'
27
+
28
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_doc_string\.feature'/)
29
+ end
30
+
25
31
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
26
32
  doc_string = clazz.new("\"\"\"\nsome doc string\n\"\"\"")
27
33
  raw_data = doc_string.raw_element
@@ -29,6 +29,12 @@ describe 'Example, Unit' do
29
29
  @element.name.should == 'test example'
30
30
  end
31
31
 
32
+ it 'provides a descriptive filename when being parsed from stand alone text' do
33
+ source = 'bad example text'
34
+
35
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_example\.feature'/)
36
+ end
37
+
32
38
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
33
39
  example = clazz.new("Examples: test example\n|param|\n|value|")
34
40
  raw_data = example.raw_element
@@ -16,12 +16,19 @@ describe 'FeatureFile, Unit' do
16
16
  @feature_file = clazz.new
17
17
  end
18
18
 
19
- it 'cannot model a non-existent directory' do
19
+ it 'cannot model a non-existent file' do
20
20
  path = "#{@default_file_directory}/missing_file.txt"
21
21
 
22
22
  expect { CukeModeler::FeatureFile.new(path) }.to raise_error(ArgumentError)
23
23
  end
24
24
 
25
+ it 'provides its own filename when being parsed' do
26
+ path = "#{@default_file_directory}/#{@default_feature_file_name}"
27
+ File.open(path, "w") { |file| file.puts 'bad feature text' }
28
+
29
+ expect { clazz.new(path) }.to raise_error(/'#{path}'/)
30
+ end
31
+
25
32
  it 'knows the name of the file that it is modeling' do
26
33
  path = "#{@default_file_directory}/#{@default_feature_file_name}"
27
34
  File.open(path, "w") { |file| file.puts "Feature:" }
@@ -35,9 +42,9 @@ describe 'FeatureFile, Unit' do
35
42
  path = "#{@default_file_directory}/#{@default_feature_file_name}"
36
43
  File.open(path, "w") { |file| file.puts "Feature:" }
37
44
 
38
- directory = CukeModeler::FeatureFile.new(path)
45
+ file = CukeModeler::FeatureFile.new(path)
39
46
 
40
- directory.path.should == path
47
+ file.path.should == path
41
48
  end
42
49
 
43
50
  it 'has features - #features' do
@@ -28,6 +28,12 @@ describe 'Feature, Unit' do
28
28
  @element.name.should == 'test feature'
29
29
  end
30
30
 
31
+ it 'provides a descriptive filename when being parsed from stand alone text' do
32
+ source = 'bad feature text'
33
+
34
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_feature\.feature'/)
35
+ end
36
+
31
37
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
32
38
  feature = clazz.new('Feature: test feature')
33
39
  raw_data = feature.raw_element
@@ -29,6 +29,12 @@ describe 'Outline, Unit' do
29
29
  @element.name.should == 'test outline'
30
30
  end
31
31
 
32
+ it 'provides a descriptive filename when being parsed from stand alone text' do
33
+ source = "bad outline text \n Scenario Outline:\n And a step\n @foo "
34
+
35
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_outline\.feature'/)
36
+ end
37
+
32
38
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
33
39
  outline = clazz.new("Scenario Outline: test outline\nExamples:\n|param|\n|value|")
34
40
  raw_data = outline.raw_element
@@ -4,18 +4,82 @@ SimpleCov.command_name('Parsing') unless RUBY_VERSION.to_s < '1.9.0'
4
4
 
5
5
  describe 'Parsing, Unit' do
6
6
 
7
+ let(:nodule) { CukeModeler::Parsing }
8
+
9
+
7
10
  it 'can parse text - #parse_text' do
8
- CukeModeler::Parsing.should respond_to(:parse_text)
11
+ nodule.should respond_to(:parse_text)
9
12
  end
10
13
 
11
14
  it 'can only parse strings' do
12
- expect{CukeModeler::Parsing.parse_text(5)}.to raise_error(ArgumentError)
13
- expect{CukeModeler::Parsing.parse_text('Feature:')}.to_not raise_error
15
+ expect { nodule.parse_text(5) }.to raise_error(ArgumentError)
16
+ expect { nodule.parse_text('Feature:') }.to_not raise_error
14
17
  end
15
18
 
16
19
  it 'returns an Array' do
17
- result = CukeModeler::Parsing.parse_text('Feature:')
20
+ result = nodule.parse_text('Feature:')
18
21
  result.is_a?(Array).should be_true
19
22
  end
20
23
 
24
+ it 'takes the text that is to be parsed and an optional file name' do
25
+ expect(nodule.method(:parse_text).arity).to eq(-2)
26
+ end
27
+
28
+ it 'raises and error if an error is encountered while parsing text' do
29
+ expect { nodule.parse_text('bad file') }.to raise_error(ArgumentError, /Error encountered while parsing '.*'/)
30
+ end
31
+
32
+ it 'includes the file parsed in the error that it raises' do
33
+ expect { nodule.parse_text('bad file', 'file foo.txt') }.to raise_error(/'file foo\.txt'/)
34
+ end
35
+
36
+ it 'includes the underlying error message in the error that it raises' do
37
+ begin
38
+ # Custom error type in order to ensure that we are throwing the correct thing
39
+ module CukeModeler
40
+ class TestError < StandardError
41
+ end
42
+ end
43
+
44
+ # Monkey patch Gherkin to throw the error that we need for testing
45
+ if Gem.loaded_specs['gherkin'].version.version[/^3/]
46
+ old_method = Gherkin::Parser.instance_method(:parse)
47
+
48
+ module Gherkin
49
+ class Parser
50
+ def parse(*args)
51
+ raise(CukeModeler::TestError, 'something went wrong')
52
+ end
53
+ end
54
+ end
55
+ else
56
+ old_method = Gherkin::Parser::Parser.instance_method(:parse)
57
+
58
+ module Gherkin
59
+ module Parser
60
+ class Parser
61
+ def parse(*args)
62
+ raise(CukeModeler::TestError, 'something went wrong')
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ expect { nodule.parse_text('bad file') }.to raise_error(/CukeModeler::TestError.*something went wrong/)
70
+ ensure
71
+ # Making sure that our changes don't escape a test and ruin the rest of the suite
72
+ if Gem.loaded_specs['gherkin'].version.version[/^3/]
73
+ Gherkin::Parser.send(:define_method, :parse, old_method)
74
+ else
75
+ Gherkin::Parser::Parser.send(:define_method, :parse, old_method)
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ it 'has a default file name if one is not provided' do
82
+ expect { nodule.parse_text('bad file') }.to raise_error(ArgumentError, /'cuke_modeler_fake_file\.feature'/)
83
+ end
84
+
21
85
  end
@@ -21,6 +21,12 @@ describe 'Row, Unit' do
21
21
  @element.cells.should == ['a', 'row']
22
22
  end
23
23
 
24
+ it 'provides a descriptive filename when being parsed from stand alone text' do
25
+ source = " |bad |row| text| \n @foo "
26
+
27
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_row\.feature'/)
28
+ end
29
+
24
30
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
25
31
  example_row = clazz.new("| a | row |")
26
32
  raw_data = example_row.raw_element
@@ -25,6 +25,12 @@ describe 'Scenario, Unit' do
25
25
  @element.name.should == 'test scenario'
26
26
  end
27
27
 
28
+ it 'provides a descriptive filename when being parsed from stand alone text' do
29
+ source = "bad scenario text \n Scenario:\n And a step\n @foo "
30
+
31
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_scenario\.feature'/)
32
+ end
33
+
28
34
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
29
35
  scenario = clazz.new("Scenario: test scenario")
30
36
  raw_data = scenario.raw_element
@@ -187,6 +187,12 @@ describe 'Step, Unit' do
187
187
  @element.base.should == 'test step'
188
188
  end
189
189
 
190
+ it 'provides a descriptive filename when being parsed from stand alone text' do
191
+ source = "bad step text\n And a step\n @foo"
192
+
193
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_step\.feature'/)
194
+ end
195
+
190
196
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
191
197
  step = clazz.new("* test step")
192
198
  raw_data = step.raw_element
@@ -21,6 +21,12 @@ describe 'TableRow, Unit' do
21
21
  @element.cells.should == ['a', 'row']
22
22
  end
23
23
 
24
+ it 'provides a descriptive filename when being parsed from stand alone text' do
25
+ source = 'bad table row text'
26
+
27
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_table_row\.feature'/)
28
+ end
29
+
24
30
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
25
31
  table_row = clazz.new("| a | row |")
26
32
  raw_data = table_row.raw_element
@@ -22,6 +22,12 @@ describe 'Table, Unit' do
22
22
  @element.contents.should == [['a table']]
23
23
  end
24
24
 
25
+ it 'provides a descriptive filename when being parsed from stand alone text' do
26
+ source = 'bad table text'
27
+
28
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_table\.feature'/)
29
+ end
30
+
25
31
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
26
32
  table = clazz.new("| a table |")
27
33
  raw_data = table.raw_element
@@ -20,6 +20,12 @@ describe 'Tag, Unit' do
20
20
  @element.name.should == '@a_tag'
21
21
  end
22
22
 
23
+ it 'provides a descriptive filename when being parsed from stand alone text' do
24
+ source = 'bad tag text'
25
+
26
+ expect { clazz.new(source) }.to raise_error(/'cuke_modeler_stand_alone_tag\.feature'/)
27
+ end
28
+
23
29
  it 'stores the original data generated by the parsing adapter', :gherkin3 => true do
24
30
  tag = clazz.new('@a_tag')
25
31
  raw_data = tag.raw_element
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuke_modeler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
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: 2016-02-10 00:00:00.000000000 Z
12
+ date: 2016-02-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gherkin