lucid 0.3.3 → 0.4.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.md +13 -9
  3. data/README.md +2 -6
  4. data/lib/lucid.rb +22 -3
  5. data/lib/lucid/{term/ansicolor.rb → ansicolor.rb} +34 -41
  6. data/lib/lucid/ast.rb +2 -2
  7. data/lib/lucid/ast/outline_table.rb +2 -2
  8. data/lib/lucid/ast/{specs.rb → spec.rb} +10 -1
  9. data/lib/lucid/ast/step.rb +3 -3
  10. data/lib/lucid/ast/step_invocation.rb +16 -16
  11. data/lib/lucid/ast/table.rb +1 -1
  12. data/lib/lucid/ast/{tdl_walker.rb → walker.rb} +15 -16
  13. data/lib/lucid/cli/app.rb +23 -21
  14. data/lib/lucid/cli/{configuration.rb → context.rb} +66 -38
  15. data/lib/lucid/cli/options.rb +59 -40
  16. data/lib/lucid/{configuration.rb → context.rb} +2 -3
  17. data/lib/lucid/{runtime.rb → context_loader.rb} +58 -61
  18. data/lib/lucid/{runtime/facade.rb → facade.rb} +5 -6
  19. data/lib/lucid/formatter/ansicolor.rb +15 -14
  20. data/lib/lucid/formatter/debug.rb +1 -1
  21. data/lib/lucid/formatter/usage.rb +2 -2
  22. data/lib/lucid/interface.rb +121 -0
  23. data/lib/lucid/{runtime/interface_io.rb → interface_io.rb} +2 -2
  24. data/lib/lucid/interface_rb/rb_language.rb +6 -23
  25. data/lib/lucid/interface_rb/rb_step_definition.rb +1 -2
  26. data/lib/lucid/{core_ext/instance_exec.rb → lang_extend.rb} +112 -69
  27. data/lib/lucid/{runtime/orchestrator.rb → orchestrator.rb} +36 -24
  28. data/lib/lucid/platform.rb +1 -1
  29. data/lib/lucid/{runtime/results.rb → results.rb} +10 -10
  30. data/lib/lucid/{tdl_builder.rb → spec_builder.rb} +26 -22
  31. data/lib/lucid/spec_file.rb +33 -13
  32. data/lib/lucid/{runtime/specs_loader.rb → spec_loader.rb} +13 -22
  33. data/lib/lucid/{step_definition_light.rb → step_definition_usage.rb} +2 -4
  34. data/lib/lucid/step_definitions.rb +4 -4
  35. data/spec/lucid/app_spec.rb +6 -18
  36. data/spec/lucid/ast/background_spec.rb +4 -4
  37. data/spec/lucid/ast/feature_spec.rb +7 -7
  38. data/spec/lucid/ast/scenario_outline_spec.rb +9 -9
  39. data/spec/lucid/ast/specs_spec.rb +8 -8
  40. data/spec/lucid/ast/step_spec.rb +5 -5
  41. data/spec/lucid/ast/tdl_walker_spec.rb +5 -5
  42. data/spec/lucid/{configuration_spec.rb → context_spec.rb} +78 -78
  43. data/spec/lucid/facade_spec.rb +7 -7
  44. data/spec/lucid/orchestrator_spec.rb +7 -7
  45. data/spec/lucid/pending_spec.rb +3 -3
  46. data/spec/lucid/progress_spec.rb +3 -3
  47. data/spec/lucid/rb_step_definition_spec.rb +4 -4
  48. data/spec/lucid/results_spec.rb +2 -2
  49. data/spec/lucid/runtime_spec.rb +7 -7
  50. metadata +20 -32
  51. data/bin/lucid-gen +0 -4
  52. data/lib/lucid/core_ext/proc.rb +0 -36
  53. data/lib/lucid/core_ext/string.rb +0 -9
  54. data/lib/lucid/generator.rb +0 -21
  55. data/lib/lucid/generators/project.rb +0 -64
  56. data/lib/lucid/generators/project/Gemfile.tt +0 -6
  57. data/lib/lucid/generators/project/browser-fluent.rb +0 -37
  58. data/lib/lucid/generators/project/driver-fluent.rb +0 -1
  59. data/lib/lucid/generators/project/errors.rb +0 -26
  60. data/lib/lucid/generators/project/events-fluent.rb +0 -33
  61. data/lib/lucid/interface_methods.rb +0 -125
@@ -5,8 +5,8 @@ require 'lucid/ast/empty_background'
5
5
 
6
6
  module Lucid
7
7
  module Parser
8
- # The TDL Builder conforms to the Gherkin event API.
9
- class TDLBuilder
8
+ # The SpecBuilder conforms to the Gherkin event API.
9
+ class SpecBuilder
10
10
  include Gherkin::Rubify
11
11
 
12
12
  def initialize(path = 'UNKNOWN-FILE')
@@ -26,16 +26,19 @@ module Lucid
26
26
  @path = uri
27
27
  end
28
28
 
29
+ # @param node [Object] instance of Gherkin::Formatter::Model::Feature
29
30
  def feature(node)
30
31
  @feature_builder = FeatureBuilder.new(file, node)
31
32
  end
32
33
 
34
+ # @param node [Object] instance of Gherkin::Formatter::Model::Background
33
35
  def background(node)
34
36
  builder = BackgroundBuilder.new(file, node)
35
37
  @feature_builder.background_builder = builder
36
38
  @current = builder
37
39
  end
38
40
 
41
+ # @param node [Object] instance of Gherkin::Formatter::Model::Scenario
39
42
  def scenario(node)
40
43
  builder = ScenarioBuilder.new(file, node)
41
44
  @feature_builder.add_child builder
@@ -50,8 +53,8 @@ module Lucid
50
53
 
51
54
  def examples(examples)
52
55
  examples_fields = [
53
- AST::Location.new(file, examples.line),
54
- AST::Comment.new(examples.comments.map{|comment| comment.value}.join("\n")),
56
+ Lucid::AST::Location.new(file, examples.line),
57
+ Lucid::AST::Comment.new(examples.comments.map{|comment| comment.value}.join("\n")),
55
58
  examples.keyword,
56
59
  examples.name,
57
60
  examples.description,
@@ -60,6 +63,7 @@ module Lucid
60
63
  @current.add_examples examples_fields, examples
61
64
  end
62
65
 
66
+ # @param node [Object] instance of Gherkin::Formatter::Model::Step
63
67
  def step(node)
64
68
  builder = StepBuilder.new(file, node)
65
69
  @current.add_child builder
@@ -69,7 +73,7 @@ module Lucid
69
73
  end
70
74
 
71
75
  def syntax_error(state, event, legal_events, line)
72
- # raise "SYNTAX ERROR"
76
+ # Unsure if I should raise something here.
73
77
  end
74
78
 
75
79
  private
@@ -91,7 +95,7 @@ module Lucid
91
95
  end
92
96
 
93
97
  def language
94
- @language || raise("Language has not been set")
98
+ @language || raise('Language has not been set.')
95
99
  end
96
100
 
97
101
  def file
@@ -102,7 +106,7 @@ module Lucid
102
106
  end
103
107
  end
104
108
 
105
- class Builder
109
+ class Spec
106
110
  def initialize(file, node)
107
111
  @file, @node = file, node
108
112
  end
@@ -110,24 +114,24 @@ module Lucid
110
114
  private
111
115
 
112
116
  def tags
113
- AST::Tags.new(nil, node.tags)
117
+ Lucid::AST::Tags.new(nil, node.tags)
114
118
  end
115
119
 
116
120
  def location
117
- AST::Location.new(file, node.line)
121
+ Lucid::AST::Location.new(file, node.line)
118
122
  end
119
123
 
120
124
  def comment
121
- AST::Comment.new(node.comments.map{ |comment| comment.value }.join("\n"))
125
+ Lucid::AST::Comment.new(node.comments.map{ |comment| comment.value }.join("\n"))
122
126
  end
123
127
 
124
128
  attr_reader :file, :node
125
129
  end
126
130
 
127
- class FeatureBuilder < Builder
131
+ class FeatureBuilder < Spec
128
132
  def result(language)
129
133
  background = background(language)
130
- feature = AST::Feature.new(
134
+ feature = Lucid::AST::Feature.new(
131
135
  location,
132
136
  background,
133
137
  comment,
@@ -157,14 +161,14 @@ module Lucid
157
161
  private
158
162
 
159
163
  def background(language)
160
- return AST::EmptyBackground.new unless @background_builder
164
+ return Lucid::AST::EmptyBackground.new unless @background_builder
161
165
  @background ||= @background_builder.result(language)
162
166
  end
163
167
  end
164
168
 
165
- class BackgroundBuilder < Builder
169
+ class BackgroundBuilder < Spec
166
170
  def result(language)
167
- background = AST::Background.new(
171
+ background = Lucid::AST::Background.new(
168
172
  language,
169
173
  location,
170
174
  comment,
@@ -191,9 +195,9 @@ module Lucid
191
195
 
192
196
  end
193
197
 
194
- class ScenarioBuilder < Builder
198
+ class ScenarioBuilder < Spec
195
199
  def result(background, language, feature_tags)
196
- scenario = AST::Scenario.new(
200
+ scenario = Lucid::AST::Scenario.new(
197
201
  language,
198
202
  location,
199
203
  background,
@@ -222,9 +226,9 @@ module Lucid
222
226
  end
223
227
  end
224
228
 
225
- class ScenarioOutlineBuilder < Builder
229
+ class ScenarioOutlineBuilder < Spec
226
230
  def result(background, language, feature_tags)
227
- scenario_outline = AST::ScenarioOutline.new(
231
+ scenario_outline = Lucid::AST::ScenarioOutline.new(
228
232
  language,
229
233
  location,
230
234
  background,
@@ -263,14 +267,14 @@ module Lucid
263
267
  attr_reader :examples_sections
264
268
  end
265
269
 
266
- class StepBuilder < Builder
270
+ class StepBuilder < Spec
267
271
  def result(language)
268
- step = AST::Step.new(
272
+ step = Lucid::AST::Step.new(
269
273
  language,
270
274
  location,
271
275
  node.keyword,
272
276
  node.name,
273
- AST::MultilineArgument.from(node.doc_string || node.rows)
277
+ Lucid::AST::MultilineArgument.from(node.doc_string || node.rows)
274
278
  )
275
279
  step.gherkin_statement(node)
276
280
  step
@@ -1,4 +1,4 @@
1
- require 'lucid/tdl_builder'
1
+ require 'lucid/spec_builder'
2
2
  require 'gherkin/formatter/filter_formatter'
3
3
  require 'gherkin/formatter/tag_count_formatter'
4
4
  require 'gherkin/parser/parser'
@@ -29,30 +29,31 @@ module Lucid
29
29
  def parse(specified_filters, tag_counts)
30
30
  filters = @lines || specified_filters
31
31
 
32
- tdl_builder = Lucid::Parser::TDLBuilder.new(@path)
33
- filter_formatter = filters.empty? ? tdl_builder : Gherkin::Formatter::FilterFormatter.new(tdl_builder, filters)
32
+ spec_builder = Lucid::Parser::SpecBuilder.new(@path)
33
+ filter_formatter = filters.empty? ? spec_builder : Gherkin::Formatter::FilterFormatter.new(spec_builder, filters)
34
34
  tag_count_formatter = Gherkin::Formatter::TagCountFormatter.new(filter_formatter, tag_counts)
35
35
 
36
36
  # Gherkin Parser parameters:
37
37
  # formatter, raise_on_error, machine_name, force_ruby
38
38
  # The machine name refers to a state machine table.
39
- parser = Gherkin::Parser::Parser.new(tag_count_formatter, true, "root", false)
39
+ parser = Gherkin::Parser::Parser.new(tag_count_formatter, true, 'root', false)
40
40
 
41
41
  begin
42
42
  # parse parameters:
43
43
  # gherkin, feature_uri, line_offset
44
44
  parser.parse(source, @path, 0)
45
- tdl_builder.language = parser.i18n_language
46
- tdl_builder.result
47
- rescue Gherkin::Lexer::LexingError, Gherkin::Parser::ParseError => e
48
- e.message.insert(0, "#{@path}: ")
49
- raise e
45
+ spec_builder.language = parser.i18n_language
46
+ spec_builder.result
47
+ rescue Gherkin::Lexer::LexingError => e
48
+ handle_lexing_error(e)
49
+ rescue Gherkin::Parser::ParseError => e
50
+ handle_parsing_error(e)
50
51
  end
51
52
  end
52
53
 
53
54
  # The source method is used to return a properly encoded spec file.
54
55
  # If the spec source read in declares a different encoding, then this
55
- # method will make sure to use Lucid's default encoding.
56
+ # method will make sure to use the default encoding of Lucid.
56
57
  def source
57
58
  @source ||= if @path =~ /^http/
58
59
  require 'open-uri'
@@ -70,13 +71,13 @@ module Lucid
70
71
  e.message << "\nLucid was unable to access #{File.expand_path(@path)}."
71
72
  raise e
72
73
  rescue Errno::ENOENT => e
73
- if @path == "specs"
74
+ if @path == 'specs'
74
75
  STDOUT.puts ["\nYou don't have a 'specs' directory. This is the default specification",
75
- "directory that Lucid will use if one is not specified. So either create",
76
+ 'directory that Lucid will use if one is not specified. So either create',
76
77
  "that directory or specify where your test repository is located.\n\n"].join("\n")
77
78
  else
78
79
  STDOUT.puts ["\nThere is no '#{@path}' directory. Since that is what you specified as",
79
- "your spec repository, this directory must be present."].join("\n")
80
+ 'your spec repository, this directory must be present.'].join("\n")
80
81
  end
81
82
  Kernel.exit(1)
82
83
  end
@@ -85,6 +86,25 @@ module Lucid
85
86
 
86
87
  private
87
88
 
89
+ def handle_lexing_error(e)
90
+ core_exception = e.message[0..e.message.index('See http:') - 1]
91
+ core_exception.insert(0, "Lucid was looking at: #{@path}\n\n")
92
+ puts 'Lucid: Lexing Error with Gherkin'
93
+ puts core_exception
94
+ Kernel.exit(1)
95
+ end
96
+
97
+ def handle_parsing_error(e)
98
+ core_exception = "Lucid was looking at: #{@path}\n\n"
99
+ core_message_start = e.message.index('Found')
100
+ core_state_start = e.message.index('(Current')
101
+ core_message = e.message[core_message_start..core_state_start - 1]
102
+ core_state = e.message[core_state_start..-1]
103
+ puts 'Lucid: Parsing Error with Gherkin'
104
+ puts core_exception, core_message, core_state
105
+ Kernel.exit(1)
106
+ end
107
+
88
108
  def encoding_for(source)
89
109
  encoding = DEFAULT_ENCODING
90
110
 
@@ -1,32 +1,28 @@
1
1
  require 'lucid/errors'
2
2
 
3
3
  module Lucid
4
- class Runtime
5
- class SpecsLoader
4
+ class ContextLoader
5
+ class SpecLoader
6
6
  include Formatter::Duration
7
7
 
8
8
  def initialize(spec_files, filters, tag_expression)
9
9
  @spec_files, @filters, @tag_expression = spec_files, filters, tag_expression
10
10
  end
11
11
 
12
- # @see Lucid::Runtime.specs
13
- def specs
14
- load unless (defined? @specs) and @specs
15
- @specs
12
+ # @see Lucid::ContextLoader.load_spec_context
13
+ def load_specs
14
+ load unless (defined? @spec) and @spec
15
+ @spec
16
16
  end
17
17
 
18
- private
18
+ private
19
19
 
20
20
  # The specs loader will call upon load to load up all specs that were
21
- # found in the spec repository. During this process, a Specs instance
21
+ # found in the spec repository. During this process, a Spec instance
22
22
  # is created that will hold instances of the high level construct,
23
23
  # which is basically the feature.
24
24
  def load
25
- specs = AST::Specs.new
26
-
27
- # Note that "specs" is going to be an instance of Lucid::AST::Specs.
28
- # It will contain a @specs instance variable that is going to contain
29
- # an specs found.
25
+ spec = Lucid::AST::Spec.new
30
26
 
31
27
  tag_counts = {}
32
28
  start = Time.new
@@ -35,15 +31,10 @@ module Lucid
35
31
  @spec_files.each do |f|
36
32
  spec_file = SpecFile.new(f)
37
33
 
38
- # The "spec_file" will contain a Lucid::SpecFile instance, a
39
- # primary attribute of which will be a @location instance variable.
40
-
41
- spec = spec_file.parse(@filters, tag_counts)
42
-
43
- # The "spec" will contain an instance of Lucid::AST::Feature.
34
+ feature = spec_file.parse(@filters, tag_counts)
44
35
 
45
- if spec
46
- specs.add_feature(spec)
36
+ if feature
37
+ spec.add_feature(feature)
47
38
  log.info(" * #{f}\n")
48
39
  end
49
40
  end
@@ -53,7 +44,7 @@ module Lucid
53
44
 
54
45
  check_tag_limits(tag_counts)
55
46
 
56
- @specs = specs
47
+ @spec = spec
57
48
  end
58
49
 
59
50
  def check_tag_limits(tag_counts)
@@ -1,8 +1,6 @@
1
1
  module Lucid
2
- # Only used for keeping track of available and invoked step definitions
3
- # in a way that also works for other programming languages (i.e. cuke4duke)
4
- # Used for reporting purposes only (usage formatter).
5
- class StepDefinitionLight
2
+ # Only used for keeping track of available and invoked step definitions.
3
+ class StepDefinitionUsage
6
4
  attr_reader :regexp_source, :file_colon_line
7
5
 
8
6
  def initialize(regexp_source, file_colon_line)
@@ -1,9 +1,9 @@
1
1
  module Lucid
2
2
  class StepDefinitions
3
- def initialize(configuration = Configuration.default)
4
- configuration = Configuration.parse(configuration)
5
- @orchestrator = Runtime::Orchestrator.new(nil, false)
6
- @orchestrator.load_files_from_paths(configuration.autoload_code_paths)
3
+ def initialize(context = Context.default)
4
+ context = Context.parse(context)
5
+ @orchestrator = ContextLoader::Orchestrator.new(nil, false)
6
+ @orchestrator.load_files_from_paths(context.autoload_code_paths)
7
7
  end
8
8
 
9
9
  def to_json
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'lucid/tdl_builder'
2
+ require 'lucid/spec_builder'
3
3
  require 'gherkin/formatter/model'
4
4
 
5
5
  module Lucid
@@ -23,7 +23,7 @@ module Lucid
23
23
 
24
24
  it 'configures the runtime' do
25
25
  configuration = double('Configuration').as_null_object
26
- Configuration.stub(:new => configuration)
26
+ Context.stub(:new => configuration)
27
27
  runtime.should_receive(:configure).with(configuration)
28
28
  kernel.should_receive(:exit).with(1)
29
29
  do_start
@@ -31,7 +31,7 @@ module Lucid
31
31
 
32
32
  it 'uses that runtime for running and reporting results' do
33
33
  results = double('results', :failure? => true)
34
- runtime.should_receive(:run)
34
+ runtime.should_receive(:execute)
35
35
  runtime.stub(:results).and_return(results)
36
36
  kernel.should_receive(:exit).with(1)
37
37
  do_start
@@ -45,8 +45,8 @@ module Lucid
45
45
 
46
46
  it 'should register as a failure' do
47
47
  results = double('results', :failure? => false)
48
- runtime = Runtime.any_instance
49
- runtime.stub(:run)
48
+ runtime = ContextLoader.any_instance
49
+ runtime.stub(:excute)
50
50
  runtime.stub(:results).and_return(results)
51
51
 
52
52
  Lucid.wants_to_quit = true
@@ -58,7 +58,7 @@ module Lucid
58
58
 
59
59
  describe 'verbose execution' do
60
60
  before(:each) do
61
- b = Lucid::Parser::TDLBuilder.new('specs/test.spec')
61
+ b = Lucid::Parser::SpecBuilder.new('specs/test.spec')
62
62
  b.feature(Gherkin::Formatter::Model::Feature.new([], [], 'Feature', 'Testing', '', 99, ''))
63
63
  b.language = double
64
64
  @empty_feature = b.result
@@ -77,18 +77,6 @@ module Lucid
77
77
  end
78
78
  end
79
79
 
80
- describe 'handling exceptions' do
81
- [ProfilesNotDefinedError, YmlLoadError, ProfileNotFound].each do |exception_class|
82
- it "rescues #{exception_class}, prints the message to the error stream" do
83
- Configuration.stub(:new).and_return(configuration = double('configuration'))
84
- configuration.stub(:parse).and_raise(exception_class.new('error message'))
85
-
86
- subject.start!
87
- stderr.string.should == "error message\n"
88
- end
89
- end
90
- end
91
-
92
80
  end
93
81
  end
94
82
  end
@@ -11,7 +11,7 @@ module Lucid
11
11
 
12
12
  before do
13
13
  extend(Lucid::InterfaceRb::RbLucid)
14
- @runtime = Lucid::Runtime.new
14
+ @runtime = Lucid::ContextLoader.new
15
15
  @rb = @runtime.load_code_language('rb')
16
16
 
17
17
  $x = $y = nil
@@ -22,7 +22,7 @@ module Lucid
22
22
  $y = $x * n.to_i
23
23
  end
24
24
 
25
- @visitor = TDLWalker.new(@runtime)
25
+ @visitor = Walker.new(@runtime)
26
26
 
27
27
  @feature = double('feature', :visit? => true, :feature_elements => []).as_null_object
28
28
  end
@@ -122,7 +122,7 @@ module Lucid
122
122
  background.should be_failed
123
123
  end
124
124
  end
125
-
125
+
126
126
  end
127
127
  end
128
- end
128
+ end
@@ -5,20 +5,20 @@ module Lucid
5
5
  module AST
6
6
  describe Feature do
7
7
  include TDLFactory
8
-
8
+
9
9
  it 'should convert to a symbolic expression' do
10
- runtime = Lucid::Runtime.new
10
+ runtime = Lucid::ContextLoader.new
11
11
  runtime.load_code_language('rb')
12
12
  dsl = Object.new
13
13
  dsl.extend Lucid::InterfaceRb::RbLucid
14
-
14
+
15
15
  feature = create_feature(dsl)
16
16
  if Lucid::WINDOWS
17
17
  feature_file_path = 'specs\\test.spec'
18
18
  else
19
19
  feature_file_path = 'specs/test.spec'
20
20
  end
21
-
21
+
22
22
  feature.to_sexp.should ==
23
23
  [
24
24
  :feature,
@@ -48,7 +48,7 @@ module Lucid
48
48
  end
49
49
 
50
50
  it 'should store operating system specific file paths' do
51
- runtime = Lucid::Runtime.new
51
+ runtime = Lucid::ContextLoader.new
52
52
  runtime.load_code_language('rb')
53
53
  dsl = Object.new
54
54
  dsl.extend Lucid::InterfaceRb::RbLucid
@@ -60,7 +60,7 @@ module Lucid
60
60
  feature.file.should == 'specs/test.spec'
61
61
  end
62
62
  end
63
-
63
+
64
64
  end
65
65
  end
66
- end
66
+ end