lucid 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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