lucid 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.md +13 -0
  3. data/bin/lucid +1 -7
  4. data/lib/lucid/ast/doc_string.rb +1 -1
  5. data/lib/lucid/ast/step_invocation.rb +2 -2
  6. data/lib/lucid/cli/app.rb +6 -2
  7. data/lib/lucid/cli/configuration.rb +18 -5
  8. data/lib/lucid/cli/options.rb +56 -53
  9. data/lib/lucid/core_ext/instance_exec.rb +1 -2
  10. data/lib/lucid/core_ext/proc.rb +2 -2
  11. data/lib/lucid/errors.rb +3 -3
  12. data/lib/lucid/formatter/ansicolor.rb +20 -21
  13. data/lib/lucid/formatter/console.rb +1 -1
  14. data/lib/lucid/formatter/progress.rb +1 -1
  15. data/lib/lucid/generators/project.rb +1 -7
  16. data/lib/lucid/generators/project/browser-fluent.rb +0 -1
  17. data/lib/lucid/generators/project/events-fluent.rb +1 -4
  18. data/lib/lucid/interface_rb/matcher.rb +7 -7
  19. data/lib/lucid/interface_rb/rb_lucid.rb +2 -0
  20. data/lib/lucid/interface_rb/rb_step_definition.rb +5 -6
  21. data/lib/lucid/interface_rb/rb_world.rb +2 -3
  22. data/lib/lucid/platform.rb +3 -3
  23. data/lib/lucid/runtime/facade.rb +9 -11
  24. data/lib/lucid/runtime/orchestrator.rb +2 -3
  25. data/lib/lucid/runtime/results.rb +0 -2
  26. data/lib/lucid/spec_file.rb +1 -3
  27. data/spec/lucid/ansicolor_spec.rb +31 -0
  28. data/spec/lucid/app_spec.rb +73 -4
  29. data/spec/lucid/ast/background_spec.rb +128 -0
  30. data/spec/lucid/ast/doc_string_spec.rb +36 -0
  31. data/spec/lucid/ast/feature_spec.rb +66 -0
  32. data/spec/lucid/ast/outline_table_spec.rb +21 -0
  33. data/spec/lucid/ast/scenario_outline_spec.rb +81 -0
  34. data/spec/lucid/ast/specs_spec.rb +48 -0
  35. data/spec/lucid/ast/step_invocation_spec.rb +45 -0
  36. data/spec/lucid/ast/step_spec.rb +72 -0
  37. data/spec/lucid/ast/table_spec.rb +265 -0
  38. data/spec/lucid/ast/tdl_factory.rb +78 -0
  39. data/spec/lucid/ast/tdl_walker_spec.rb +21 -0
  40. data/spec/lucid/configuration_spec.rb +163 -8
  41. data/spec/lucid/duration_spec.rb +22 -0
  42. data/spec/lucid/facade_spec.rb +31 -0
  43. data/spec/lucid/matcher_spec.rb +127 -0
  44. data/spec/lucid/options_spec.rb +223 -3
  45. data/spec/lucid/orchestrator_spec.rb +117 -0
  46. data/spec/lucid/pending_spec.rb +45 -0
  47. data/spec/lucid/progress_spec.rb +34 -0
  48. data/spec/lucid/rb_step_definition_spec.rb +127 -0
  49. data/spec/lucid/rb_transform_spec.rb +24 -0
  50. data/spec/lucid/regexp_argument_matcher_spec.rb +19 -0
  51. data/spec/lucid/results_spec.rb +81 -0
  52. data/spec/lucid/runtime_spec.rb +1 -1
  53. data/spec/lucid/step_match_spec.rb +55 -0
  54. data/spec/spec_helper.rb +11 -5
  55. metadata +51 -7
  56. data/.ruby-gemset +0 -1
  57. data/.ruby-version +0 -1
  58. data/lib/lucid/generators/project/lucid-fluent.yml +0 -6
@@ -0,0 +1,128 @@
1
+ require 'spec_helper'
2
+
3
+ require 'lucid/ast'
4
+ require 'lucid/interface_rb/rb_language'
5
+
6
+ module Lucid
7
+ module AST
8
+ describe Background do
9
+
10
+ let(:language) { double.as_null_object }
11
+
12
+ before do
13
+ extend(Lucid::InterfaceRb::RbLucid)
14
+ @runtime = Lucid::Runtime.new
15
+ @rb = @runtime.load_code_language('rb')
16
+
17
+ $x = $y = nil
18
+ Before do
19
+ $x = 2
20
+ end
21
+ Given /y is (\d+)/ do |n|
22
+ $y = $x * n.to_i
23
+ end
24
+
25
+ @visitor = TDLWalker.new(@runtime)
26
+
27
+ @feature = double('feature', :visit? => true, :feature_elements => []).as_null_object
28
+ end
29
+
30
+ it 'should execute Before blocks before background steps' do
31
+ background = Background.new(
32
+ language,
33
+ Location.new('test.spec', 2),
34
+ comment = Comment.new(''),
35
+ keyword = '',
36
+ title = '',
37
+ description = '',
38
+ steps = [
39
+ Step.new(language,Location.new('test.spec', 7), "Given", "y is 5")
40
+ ]
41
+ )
42
+
43
+ scenario = Scenario.new(
44
+ language,
45
+ background,
46
+ comment = Comment.new(''),
47
+ tags = Tags.new(98,[]),
48
+ feature_tags = Tags.new(1,[]),
49
+ line = 99,
50
+ keyword = '',
51
+ title = '',
52
+ description = '',
53
+ steps=[]
54
+ )
55
+
56
+ background.feature = @feature
57
+ background.accept(@visitor)
58
+ $x.should == 2
59
+ $y.should == 10
60
+ end
61
+
62
+ describe 'should respond to #name' do
63
+ it 'with a value' do
64
+ background = Background.new(
65
+ language,
66
+ Location.new('test.spec', 2),
67
+ comment = Comment.new(''),
68
+ keyword = '',
69
+ title = 'background name',
70
+ description = '',
71
+ steps=[]
72
+ )
73
+
74
+ lambda{ background.name }.should_not raise_error
75
+ background.name.should == 'background name'
76
+ end
77
+
78
+ it 'without a value' do
79
+ background = Background.new(
80
+ language,
81
+ comment = Comment.new(''),
82
+ line = 2,
83
+ keyword = '',
84
+ title = '',
85
+ description = '',
86
+ steps=[]
87
+ )
88
+
89
+ lambda{ background.name }.should_not raise_error
90
+ end
91
+ end
92
+
93
+ describe 'failures in a Before hook' do
94
+ before do
95
+ Before do
96
+ raise Exception, 'Exception from Before hook'
97
+ end
98
+ end
99
+
100
+ it 'should state that the background has failed' do
101
+ background = Background.new(
102
+ language,
103
+ Location.new('test.spec', 2),
104
+ comment = Comment.new(''),
105
+ keyword = '',
106
+ title = '',
107
+ description = '',
108
+ steps = [
109
+ Step.new(language, Location.new('test.spec', 7), "Given", "y is 5")
110
+ ]
111
+ )
112
+
113
+ background.feature = @feature
114
+
115
+ @visitor.should_receive( :visit_exception ) do |exception, status|
116
+ exception.should be_instance_of( Exception )
117
+ exception.message.should == "Exception from Before hook"
118
+ status.should == :failed
119
+ end
120
+
121
+ lambda{ background.accept(@visitor) }.should_not raise_error
122
+ background.should be_failed
123
+ end
124
+ end
125
+
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'lucid/ast/doc_string'
3
+
4
+ module Lucid
5
+ module AST
6
+ describe DocString do
7
+
8
+ describe 'replacing arguments' do
9
+ before(:each) do
10
+ @ps = DocString.new("<book>\n<qty>\n", '')
11
+ end
12
+
13
+ it 'should return a new doc_string with arguments replaced with values' do
14
+ doc_string_with_replaced_arg = @ps.arguments_replaced({'<book>' => 'Leviathan', '<qty>' => '5'})
15
+ doc_string_with_replaced_arg.to_step_definition_arg.should == "Leviathan\n5\n"
16
+ end
17
+
18
+ it 'should not change the original doc_string' do
19
+ doc_string_with_replaced_arg = @ps.arguments_replaced({'<book>' => 'Leviathan'})
20
+ @ps.to_s.should_not include('Leviathan')
21
+ end
22
+
23
+ it 'should replace nil with empty string' do
24
+ ps = DocString.new("'<book>'", '')
25
+ doc_string_with_replaced_arg = ps.arguments_replaced({'<book>' => nil})
26
+ doc_string_with_replaced_arg.to_step_definition_arg.should == "''"
27
+ end
28
+
29
+ it 'should recognise when just a subset of a cell is delimited' do
30
+ @ps.should have_text('<qty>')
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'lucid/ast/tdl_factory'
3
+
4
+ module Lucid
5
+ module AST
6
+ describe Feature do
7
+ include TDLFactory
8
+
9
+ it 'should convert to a symbolic expression' do
10
+ runtime = Lucid::Runtime.new
11
+ runtime.load_code_language('rb')
12
+ dsl = Object.new
13
+ dsl.extend Lucid::InterfaceRb::RbLucid
14
+
15
+ feature = create_feature(dsl)
16
+ if Lucid::WINDOWS
17
+ feature_file_path = 'specs\\test.spec'
18
+ else
19
+ feature_file_path = 'specs/test.spec'
20
+ end
21
+
22
+ feature.to_sexp.should ==
23
+ [
24
+ :feature,
25
+ feature_file_path,
26
+ 'Testing TDL',
27
+ [:comment, "# Feature Comment Line\n"],
28
+ [:tag, 'smoke'],
29
+ [:tag, 'critical'],
30
+ [:background, 2, 'Background:',
31
+ [:step, 3, 'Given', 'a passing step']],
32
+ [:scenario, 9, 'Scenario:',
33
+ 'Test Scenario',
34
+ [:comment, " # Scenario Comment Line 1 \n# Scenario Comment Line 2 \n"],
35
+ [:tag, 'regression'],
36
+ [:tag, 'selenium'],
37
+ [:step_invocation, 3, 'Given', 'a passing step'],
38
+ [:step_invocation, 10, 'Given', 'a passing step with an inline argument:',
39
+ [:table,
40
+ [:row, -1,
41
+ [:cell, '1'], [:cell, '22'], [:cell, '333']],
42
+ [:row, -1,
43
+ [:cell, '4444'], [:cell, '55555'], [:cell, '666666']]]],
44
+ [:step_invocation, 11, 'Given', 'a working step with an inline argument:',
45
+ [:doc_string, "\n Testing with\nLucid tools\n"]],
46
+ [:step_invocation, 12, 'Given', 'a non-passing step']]
47
+ ]
48
+ end
49
+
50
+ it 'should store operating system specific file paths' do
51
+ runtime = Lucid::Runtime.new
52
+ runtime.load_code_language('rb')
53
+ dsl = Object.new
54
+ dsl.extend Lucid::InterfaceRb::RbLucid
55
+ feature = create_feature(dsl)
56
+
57
+ if Lucid::WINDOWS
58
+ feature.file.should == 'specs\test.spec'
59
+ else
60
+ feature.file.should == 'specs/test.spec'
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ module Lucid::AST
4
+ describe OutlineTable do
5
+ describe OutlineTable::ExampleRow do
6
+ describe 'a header row' do
7
+ before(:each) do
8
+ @row = OutlineTable::ExampleRow.new(
9
+ double('table', :index => 0),
10
+ [double('cell', :status= => nil, :accept => nil)]
11
+ )
12
+ end
13
+
14
+ it 'should raise an error if you try to call #failed?' do
15
+ @row.accept_plain double('visitor', :visit_table_cell => nil)
16
+ lambda{ @row.failed? }.should raise_error(NoMethodError, /cannot pass or fail/)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ require 'lucid/ast'
4
+ require 'lucid/core_ext/string'
5
+ require 'lucid/interface_rb/rb_language'
6
+
7
+ module Lucid
8
+ module AST
9
+
10
+ describe ScenarioOutline do
11
+
12
+ before do
13
+ @runtime = Lucid::Runtime.new
14
+ @runtime.load_code_language('rb')
15
+ @dsl = Object.new
16
+ @dsl.extend(Lucid::InterfaceRb::RbLucid)
17
+
18
+ @dsl.Given(/^there are (\d+) tests$/) do |n|
19
+ @initial = n.to_i
20
+ end
21
+
22
+ @dsl.When(/^testing (\d+) scenarios$/) do |n|
23
+ @tested = n.to_i
24
+ end
25
+
26
+ @dsl.Then(/^there should be (\d+) tests$/) do |n|
27
+ (@initial - @tested).should == n.to_i
28
+ end
29
+
30
+ @dsl.Then(/^there should be (\d+) tests completed$/) do |n|
31
+ @tested.should == n.to_i
32
+ end
33
+
34
+ location = AST::Location.new('test.spec', 19)
35
+ language = double
36
+
37
+ @scenario_outline = ScenarioOutline.new(
38
+ language,
39
+ location,
40
+ background=AST::EmptyBackground.new,
41
+ Comment.new(''),
42
+ Tags.new(18, []),
43
+ Tags.new(0, []),
44
+ 'Scenario:', 'Test Outline', '',
45
+ [
46
+ Step.new(language, location.on_line(20), 'Given', 'there are <start> tests'),
47
+ Step.new(language, location.on_line(21), 'When', 'testing <tests> scenarios'),
48
+ Step.new(language, location.on_line(22), 'Then', 'there should be <left> tests'),
49
+ Step.new(language, location.on_line(23), 'And', 'there should be <tests> tests completed')
50
+ ],
51
+ [
52
+ [
53
+ [
54
+ location.on_line(24),
55
+ Comment.new("# Testing\n"),
56
+ 'Examples:',
57
+ 'First table',
58
+ '',
59
+ [
60
+ %w{start tests left},
61
+ %w{12 5 7},
62
+ %w{20 6 14}
63
+ ]
64
+ ],
65
+ Gherkin::Formatter::Model::Examples.new(nil, nil, nil, nil, nil, nil, nil, nil)
66
+ ]
67
+ ]
68
+ )
69
+ end
70
+
71
+ it 'should replace all variables and call outline once for each table row' do
72
+ visitor = TDLWalker.new(@runtime)
73
+ visitor.should_receive(:visit_table_row).exactly(3).times
74
+ @scenario_outline.feature = double.as_null_object
75
+ @scenario_outline.accept(visitor)
76
+ end
77
+
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ module Lucid
4
+ module AST
5
+ describe Specs do
6
+ let(:specs) { Specs.new }
7
+
8
+ def parse_feature(gherkin)
9
+ path = 'specs/test.spec'
10
+ builder = Lucid::Parser::TDLBuilder.new(path)
11
+ parser = Gherkin::Parser::Parser.new(builder, true, 'root', false)
12
+ parser.parse(gherkin, path, 0)
13
+ builder.language = parser.i18n_language
14
+ feature = builder.result
15
+ specs.add_feature(feature)
16
+ end
17
+
18
+ it 'has a step_count' do
19
+ parse_feature(<<-GHERKIN)
20
+ Feature:
21
+ Background:
22
+ Given step 1
23
+ And step 2
24
+
25
+ Scenario:
26
+ Given step 3
27
+ And step 4
28
+ And step 5
29
+
30
+ Scenario Outline:
31
+ Given step <n>
32
+ And another step
33
+
34
+ Examples:
35
+ | n |
36
+ | 6 |
37
+ | 7 |
38
+
39
+ Examples:
40
+ | n |
41
+ | 8 |
42
+ GHERKIN
43
+
44
+ specs.step_count.should == (2 + 3) + (3 * (2 + 2))
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'lucid/ast/step_invocation'
3
+
4
+ module Lucid
5
+ module AST
6
+ describe StepInvocation do
7
+ let(:step_invocation) do
8
+ matched_cells = []
9
+ StepInvocation.new(double, double, double, matched_cells)
10
+ end
11
+
12
+ describe 'filtering backtraces' do
13
+ context 'when enabled' do
14
+ before { Lucid.stub use_full_backtrace: false }
15
+
16
+ it "removes lines with 'gems' in the path" do
17
+ original_backtrace = ['/foo/bar/gems/baz', '/path/to/my/file.rb']
18
+ exception = StandardError.new
19
+ exception.set_backtrace(original_backtrace)
20
+ result = step_invocation.filter_backtrace(exception).backtrace
21
+ result.should == ['/path/to/my/file.rb']
22
+ end
23
+
24
+ it "removes lines with '.gem' in the path" do
25
+ original_backtrace = ['/foo/bar/.gem/baz', '/path/to/my/file.rb']
26
+ exception = StandardError.new
27
+ exception.set_backtrace(original_backtrace)
28
+ result = step_invocation.filter_backtrace(exception).backtrace
29
+ result.should == ['/path/to/my/file.rb']
30
+ end
31
+ end
32
+
33
+ context 'when disabled' do
34
+ before { Lucid.stub use_full_backtrace: true }
35
+
36
+ it 'return the exception unmodified' do
37
+ exception = double
38
+ step_invocation.filter_backtrace(exception).should == exception
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ require 'lucid/ast'
4
+ require 'lucid/core_ext/string'
5
+
6
+ module Lucid
7
+ module AST
8
+
9
+ describe Step do
10
+ let(:language) { double }
11
+
12
+ it 'should replace arguments in name' do
13
+ step = Step.new(language, 1, 'Given', 'a <status> test')
14
+
15
+ invocation_table = Table.new([
16
+ %w{status build},
17
+ %w{passing failing}
18
+ ])
19
+
20
+ cells = invocation_table.cells_rows[1]
21
+ step_invocation = step.step_invocation_from_cells(cells)
22
+
23
+ step_invocation.name.should == 'a passing test'
24
+ end
25
+
26
+ it 'should use empty string for the replacement of arguments in name when replace value is nil' do
27
+ step = Step.new(language, 1, 'Given', 'a <status> test')
28
+
29
+ invocation_table = Table.new([
30
+ %w(status),
31
+ [nil]
32
+ ])
33
+
34
+ cells = invocation_table.cells_rows[1]
35
+ step_invocation = step.step_invocation_from_cells(cells)
36
+
37
+ step_invocation.name.should == 'a test'
38
+ end
39
+
40
+ it 'should replace arguments in provided table arguments' do
41
+ arg_table = Table.new([%w{status_<status> type_<type>}])
42
+ step = Step.new(language, 1, 'Given', 'a <status> test', arg_table)
43
+
44
+ invocation_table = Table.new([
45
+ %w{status type},
46
+ %w{passing regression}
47
+ ])
48
+
49
+ cells = invocation_table.cells_rows[1]
50
+ step_invocation = step.step_invocation_from_cells(cells)
51
+
52
+ step_invocation.instance_variable_get('@multiline_arg').raw.should == [%w{status_passing type_regression}]
53
+ end
54
+
55
+ it 'should replace arguments in a doc string argument' do
56
+ doc_string = DocString.new('status_<status> type_<type>', '')
57
+ step = Step.new(language, 1, 'Given', 'a <status> test', doc_string)
58
+
59
+ invocation_table = Table.new([
60
+ %w{status type},
61
+ %w{passing regression}
62
+ ])
63
+
64
+ cells = invocation_table.cells_rows[1]
65
+ step_invocation = step.step_invocation_from_cells(cells)
66
+
67
+ step_invocation.instance_variable_get('@multiline_arg').to_step_definition_arg.should == 'status_passing type_regression'
68
+ end
69
+
70
+ end
71
+ end
72
+ end