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
@@ -210,7 +210,7 @@ module Lucid
210
210
  profiles_sentence = profiles.size == 1 ? profiles.first :
211
211
  "#{profiles[0...-1].join(', ')} and #{profiles.last}"
212
212
 
213
- @io.puts "Using the #{profiles_sentence} profile#{'s' if profiles.size> 1}..."
213
+ @io.puts "Using the #{profiles_sentence} profile#{'s' if profiles.size> 1}...\n\n"
214
214
  end
215
215
 
216
216
  private
@@ -9,7 +9,7 @@ module Lucid
9
9
  attr_reader :runtime
10
10
 
11
11
  def initialize(runtime, path_or_io, options)
12
- @runtime, @io, @options = runtime, ensure_io(path_or_io, "progress"), options
12
+ @runtime, @io, @options = runtime, ensure_io(path_or_io, 'progress'), options
13
13
  end
14
14
 
15
15
  def before_features(features)
@@ -58,13 +58,7 @@ module Lucid
58
58
  def copy_gemfile
59
59
  template 'Gemfile.tt', "#{name}/Gemfile"
60
60
  end
61
-
62
- def copy_lucid_yml
63
- if driver.downcase == 'fluent'
64
- copy_file 'lucid-fluent.yml', "#{name}/lucid.yml"
65
- end
66
- end
67
-
61
+
68
62
  end
69
63
  end
70
64
  end
@@ -1,6 +1,5 @@
1
1
  begin
2
2
  require 'fluent'
3
- require 'fluent/factory'
4
3
  rescue LoadError
5
4
  STDOUT.puts ['The Fluent test execution library is not installed.',
6
5
  'The driver file is currently set to use the Fluent library but',
@@ -7,7 +7,7 @@ Before('~@practice','~@sequence') do
7
7
  end
8
8
 
9
9
  AfterStep('@pause') do
10
- print "Press ENTER to continue..."
10
+ print 'Press ENTER to continue...'
11
11
  STDIN.getc
12
12
  end
13
13
 
@@ -24,9 +24,6 @@ After do |scenario|
24
24
  encoded_img = @browser.driver.screenshot_as(:base64)
25
25
  embed("data:image/png;base64,#{encoded_img}", 'image/png')
26
26
  end
27
-
28
- # This is an alternative way to embed.
29
- #embed screenshot, 'image/png'
30
27
  end
31
28
  Fluent::Browser.stop
32
29
  end
@@ -41,11 +41,11 @@ module Lucid
41
41
  end
42
42
 
43
43
  def do_block
44
- do_block = ""
44
+ do_block = ''
45
45
  do_block << "do#{arguments}\n"
46
46
  do_block << multiline_comment if multiline_argument_class?
47
47
  do_block << " pending\n"
48
- do_block << "end"
48
+ do_block << 'end'
49
49
  do_block
50
50
  end
51
51
 
@@ -56,7 +56,7 @@ module Lucid
56
56
  block_args << multiline_argument_class.default_arg_name
57
57
  end
58
58
 
59
- block_args.empty? ? "" : " |#{block_args.join(", ")}|"
59
+ block_args.empty? ? '' : " |#{block_args.join(", ")}|"
60
60
  end
61
61
 
62
62
  def multiline_comment
@@ -68,7 +68,7 @@ module Lucid
68
68
  end
69
69
 
70
70
  def self.example
71
- new("Given", "some phrase", nil).step
71
+ new('Given', 'some phrase', nil).step
72
72
  end
73
73
 
74
74
  end
@@ -79,7 +79,7 @@ module Lucid
79
79
  end
80
80
 
81
81
  def self.description
82
- "Matchers with parentheses."
82
+ 'Matchers with parentheses.'
83
83
  end
84
84
  end
85
85
 
@@ -89,7 +89,7 @@ module Lucid
89
89
  end
90
90
 
91
91
  def self.description
92
- "Matchers without parentheses."
92
+ 'Matchers without parentheses.'
93
93
  end
94
94
  end
95
95
 
@@ -99,7 +99,7 @@ module Lucid
99
99
  end
100
100
 
101
101
  def self.description
102
- "Matchers with delimited regexp."
102
+ 'Matchers with delimited regexp.'
103
103
  end
104
104
  end
105
105
 
@@ -50,6 +50,8 @@ module Lucid
50
50
  RbLucid.build_rb_world_factory(domain_modules, proc)
51
51
  end
52
52
 
53
+ alias_method :World, :Domain
54
+
53
55
  # Registers a proc that will run before each Scenario. You can register as many
54
56
  # as you want (typically from ruby scripts under <tt>support/hooks.rb</tt>).
55
57
  def Before(*tag_expressions, &proc)
@@ -5,13 +5,12 @@ require 'lucid/interface_rb/regexp_argument_matcher'
5
5
 
6
6
  module Lucid
7
7
  module InterfaceRb
8
- # A Ruby Step Definition holds a Regexp and a Proc, and is created
9
- # by calling <tt>Given</tt>, <tt>When</tt> or <tt>Then</tt>
10
- # in the <tt>step_definitions</tt> ruby files. See also RbLucid.
8
+ # A Ruby test definition holds a Regexp and a Proc, and is created
9
+ # by calling <tt>Given</tt>, <tt>When</tt> or <tt>Then</tt>.
11
10
  #
12
11
  # Example:
13
12
  #
14
- # Given /I have (\d+) lucid testing on the mind/ do
13
+ # Given /there are (\d+) lucid tests to run/ do
15
14
  # # some code here
16
15
  # end
17
16
  #
@@ -19,7 +18,7 @@ module Lucid
19
18
 
20
19
  class MissingProc < StandardError
21
20
  def message
22
- "Step definitions must always have a proc or symbol"
21
+ 'Test definitions must always have a proc or symbol'
23
22
  end
24
23
  end
25
24
 
@@ -59,7 +58,7 @@ module Lucid
59
58
  when Symbol
60
59
  lambda { self.send(target) }
61
60
  else
62
- lambda { raise ArgumentError, "Target must be a symbol or a proc" }
61
+ lambda { raise ArgumentError, 'Target must be a symbol or a proc' }
63
62
  end
64
63
  end
65
64
  end
@@ -99,14 +99,14 @@ module Lucid
99
99
  end
100
100
 
101
101
  # Mark the matched step as pending.
102
- def pending(message = "TODO")
102
+ def pending(message = 'TODO')
103
103
  if block_given?
104
104
  begin
105
105
  yield
106
106
  rescue Exception
107
107
  raise Pending.new(message)
108
108
  end
109
- raise Pending.new("Expected pending '#{message}' to fail. No Error was raised. No longer pending?")
109
+ raise Pending.new("Expected pending '#{message}' to fail. No error was raised. No longer pending?")
110
110
  else
111
111
  raise Pending.new(message)
112
112
  end
@@ -121,7 +121,6 @@ module Lucid
121
121
  sprintf("#<%s:0x%x>", modules.join('+'), self.object_id)
122
122
  end
123
123
 
124
- # see {#inspect}
125
124
  def to_s
126
125
  inspect
127
126
  end
@@ -2,11 +2,11 @@ require 'rbconfig'
2
2
 
3
3
  module Lucid
4
4
  unless defined?(Lucid::VERSION)
5
- VERSION = '0.2.1'
5
+ VERSION = '0.3.0'
6
6
  BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/lucid')
7
7
  LIBDIR = File.expand_path(File.dirname(__FILE__) + '/../../lib')
8
8
  JRUBY = defined?(JRUBY_VERSION)
9
- IRONRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == "ironruby"
9
+ IRONRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ironruby'
10
10
  WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
11
11
  OS_X = RbConfig::CONFIG['host_os'] =~ /darwin/
12
12
  WINDOWS_MRI = WINDOWS && !JRUBY && !IRONRUBY
@@ -18,7 +18,7 @@ module Lucid
18
18
  class << self
19
19
  attr_accessor :use_full_backtrace
20
20
 
21
- def file_mode(m, encoding="UTF-8")
21
+ def file_mode(m, encoding='UTF-8')
22
22
  "#{m}:#{encoding}"
23
23
  end
24
24
  end
@@ -4,7 +4,7 @@ module Lucid
4
4
  class Runtime
5
5
  # This is what a programming language will consider to be a runtime.
6
6
  #
7
- # It's a thin class that directs the handul of methods needed by the
7
+ # It's a thin class that directs the specific methods needed by the
8
8
  # programming languages to the right place.
9
9
  class Facade
10
10
  extend Forwardable
@@ -25,21 +25,20 @@ module Lucid
25
25
  :invoke,
26
26
  :load_code_language
27
27
 
28
- # Returns a Lucid::AST::Table for +text_or_table+, which can either
29
- # be a String:
28
+ # Returns a Lucid::AST::Table which can either be a String:
30
29
  #
31
30
  # table(%{
32
- # | account | description | amount |
33
- # | INT-100 | Taxi | 114 |
34
- # | CUC-101 | Peeler | 22 |
31
+ # | study | phase |
32
+ # | Test-01 | I |
33
+ # | Test-02 | II |
35
34
  # })
36
35
  #
37
36
  # or a 2D Array:
38
37
  #
39
38
  # table([
40
- # %w{ account description amount },
41
- # %w{ INT-100 Taxi 114 },
42
- # %w{ CUC-101 Peeler 22 }
39
+ # %w{ study phase },
40
+ # %w{ Test-01 I },
41
+ # %w{ Test-02 II }
43
42
  # ])
44
43
  #
45
44
  def table(text_or_table, file=nil, line_offset=0)
@@ -50,8 +49,7 @@ module Lucid
50
49
  end
51
50
  end
52
51
 
53
- # Returns AST::DocString for +string_without_triple_quotes+.
54
- #
52
+ # Returns AST::DocString
55
53
  def doc_string(string_without_triple_quotes, content_type='', line_offset=0)
56
54
  AST::DocString.new(string_without_triple_quotes,content_type)
57
55
  end
@@ -44,8 +44,8 @@ module Lucid
44
44
  # Invokes a series of steps +steps_text+. Example:
45
45
  #
46
46
  # invoke(%Q{
47
- # Given I have 8 cukes in my belly
48
- # Then I should not be thirsty
47
+ # Given lucid exists
48
+ # Then test specs can be executed
49
49
  # })
50
50
  def invoke_steps(steps_text, i18n, file_colon_line)
51
51
  file, line = file_colon_line.split(':')
@@ -55,7 +55,6 @@ module Lucid
55
55
 
56
56
  def invoke(step_name, multiline_argument=nil)
57
57
  multiline_argument = Lucid::AST::MultilineArgument.from(multiline_argument)
58
- # It is very important to leave multiline_argument=nil as a vararg. Cuke4Duke needs it that way.
59
58
  begin
60
59
  step_match(step_name).invoke(multiline_argument)
61
60
  rescue Exception => e
@@ -4,8 +4,6 @@ module Lucid
4
4
  class Results
5
5
  def initialize(configuration)
6
6
  @configuration = configuration
7
-
8
- # Optimization - quicker lookup.
9
7
  @inserted_steps = {}
10
8
  @inserted_scenarios = {}
11
9
  end
@@ -6,7 +6,7 @@ require 'gherkin/parser/parser'
6
6
  module Lucid
7
7
  class SpecFile
8
8
  SPEC_PATTERN = /^([\w\W]*?):([\d:]+)$/ #:nodoc:
9
- DEFAULT_ENCODING = "UTF-8" #:nodoc:
9
+ DEFAULT_ENCODING = 'UTF-8' #:nodoc:
10
10
  NON_EXEC_PATTERN = /^\s*#|^\s*$/ #:nodoc:
11
11
  ENCODING_PATTERN = /^\s*#\s*encoding\s*:\s*([^\s]+)/ #:nodoc:
12
12
 
@@ -74,8 +74,6 @@ module Lucid
74
74
  STDOUT.puts ["\nYou don't have a 'specs' directory. This is the default specification",
75
75
  "directory that Lucid will use if one is not specified. So either create",
76
76
  "that directory or specify where your test repository is located.\n\n"].join("\n")
77
- #e.message << "."
78
- raise e
79
77
  else
80
78
  STDOUT.puts ["\nThere is no '#{@path}' directory. Since that is what you specified as",
81
79
  "your spec repository, this directory must be present."].join("\n")
@@ -0,0 +1,31 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module Lucid
4
+ module Formatter
5
+ describe ANSIColor do
6
+ include ANSIColor
7
+
8
+ it 'should wrap passed_param with bold green and reset to green' do
9
+ passed_param('test').should == "\e[32m\e[1mtest\e[0m\e[0m\e[32m"
10
+ end
11
+
12
+ it 'should wrap passed in green' do
13
+ passed('test').should == "\e[32mtest\e[0m"
14
+ end
15
+
16
+ it 'should not reset passed if there are no arguments' do
17
+ passed.should == "\e[32m"
18
+ end
19
+
20
+ it 'should wrap comments in grey' do
21
+ comment('test').should == "\e[90mtest\e[0m"
22
+ end
23
+
24
+ it 'should not generate ansi codes when colors are disabled' do
25
+ ::Lucid::Term::ANSIColor.coloring = false
26
+ passed('test').should == 'test'
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -1,22 +1,24 @@
1
- require_relative '../spec_helper'
1
+ require 'spec_helper'
2
+ require 'lucid/tdl_builder'
3
+ require 'gherkin/formatter/model'
2
4
 
3
5
  module Lucid
4
6
  module CLI
5
7
  describe App do
6
-
8
+
7
9
  let(:args) { [] }
8
10
  let(:stdin) { StringIO.new }
9
11
  let(:stdout) { StringIO.new }
10
12
  let(:stderr) { StringIO.new }
11
13
  let(:kernel) { double(:kernel) }
12
14
  subject { App.new(args, stdin, stdout, stderr, kernel) }
13
-
15
+
14
16
  describe 'start' do
15
17
  context 'passed a runtime' do
16
18
  let(:runtime) { double('runtime').as_null_object }
17
19
 
18
20
  def do_start
19
- subject.start(runtime)
21
+ subject.start!(runtime)
20
22
  end
21
23
 
22
24
  it 'configures the runtime' do
@@ -35,6 +37,73 @@ module Lucid
35
37
  do_start
36
38
  end
37
39
  end
40
+
41
+ context 'execution is interrupted' do
42
+ after do
43
+ Lucid.wants_to_quit = false
44
+ end
45
+
46
+ it 'should register as a failure' do
47
+ results = double('results', :failure? => false)
48
+ runtime = Runtime.any_instance
49
+ runtime.stub(:run)
50
+ runtime.stub(:results).and_return(results)
51
+
52
+ Lucid.wants_to_quit = true
53
+ kernel.should_receive(:exit).with(1)
54
+ subject.start!
55
+ end
56
+ end
57
+ end
58
+
59
+ describe 'verbose execution' do
60
+ before(:each) do
61
+ b = Lucid::Parser::TDLBuilder.new('specs/test.spec')
62
+ b.feature(Gherkin::Formatter::Model::Feature.new([], [], 'Feature', 'Testing', '', 99, ''))
63
+ b.language = double
64
+ @empty_feature = b.result
65
+ end
66
+
67
+ it 'should show the spec files that were parsed' do
68
+ cli = App.new(%w{--verbose test.spec}, stdin, stdout, stderr, kernel)
69
+ cli.stub(:require)
70
+
71
+ Lucid::SpecFile.stub(:new).and_return(double('spec file', :parse => @empty_feature))
72
+ kernel.should_receive(:exit).with(0)
73
+
74
+ cli.start!
75
+
76
+ stdout.string.should include('test.spec')
77
+ end
78
+ end
79
+
80
+ describe '--format with a formatter' do
81
+ it 'should fail if it cannot resolve a Formatter class' do
82
+ cli = App.new(%w{--format ZooModule::MonkeyFormatterClass}, stdin, stdout, stderr, kernel)
83
+ mock_module = double('module')
84
+ Object.stub(:const_defined?).and_return(true)
85
+ mock_module.stub(:const_defined?).and_return(true)
86
+
87
+ f = double('formatter').as_null_object
88
+
89
+ Object.should_receive(:const_get).with('ZooModule', false).and_return(mock_module)
90
+ mock_module.should_receive(:const_get).with('MonkeyFormatterClass', false).and_return(double('formatter class', :new => f))
91
+
92
+ kernel.should_receive(:exit).with(1)
93
+ cli.start!
94
+ end
95
+ end
96
+
97
+ describe 'handling exceptions' do
98
+ [ProfilesNotDefinedError, YmlLoadError, ProfileNotFound].each do |exception_class|
99
+ it "rescues #{exception_class}, prints the message to the error stream" do
100
+ Configuration.stub(:new).and_return(configuration = double('configuration'))
101
+ configuration.stub(:parse).and_raise(exception_class.new('error message'))
102
+
103
+ subject.start!
104
+ stderr.string.should == "error message\n"
105
+ end
106
+ end
38
107
  end
39
108
 
40
109
  end