lucid 0.2.1 → 0.3.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 (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