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
@@ -451,7 +451,7 @@ module Lucid
451
451
  Lucid::Term::ANSIColor.coloring = options[:color]
452
452
  formatter = Formatter::Standard.new(nil, io, options)
453
453
  formatter.instance_variable_set('@indent', options[:indent])
454
- TDLWalker.new(nil, [formatter]).visit_multiline_arg(self)
454
+ Walker.new(nil, [formatter]).visit_multiline_arg(self)
455
455
 
456
456
  Lucid::Term::ANSIColor.coloring = c
457
457
  io.rewind
@@ -1,21 +1,20 @@
1
1
  module Lucid
2
2
  module AST
3
- class TDLWalker
4
- attr_accessor :configuration #:nodoc:
5
- attr_reader :runtime #:nodoc:
3
+ class Walker
4
+ attr_accessor :context
5
+ attr_reader :runtime
6
6
 
7
- def initialize(runtime, listeners = [], configuration = Lucid::Configuration.default)
8
- @runtime, @listeners, @configuration = runtime, listeners, configuration
7
+ def initialize(runtime, listeners = [], context = Lucid::Context.default)
8
+ @runtime, @listeners, @context = runtime, listeners, context
9
9
  end
10
10
 
11
11
  # This is being used to forward on messages from the AST to
12
- # the formatters. This is being done in lieu of the explicit
13
- # forwarding that was previously done.
12
+ # the formatters.
14
13
  def method_missing(message, *args, &block)
15
- broadcast_message(message, *args, &block)
14
+ send_message(message, *args, &block)
16
15
  end
17
16
 
18
- def visit_multiline_arg(multiline_arg) #:nodoc:
17
+ def visit_multiline_arg(multiline_arg)
19
18
  broadcast(multiline_arg) do
20
19
  multiline_arg.accept(self)
21
20
  end
@@ -25,32 +24,32 @@ module Lucid
25
24
 
26
25
  def broadcast(*args, &block)
27
26
  message = extract_method_name_from(caller[0])
28
- broadcast_message message, *args, &block
27
+ send_message message, *args, &block
29
28
  self
30
29
  end
31
30
 
32
- def broadcast_message(message, *args, &block)
31
+ def send_message(message, *args, &block)
33
32
  return self if Lucid.wants_to_quit
34
33
  message = message.to_s.gsub('visit_', '')
35
34
  if block_given?
36
- send_to_all("before_#{message}", *args)
35
+ send_to_listeners("before_#{message}", *args)
37
36
  yield if block_given?
38
- send_to_all("after_#{message}", *args)
37
+ send_to_listeners("after_#{message}", *args)
39
38
  else
40
- send_to_all(message, *args)
39
+ send_to_listeners(message, *args)
41
40
  end
42
41
  self
43
42
  end
44
43
 
45
- def send_to_all(message, *args)
44
+ def send_to_listeners(message, *args)
46
45
  @listeners.each do |listener|
47
46
  if listener.respond_to?(message)
48
47
  listener.__send__(message, *args)
49
48
  end
50
49
  end
51
50
  end
51
+
52
52
  def extract_method_name_from(call_stack)
53
- #call_stack[0].match(/in `(.*)'/).captures[0]
54
53
  match = call_stack.match(/in `(.*)'/)
55
54
  match.captures[0]
56
55
  end
@@ -3,7 +3,7 @@ require 'optparse'
3
3
  require 'lucid'
4
4
  require 'logger'
5
5
  require 'lucid/spec_file'
6
- require 'lucid/cli/configuration'
6
+ require 'lucid/cli/context'
7
7
 
8
8
  module Lucid
9
9
  module CLI
@@ -11,7 +11,7 @@ module Lucid
11
11
  def self.start(args)
12
12
  new(args).start!
13
13
  end
14
-
14
+
15
15
  def initialize(args, stdin=STDIN, out=STDOUT, err=STDERR, kernel=Kernel)
16
16
  raise "args can't be nil" unless args
17
17
  raise "out can't be nil" unless out
@@ -21,24 +21,25 @@ module Lucid
21
21
  @out = out
22
22
  @err = err
23
23
  @kernel = kernel
24
- @configuration = nil
24
+ @context = nil
25
25
  end
26
-
27
- def start!(existing_runtime = nil)
26
+
27
+ def start!(existing_context = nil)
28
28
  trap_interrupt
29
29
 
30
- runtime = if existing_runtime
31
- existing_runtime.configure(configuration)
32
- existing_runtime
30
+ context_loader = if existing_context
31
+ existing_context.configure(load_context)
32
+ existing_context
33
33
  else
34
- Runtime.new(configuration)
34
+ ContextLoader.new(load_context)
35
35
  end
36
36
 
37
- log.debug("Runtime: #{runtime.inspect}")
37
+ log.debug('Context Loader')
38
+ log.debug(context_loader)
38
39
 
39
- runtime.run
40
- runtime.write_testdefs_json
41
- failure = runtime.results.failure? || Lucid.wants_to_quit
40
+ context_loader.execute
41
+ context_loader.write_testdefs_json
42
+ failure = context_loader.results.failure? || Lucid.wants_to_quit
42
43
  @kernel.exit(failure ? 1 : 0)
43
44
  rescue ProfilesNotDefinedError, YmlLoadError, ProfileNotFound => e
44
45
  @err.puts(e.message)
@@ -53,14 +54,15 @@ module Lucid
53
54
  @kernel.exit(1)
54
55
  end
55
56
 
56
- def configuration
57
- return @configuration if @configuration
57
+ def load_context
58
+ return @context if @context
58
59
 
59
- @configuration = Configuration.new(@out, @err)
60
- @configuration.parse(@args)
61
- Lucid.logger = @configuration.log
62
- log.debug("Configuration: #{@configuration.inspect}")
63
- @configuration
60
+ @context = Context.new(@out, @err)
61
+ @context.parse_options(@args)
62
+ Lucid.logger = @context.log
63
+ log.debug('Context:')
64
+ log.debug(@context)
65
+ @context
64
66
  end
65
67
 
66
68
  private
@@ -73,7 +75,7 @@ module Lucid
73
75
  trap('INT') do
74
76
  exit!(1) if Lucid.wants_to_quit
75
77
  Lucid.wants_to_quit = true
76
- STDERR.puts "\nExiting. Interrupt again to exit immediately."
78
+ STDERR.puts "\nExiting Lucid execution.\nInterrupt again to exit immediately."
77
79
  end
78
80
  end
79
81
  end
@@ -8,23 +8,24 @@ module Lucid
8
8
  class ProfilesNotDefinedError < YmlLoadError; end
9
9
  class ProfileNotFound < StandardError; end
10
10
 
11
- class Configuration
11
+ class Context
12
12
  include Factory
13
13
 
14
14
  attr_reader :out_stream
15
15
 
16
16
  def initialize(out_stream = STDOUT, err_stream = STDERR)
17
- @out_stream = out_stream
17
+ @out_stream = out_stream
18
18
  @err_stream = err_stream
19
19
  @options = Options.new(@out_stream, @err_stream, :default_profile => 'default')
20
20
  end
21
21
 
22
- def parse(args)
22
+ def parse_options(args)
23
23
  @args = args
24
24
  @options.parse(args)
25
- log.debug("Options: #{@options.inspect}")
25
+ log.debug('Options:')
26
+ log.debug(@options)
26
27
 
27
- prepare_output_formatting
28
+ set_formatter
28
29
  raise('You cannot use both --strict and --wip tags.') if strict? && wip?
29
30
 
30
31
  @options[:tag_expression] = Gherkin::TagExpression.new(@options[:tag_expressions])
@@ -68,24 +69,26 @@ module Lucid
68
69
  @options[:matcher_type] || :regexp
69
70
  end
70
71
 
71
- def establish_tdl_walker(runtime)
72
- AST::TDLWalker.new(runtime, formatters(runtime), self)
72
+ # @see Lucid::ContextLoader.execute
73
+ def establish_ast_walker(runtime)
74
+ Lucid::AST::Walker.new(runtime, formatters(runtime), self)
73
75
  end
74
76
 
75
- def formatter_class(name)
76
- if(lucid_format = Options::LUCID_FORMATS[name])
77
+ def formatter_instance(name)
78
+ if lucid_format = Options::LUCID_FORMATS[name]
77
79
  create_object_of(lucid_format[0])
78
80
  else
79
81
  create_object_of(name)
80
82
  end
81
83
  end
82
84
 
85
+ # @return [Array] list of non-spec, executable files from all required locations
83
86
  def spec_requires
84
87
  requires = @options[:require].empty? ? require_dirs : @options[:require]
85
88
 
86
89
  files = requires.map do |path|
87
- path = path.gsub(/\\/, '/') # convert \ to /
88
- path = path.gsub(/\/$/, '') # removing trailing /
90
+ path = path.gsub(/\\/, '/')
91
+ path = path.gsub(/\/$/, '')
89
92
  File.directory?(path) ? Dir["#{path}/**/*"] : path
90
93
  end.flatten.uniq
91
94
 
@@ -93,7 +96,7 @@ module Lucid
93
96
 
94
97
  files.reject! {|f| !File.file?(f)}
95
98
 
96
- spec_types = spec_type.each do |type|
99
+ spec_type.each do |type|
97
100
  files.reject! {|f| File.extname(f) == ".#{type}" }
98
101
  end
99
102
 
@@ -102,28 +105,49 @@ module Lucid
102
105
  files.sort
103
106
  end
104
107
 
105
- # @see Lucid::Runtime.load_execution_context
108
+ # Returns all definition files that exist in the default or provided
109
+ # execution path.
110
+ #
111
+ # @return [Array] executable files outside of the library path
112
+ # @see Lucid::ContextLoader.load_execution_context
106
113
  def definition_context
107
- spec_requires.reject { |f| f=~ %r{#{library_path}} }
114
+ definition_files = spec_requires.reject { |f| f =~ %r{#{library_path}} }
115
+ log.info("Definition Files:\n#{definition_files}")
116
+
117
+ non_test_definitions = spec_requires.reject { |f| f =~ %r{#{steps_path}|#{library_path}} }
118
+ log.info("Non-Test Definition Files:\n#{non_test_definitions}")
119
+
120
+ @options[:dry_run] ? definition_files - non_test_definitions : definition_files
108
121
  end
109
122
 
110
- # @see Lucid::Runtime.load_execution_context
123
+ # Returns all library files that exist in the default or provided
124
+ # library path. During a dry run, the driver file will not be
125
+ # returned as part of the executing context.
126
+ #
127
+ # @return [Array] valid executable files in the library path
128
+ # @see Lucid::ContextLoader.load_execution_context
111
129
  def library_context
112
130
  library_files = spec_requires.select { |f| f =~ %r{#{library_path}} }
113
- driver = library_files.select {|f| f =~ %r{#{driver_file}} }
131
+ log.info("(Library Context) Library Files:\n#{library_files}")
114
132
 
115
- log.info("Driver File Found: #{driver}")
133
+ driver = library_files.select {|f| f =~ %r{#{driver_file}} }
134
+ log.info("(Library Context) Driver File:\n#{driver}")
116
135
 
117
136
  non_driver_files = library_files - driver
137
+ log.info("(Library Context) Non-Driver Files:\n#{non_driver_files}")
118
138
 
119
139
  @options[:dry_run] ? non_driver_files : driver + non_driver_files
120
140
  end
121
141
 
122
- # @see Lucid::Runtime.specs
123
- def spec_files
142
+ # Returns all spec files that exist in the default or provided spec
143
+ # repository.
144
+ #
145
+ # @return [Array] spec files from the repo
146
+ # @see Lucid::RepoRunner.load_spec_context
147
+ def spec_context
124
148
  files = specs_path(spec_source).map do |path|
125
- path = path.gsub(/\\/, '/') # convert \ to /
126
- path = path.chomp('/') # removing trailing /
149
+ path = path.gsub(/\\/, '/')
150
+ path = path.chomp('/')
127
151
 
128
152
  files_to_sort = []
129
153
 
@@ -134,7 +158,7 @@ module Lucid
134
158
 
135
159
  files_to_sort
136
160
  elsif path[0..0] == '@' and # @listfile.txt
137
- File.file?(path[1..-1]) # listfile.txt is a file
161
+ File.file?(path[1..-1]) # listfile.txt is a file
138
162
  IO.read(path[1..-1]).split
139
163
  else
140
164
  path
@@ -154,16 +178,23 @@ module Lucid
154
178
  end
155
179
 
156
180
  def spec_type
157
- @options[:spec_type]
158
-
181
+ @options[:spec_types]
159
182
  end
160
183
 
161
184
  def library_path
162
- @options[:library_path].empty? ? 'common' : @options[:library_path]
185
+ @options[:library_path]
163
186
  end
164
187
 
165
188
  def driver_file
166
- @options[:driver_file].empty? ? 'driver' : @options[:driver_file]
189
+ @options[:driver_file]
190
+ end
191
+
192
+ def steps_path
193
+ @options[:steps_path]
194
+ end
195
+
196
+ def definitions_path
197
+ @options[:definitions_path]
167
198
  end
168
199
 
169
200
  def log
@@ -191,7 +222,7 @@ module Lucid
191
222
  @options[:spec_source]
192
223
  end
193
224
 
194
- private
225
+ private
195
226
 
196
227
  def specs_path(paths)
197
228
  return ['specs'] if paths.empty?
@@ -200,16 +231,13 @@ module Lucid
200
231
 
201
232
  def formatters(runtime)
202
233
  @options[:formats].map do |format|
203
- # The name will be a name, like 'standard'. The route will be the
204
- # location where output is sent to, such as 'STDOUT'.
205
- name = format[0]
206
- route = format[1]
207
234
  begin
208
- formatter = formatter_class(name)
209
- formatter.new(runtime, route, @options)
210
- rescue Exception => e
211
- e.message << "\nLucid is unable to create the formatter: #{name}"
212
- raise e
235
+ formatter = formatter_instance(format[0])
236
+ formatter.new(runtime, format[1], @options)
237
+ rescue LoadError
238
+ message = "\nLucid is unable to create the formatter: #{format[0]}"
239
+ log.error(message)
240
+ Kernel.exit(1)
213
241
  end
214
242
  end
215
243
  end
@@ -220,7 +248,7 @@ module Lucid
220
248
  end
221
249
  end
222
250
 
223
- def prepare_output_formatting
251
+ def set_formatter
224
252
  @options[:formats] << ['standard', @out_stream] if @options[:formats].empty?
225
253
  @options[:formats] = @options[:formats].sort_by{|f| f[1] == @out_stream ? -1 : 1}
226
254
  @options[:formats].uniq!
@@ -237,7 +265,7 @@ module Lucid
237
265
  end
238
266
 
239
267
  def require_dirs
240
- spec_location + Dir["#{library_path}", 'pages', 'steps']
268
+ spec_location + Dir["#{library_path}", "#{definitions_path}", "#{steps_path}"]
241
269
  end
242
270
 
243
271
  end
@@ -1,3 +1,4 @@
1
+ require 'English'
1
2
  require 'lucid/cli/profile'
2
3
  require 'lucid/formatter/ansicolor'
3
4
  require 'lucid/interface_rb/rb_language'
@@ -83,7 +84,9 @@ module Lucid
83
84
  @args.extend(::OptionParser::Arguable)
84
85
 
85
86
  @args.options do |opts|
86
- opts.banner = ['Lucid: Test Description Language Execution Engine',
87
+ opts.banner = ['Lucid Framework',
88
+ 'Test Description Language Specification and Execution Engine',
89
+ '',
87
90
  'Usage: lucid [options] [ [FILE|DIR|URL][:LINE[:LINE]*] ]+', '', ''
88
91
  ].join("\n")
89
92
 
@@ -91,9 +94,16 @@ module Lucid
91
94
  @options[:library_path] = path
92
95
  end
93
96
 
97
+ opts.on('--definition-path PATH', 'Location of spec project definition files.') do |path|
98
+ @options[:definitions_path] = path
99
+ end
100
+
101
+ opts.on('--steps-path PATH', 'Location of spec project test step files.') do |path|
102
+ @options[:steps_path] = path
103
+ end
104
+
94
105
  opts.on('--spec-type TYPE', 'The file type (extension) for Lucid specifications.') do |type|
95
- #@options[:spec_type] = type
96
- @options[:spec_type] << type
106
+ @options[:spec_types] << type
97
107
  end
98
108
 
99
109
  opts.on('--driver-file FILE', 'The file for Lucid to connect to an execution library.') do |file|
@@ -103,19 +113,17 @@ module Lucid
103
113
  opts.separator ''
104
114
 
105
115
  opts.on('-r LIBRARY|DIR', '--require LIBRARY|DIR',
106
- 'Require files before executing the features. If this option',
107
- 'is not specified, all *.rb files that are siblings or below',
108
- 'the features will be loaded automatically. Automatic loading',
109
- 'is disabled when this option is specified. That means all',
110
- 'loading becomes explicit.',
111
- 'Assuming a default specs repo configuration, files under',
112
- "directories named \"common\\support\" will always be loaded",
113
- 'before any others.',
114
- 'This option can be specified multiple times.') do |v|
115
- @options[:require] << v
116
- if(Lucid::JRUBY && File.directory?(v))
116
+ 'Require resources (paths or individual files) prior to executing',
117
+ 'the test specs. If no require options are passed, then Lucid will',
118
+ 'use its default path and file settings via automatic loading. If',
119
+ 'require options are passed, however, then automatic loading will',
120
+ 'be disabled, which means loading any resources must be done via',
121
+ 'explicit uses of this option. The require option can be specified',
122
+ 'multiple times.') do |resource|
123
+ @options[:require] << resource
124
+ if(Lucid::JRUBY && File.directory?(resource))
117
125
  require 'java'
118
- $CLASSPATH << v
126
+ $CLASSPATH << resource
119
127
  end
120
128
  end
121
129
 
@@ -143,8 +151,9 @@ module Lucid
143
151
 
144
152
  opts.separator ''
145
153
 
146
- opts.on('-d', '--dry-run', 'Invokes formatters without executing the steps.',
147
- 'This also omits the loading of your common/support/driver.rb file if it exists.') do
154
+ opts.on('-d', '--dry-run', 'Performs spec parsing without test execution.',
155
+ 'Performing a dry run omits loading of the driver file as well as',
156
+ 'any page or activity definitions.') do
148
157
  @options[:dry_run] = true
149
158
  end
150
159
 
@@ -305,24 +314,13 @@ module Lucid
305
314
  Kernel.exit(0)
306
315
  end
307
316
  end
308
- #end.parse!
309
317
 
310
318
  begin
311
319
  @args.parse!
312
320
  rescue OptionParser::InvalidOption
313
- if $!.to_s =~ /invalid option\:\s+((?:-)?-\S+)/
314
- puts "You specified an invalid option: #{$1}"
315
- puts 'Please run lucid --help to see the list of available options.'
316
- end
317
-
321
+ invalid_option($ERROR_INFO)
318
322
  rescue OptionParser::MissingArgument
319
- if $!.to_s =~ /missing argument\:\s+((?:-)?-\S+)/
320
- puts "You specified an valid option (#{$1}), but with an invalid argument."
321
- puts 'Make sure you are providing the expected argument for the option.'
322
- puts 'Run lucid --help to see the list of available options.'
323
- end
324
-
325
- Kernel.exit(1)
323
+ missing_argument($ERROR_INFO)
326
324
  end
327
325
 
328
326
  if @quiet
@@ -335,9 +333,12 @@ module Lucid
335
333
 
336
334
  extract_environment_variables
337
335
 
338
- # This line grabs whatever is left over on the command line. That
339
- # would have to be the spec repo.
340
- @options[:spec_source] = @args.dup
336
+ # The next statement is critical because it takes whatever is left
337
+ # from the command line when all the valid options are parsed. This
338
+ # would have to be the spec repository. The empty check is because
339
+ # even if no args are passed, an empty array will be passed to the
340
+ # spec_repos key, which overwrites the default option.
341
+ @options[:spec_source] = @args.dup #unless args.empty?
341
342
 
342
343
  establish_profile
343
344
 
@@ -348,17 +349,33 @@ module Lucid
348
349
  @profiles - [@default_profile]
349
350
  end
350
351
 
351
- # @see Lucid::CLI::Configuration.filters
352
+ # @see Lucid::CLI::Context.filters
352
353
  def filters
353
354
  @options.values_at(:name_regexps, :tag_expressions).select{|v| !v.empty?}.first || []
354
355
  end
355
356
 
356
- protected
357
+ protected
357
358
 
358
359
  attr_reader :options, :profiles, :expanded_args
359
360
  protected :options, :profiles, :expanded_args
360
361
 
361
- private
362
+ private
363
+
364
+ def invalid_option(error)
365
+ if error.to_s =~ /invalid option:\s+((?:-)?-\S+)/
366
+ puts "You specified an #{$MATCH}\n\n"
367
+ puts 'Run lucid --help to see the list of available options.'
368
+ end
369
+ Kernel.exit(1)
370
+ end
371
+
372
+ def missing_argument(error)
373
+ if error.to_s =~ /(?:missing argument:\s+)((?:-)?-\S+)/
374
+ puts "Valid option with #{$MATCH}\n\n"
375
+ puts 'Run lucid --help to see the list of available options.'
376
+ end
377
+ Kernel.exit(1)
378
+ end
362
379
 
363
380
  def non_stdout_formats
364
381
  @options[:formats].select {|format, output| output != @out_stream }
@@ -435,7 +452,7 @@ module Lucid
435
452
  @options[:dry_run] |= other_options[:dry_run]
436
453
 
437
454
  @options[:library_path] += other_options[:library_path]
438
- @options[:spec_type] += other_options[:spec_type]
455
+ @options[:spec_types] += other_options[:spec_types]
439
456
  @options[:driver_file] += other_options[:driver_file]
440
457
 
441
458
  @profiles += other_options.profiles
@@ -474,9 +491,11 @@ module Lucid
474
491
  :name_regexps => [],
475
492
  :env_vars => {},
476
493
  :diff_enabled => true,
477
- :spec_type => %w(feature spec story),
478
- :library_path => '',
479
- :driver_file => ''
494
+ :spec_types => %w(feature spec story),
495
+ :library_path => 'common',
496
+ :definitions_path => 'pages',
497
+ :steps_path => 'steps',
498
+ :driver_file => 'driver'
480
499
  }
481
500
  end
482
501
  end