spicycode-micronaut 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +25 -0
- data/README +1 -1
- data/Rakefile +1 -1
- data/examples/example_helper.rb +1 -1
- data/examples/lib/micronaut/example_runner_example.rb +1 -1
- data/examples/lib/micronaut/formatters/base_formatter_example.rb +107 -0
- data/examples/lib/micronaut/formatters/progress_formatter_example.rb +98 -0
- data/examples/lib/micronaut/matchers/have_example.rb +8 -8
- data/examples/lib/micronaut/matchers/match_example.rb +1 -3
- data/examples/lib/micronaut_example.rb +0 -2
- data/lib/micronaut.rb +3 -3
- data/lib/micronaut/behaviour_group.rb +13 -9
- data/lib/micronaut/behaviour_group_class_methods.rb +3 -3
- data/lib/micronaut/expectations.rb +1 -1
- data/lib/micronaut/formatters.rb +11 -0
- data/lib/micronaut/formatters/base_formatter.rb +76 -0
- data/lib/micronaut/formatters/base_text_formatter.rb +119 -0
- data/lib/micronaut/formatters/progress_formatter.rb +35 -0
- data/lib/micronaut/matchers.rb +1 -1
- data/lib/micronaut/runner.rb +62 -0
- data/lib/micronaut/runner_options.rb +26 -0
- metadata +12 -3
- data/lib/micronaut/example_runner.rb +0 -106
data/LICENSE
CHANGED
@@ -18,3 +18,28 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
|
23
|
+
The matchers and expectations are licensed:
|
24
|
+
(The MIT License)
|
25
|
+
|
26
|
+
Copyright (c) 2005-2008 The RSpec Development Team
|
27
|
+
|
28
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
29
|
+
a copy of this software and associated documentation files (the
|
30
|
+
"Software"), to deal in the Software without restriction, including
|
31
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
32
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
33
|
+
permit persons to whom the Software is furnished to do so, subject to
|
34
|
+
the following conditions:
|
35
|
+
|
36
|
+
The above copyright notice and this permission notice shall be
|
37
|
+
included in all copies or substantial portions of the Software.
|
38
|
+
|
39
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
40
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
41
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
42
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
43
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
44
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
45
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
CHANGED
data/Rakefile
CHANGED
data/examples/example_helper.rb
CHANGED
@@ -0,0 +1,107 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
|
2
|
+
|
3
|
+
describe Micronaut::Formatters::BaseFormatter do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@formatter = Micronaut::Formatters::BaseFormatter.new(nil, nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
class HaveInterfaceMatcher
|
10
|
+
def initialize(method)
|
11
|
+
@method = method
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :object
|
15
|
+
attr_reader :method
|
16
|
+
|
17
|
+
def matches?(object)
|
18
|
+
@object = object
|
19
|
+
object.respond_to?(@method)
|
20
|
+
end
|
21
|
+
|
22
|
+
def with(arity)
|
23
|
+
WithArity.new(self, @method, arity)
|
24
|
+
end
|
25
|
+
|
26
|
+
class WithArity
|
27
|
+
def initialize(matcher, method, arity)
|
28
|
+
@have_matcher = matcher
|
29
|
+
@method = method
|
30
|
+
@arity = arity
|
31
|
+
end
|
32
|
+
|
33
|
+
def matches?(an_object)
|
34
|
+
@have_matcher.matches?(an_object) && real_arity == @arity
|
35
|
+
end
|
36
|
+
|
37
|
+
def failure_message
|
38
|
+
"#{@have_matcher} should have method :#{@method} with #{argument_arity}, but it had #{real_arity}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def arguments
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method :argument, :arguments
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def real_arity
|
50
|
+
@have_matcher.object.method(@method).arity
|
51
|
+
end
|
52
|
+
|
53
|
+
def argument_arity
|
54
|
+
if @arity == 1
|
55
|
+
"1 argument"
|
56
|
+
else
|
57
|
+
"#{@arity} arguments"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def have_interface_for(method)
|
64
|
+
HaveInterfaceMatcher.new(method)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have start as an interface with one argument" do
|
68
|
+
@formatter.should have_interface_for(:start).with(1).argument
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should have add_example_group as an interface with one argument" do
|
72
|
+
@formatter.should have_interface_for(:add_example_group).with(1).argument
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should have example_started as an interface with one argument" do
|
76
|
+
@formatter.should have_interface_for(:example_started).with(1).argument
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should have example_failed as an interface with two arguments" do
|
80
|
+
@formatter.should have_interface_for(:example_failed).with(2).arguments
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should have example_pending as an interface with two arguments" do
|
84
|
+
@formatter.should have_interface_for(:example_pending).with(2).arguments
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should have start_dump as an interface with zero arguments" do
|
88
|
+
@formatter.should have_interface_for(:start_dump).with(0).arguments
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should have dump_failures as an interface with no arguments" do
|
92
|
+
@formatter.should have_interface_for(:dump_failures).with(0).arguments
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should have dump_summary as an interface with 4 arguments" do
|
96
|
+
@formatter.should have_interface_for(:dump_summary).with(4).arguments
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should have dump_pending as an interface with zero arguments" do
|
100
|
+
@formatter.should have_interface_for(:dump_pending).with(0).arguments
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should have close as an interface with zero arguments" do
|
104
|
+
@formatter.should have_interface_for(:close).with(0).arguments
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
|
2
|
+
|
3
|
+
describe Micronaut::Formatters::ProgressFormatter do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@io = StringIO.new
|
7
|
+
@options = mock('options')
|
8
|
+
@options.stubs(:enable_color_in_output?).returns(false)
|
9
|
+
@formatter = Micronaut::Formatters::ProgressFormatter.new(@options, @io)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should produce line break on start dump" do
|
13
|
+
@formatter.start_dump
|
14
|
+
@io.string.should eql("\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should produce standard summary without pending when pending has a 0 count" do
|
18
|
+
@formatter.dump_summary(3, 2, 1, 0)
|
19
|
+
@io.string.should == "\nFinished in 3 seconds\n\n2 examples, 1 failure\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should produce standard summary" do
|
23
|
+
example_group = Micronaut::BehaviourGroup.describe("example_group") do
|
24
|
+
it('example') {}
|
25
|
+
end
|
26
|
+
example = example_group.examples.first
|
27
|
+
@formatter.example_pending(example, "message")
|
28
|
+
@io.rewind
|
29
|
+
@formatter.dump_summary(3, 2, 1, 1)
|
30
|
+
@io.string.should eql(%Q|
|
31
|
+
Finished in 3 seconds
|
32
|
+
|
33
|
+
2 examples, 1 failure, 1 pending
|
34
|
+
|)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should push green dot for passing spec" do
|
38
|
+
@io.expects(:tty?).returns(true)
|
39
|
+
@options.expects(:enable_color_in_output?).returns(true)
|
40
|
+
@formatter.example_passed("spec")
|
41
|
+
@io.string.should == "\e[32m.\e[0m"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should push red F for failure spec" do
|
45
|
+
@io.expects(:tty?).returns(true)
|
46
|
+
@options.expects(:enable_color_in_output?).returns(true)
|
47
|
+
@formatter.example_failed("spec", Micronaut::Expectations::ExpectationNotMetError.new)
|
48
|
+
@io.string.should eql("\e[31mF\e[0m")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should push magenta F for error spec" do
|
52
|
+
@io.expects(:tty?).returns(true)
|
53
|
+
@options.expects(:enable_color_in_output?).returns(true)
|
54
|
+
@formatter.example_failed("spec", RuntimeError.new)
|
55
|
+
@io.string.should eql("\e[35mF\e[0m")
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should push nothing on start" do
|
59
|
+
@formatter.start(4)
|
60
|
+
@io.string.should eql("")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should ensure two ':' in the first backtrace" do
|
64
|
+
backtrace = ["/tmp/x.rb:1", "/tmp/x.rb:2", "/tmp/x.rb:3"]
|
65
|
+
@formatter.format_backtrace(backtrace).should eql(<<-EOE.rstrip)
|
66
|
+
/tmp/x.rb:1:
|
67
|
+
/tmp/x.rb:2:
|
68
|
+
/tmp/x.rb:3:
|
69
|
+
EOE
|
70
|
+
|
71
|
+
backtrace = ["/tmp/x.rb:1: message", "/tmp/x.rb:2", "/tmp/x.rb:3"]
|
72
|
+
@formatter.format_backtrace(backtrace).should eql(<<-EOE.rstrip)
|
73
|
+
/tmp/x.rb:1: message
|
74
|
+
/tmp/x.rb:2:
|
75
|
+
/tmp/x.rb:3:
|
76
|
+
EOE
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "outputting to custom out" do
|
80
|
+
before do
|
81
|
+
@out = mock("out")
|
82
|
+
@options = mock('options')
|
83
|
+
@out.stubs(:puts)
|
84
|
+
@formatter = Micronaut::Formatters::ProgressFormatter.new(@options, @out)
|
85
|
+
@formatter.class.__send__ :public, :output_to_tty?
|
86
|
+
end
|
87
|
+
|
88
|
+
after(:each) do
|
89
|
+
@formatter.class.__send__ :protected, :output_to_tty?
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should not throw NoMethodError on output_to_tty?" do
|
93
|
+
@out.expects(:tty?).raises(NoMethodError)
|
94
|
+
@formatter.output_to_tty?.should be_false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -36,7 +36,7 @@ describe "should have(n).items" do
|
|
36
36
|
owner
|
37
37
|
end
|
38
38
|
|
39
|
-
before
|
39
|
+
before do
|
40
40
|
unless defined?(ActiveSupport::Inflector)
|
41
41
|
@active_support_was_not_defined
|
42
42
|
module ActiveSupport
|
@@ -94,7 +94,7 @@ describe 'should have(1).item when ActiveSupport::Inflector is defined' do
|
|
94
94
|
owner
|
95
95
|
end
|
96
96
|
|
97
|
-
before
|
97
|
+
before do
|
98
98
|
unless defined?(ActiveSupport::Inflector)
|
99
99
|
@active_support_was_not_defined
|
100
100
|
module ActiveSupport
|
@@ -131,7 +131,7 @@ describe 'should have(1).item when Inflector is defined' do
|
|
131
131
|
owner
|
132
132
|
end
|
133
133
|
|
134
|
-
before
|
134
|
+
before do
|
135
135
|
unless defined?(ActiveSupport::Inflector)
|
136
136
|
@active_support_was_not_defined
|
137
137
|
module ActiveSupport
|
@@ -192,7 +192,7 @@ describe "should_not have(n).items" do
|
|
192
192
|
owner
|
193
193
|
end
|
194
194
|
|
195
|
-
before
|
195
|
+
before do
|
196
196
|
unless defined?(ActiveSupport::Inflector)
|
197
197
|
@active_support_was_not_defined
|
198
198
|
module ActiveSupport
|
@@ -240,7 +240,7 @@ describe "should have_exactly(n).items" do
|
|
240
240
|
owner
|
241
241
|
end
|
242
242
|
|
243
|
-
before
|
243
|
+
before do
|
244
244
|
unless defined?(ActiveSupport::Inflector)
|
245
245
|
@active_support_was_not_defined
|
246
246
|
module ActiveSupport
|
@@ -298,7 +298,7 @@ describe "should have_at_least(n).items" do
|
|
298
298
|
owner
|
299
299
|
end
|
300
300
|
|
301
|
-
before
|
301
|
+
before do
|
302
302
|
unless defined?(ActiveSupport::Inflector)
|
303
303
|
@active_support_was_not_defined
|
304
304
|
module ActiveSupport
|
@@ -374,7 +374,7 @@ describe "should have_at_most(n).items" do
|
|
374
374
|
owner
|
375
375
|
end
|
376
376
|
|
377
|
-
before
|
377
|
+
before do
|
378
378
|
unless defined?(ActiveSupport::Inflector)
|
379
379
|
@active_support_was_not_defined
|
380
380
|
module ActiveSupport
|
@@ -491,7 +491,7 @@ describe Micronaut::Matchers::Have, "for a collection owner that implements #sen
|
|
491
491
|
owner
|
492
492
|
end
|
493
493
|
|
494
|
-
before
|
494
|
+
before do
|
495
495
|
unless defined?(ActiveSupport::Inflector)
|
496
496
|
@active_support_was_not_defined
|
497
497
|
module ActiveSupport
|
@@ -7,9 +7,7 @@ describe "should match(expected)" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should fail when target (String) does not match expected (Regexp)" do
|
10
|
-
lambda {
|
11
|
-
"string".should match(/rings/)
|
12
|
-
}.should fail
|
10
|
+
lambda { "string".should match(/rings/) }.should fail
|
13
11
|
end
|
14
12
|
|
15
13
|
it "should provide message, expected and actual on failure" do
|
data/lib/micronaut.rb
CHANGED
@@ -2,14 +2,14 @@ require 'micronaut/mocking/with_mocha'
|
|
2
2
|
require 'micronaut/matchers'
|
3
3
|
require 'micronaut/expectations'
|
4
4
|
require 'micronaut/example_world'
|
5
|
-
require 'micronaut/
|
5
|
+
require 'micronaut/runner'
|
6
|
+
require 'micronaut/runner_options'
|
6
7
|
require 'micronaut/behaviour_group_class_methods'
|
7
8
|
require 'micronaut/behaviour_group'
|
8
9
|
require 'micronaut/extensions/kernel'
|
10
|
+
require 'micronaut/formatters'
|
9
11
|
|
10
12
|
module Micronaut
|
11
|
-
VERSION = "0.0.2"
|
12
|
-
|
13
13
|
file = if RUBY_VERSION =~ /^1\.9/ then # bt's expanded, but __FILE__ isn't :(
|
14
14
|
File.expand_path __FILE__
|
15
15
|
elsif __FILE__ =~ /^[^\.]/ then # assume both relative
|
@@ -4,26 +4,28 @@ module Micronaut
|
|
4
4
|
include Micronaut::Matchers
|
5
5
|
include Micronaut::Mocking::WithMocha
|
6
6
|
|
7
|
-
def execute(
|
8
|
-
|
9
|
-
return result if self.class.examples.empty?
|
7
|
+
def execute(reporter)
|
8
|
+
return true if self.class.examples.empty?
|
10
9
|
self.class.all_before_alls.each { |aba| instance_eval(&aba) }
|
11
10
|
|
11
|
+
success = true
|
12
|
+
|
12
13
|
self.class.examples.each do |desc, opts, block|
|
13
14
|
execution_error = nil
|
14
|
-
|
15
|
+
reporter.example_started(self)
|
16
|
+
|
15
17
|
begin
|
16
18
|
setup_mocks
|
17
19
|
self.class.befores[:each].each { |be| instance_eval(&be) }
|
18
20
|
if block
|
19
|
-
result << '.'
|
20
21
|
instance_eval(&block)
|
22
|
+
reporter.example_passed(self)
|
21
23
|
else
|
22
|
-
|
24
|
+
reporter.example_pending([desc, self], 'Not yet implemented')
|
23
25
|
end
|
24
26
|
verify_mocks
|
25
27
|
rescue Exception => e
|
26
|
-
|
28
|
+
reporter.example_failed(self, e)
|
27
29
|
execution_error ||= e
|
28
30
|
ensure
|
29
31
|
teardown_mocks
|
@@ -32,11 +34,13 @@ module Micronaut
|
|
32
34
|
begin
|
33
35
|
self.class.afters[:each].each { |ae| instance_eval(&ae) }
|
34
36
|
rescue Exception => e
|
35
|
-
runner.complain(self, e)
|
36
37
|
execution_error ||= e
|
37
38
|
end
|
39
|
+
|
40
|
+
success &= execution_error.nil?
|
38
41
|
end
|
39
|
-
|
42
|
+
|
43
|
+
success
|
40
44
|
end
|
41
45
|
|
42
46
|
end
|
@@ -101,11 +101,11 @@ module Micronaut
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def all_before_alls
|
104
|
-
|
104
|
+
all_before_alls = []
|
105
105
|
each_ancestor do |ancestor|
|
106
|
-
|
106
|
+
all_before_alls << ancestor.before_alls
|
107
107
|
end
|
108
|
-
|
108
|
+
all_before_alls.concat(before_alls)
|
109
109
|
end
|
110
110
|
|
111
111
|
def run(runner)
|
@@ -28,7 +28,7 @@ module Micronaut
|
|
28
28
|
# it returns +false+, the spec passes and execution continues. If it returns
|
29
29
|
# +true+, then the spec fails with the message returned by <tt>matcher.negative_failure_message</tt>.
|
30
30
|
#
|
31
|
-
#
|
31
|
+
# Micronaut ships with a standard set of useful matchers, and writing your own
|
32
32
|
# matchers is quite simple. See Micronaut::Matchers for details.
|
33
33
|
module Expectations
|
34
34
|
class << self
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Micronaut
|
2
|
+
module Formatters
|
3
|
+
# Baseclass for formatters that implements all required methods as no-ops.
|
4
|
+
class BaseFormatter
|
5
|
+
attr_accessor :example_group, :options, :where, :total_example_failed, :total_example_pending
|
6
|
+
def initialize(options, where)
|
7
|
+
@options, @where = options, where
|
8
|
+
@total_example_failed, @total_example_pending = 0, 0
|
9
|
+
end
|
10
|
+
|
11
|
+
# This method is invoked before any examples are run, right after
|
12
|
+
# they have all been collected. This can be useful for special
|
13
|
+
# formatters that need to provide progress on feedback (graphical ones)
|
14
|
+
#
|
15
|
+
# This method will only be invoked once, and the next one to be invoked
|
16
|
+
# is #add_example_group
|
17
|
+
def start(example_count)
|
18
|
+
end
|
19
|
+
|
20
|
+
# This method is invoked at the beginning of the execution of each example_group.
|
21
|
+
# +example_group+ is the example_group.
|
22
|
+
#
|
23
|
+
# The next method to be invoked after this is #example_failed or #example_finished
|
24
|
+
def add_example_group(example_group)
|
25
|
+
@example_group = example_group
|
26
|
+
end
|
27
|
+
|
28
|
+
# This method is invoked when an +example+ starts.
|
29
|
+
def example_started(example)
|
30
|
+
end
|
31
|
+
|
32
|
+
# This method is invoked when an +example+ passes.
|
33
|
+
def example_passed(example)
|
34
|
+
end
|
35
|
+
|
36
|
+
# This method is invoked when an +example+ fails, i.e. an exception occurred
|
37
|
+
# inside it (such as a failed should or other exception). +counter+ is the
|
38
|
+
# sequence number of the failure (starting at 1) and +failure+ is the associated
|
39
|
+
# exception.
|
40
|
+
def example_failed(example, exception)
|
41
|
+
@total_example_failed += 1
|
42
|
+
end
|
43
|
+
|
44
|
+
# This method is invoked when an example is not yet implemented (i.e. has not
|
45
|
+
# been provided a block), or when an ExamplePendingError is raised.
|
46
|
+
# +message+ is the message from the ExamplePendingError, if it exists, or the
|
47
|
+
# default value of "Not Yet Implemented"
|
48
|
+
# +pending_caller+ is the file and line number of the spec which
|
49
|
+
# has called the pending method
|
50
|
+
def example_pending(example, message)
|
51
|
+
end
|
52
|
+
|
53
|
+
# This method is invoked after all of the examples have executed. The next method
|
54
|
+
# to be invoked after this one is #dump_failure (once for each failed example),
|
55
|
+
def start_dump
|
56
|
+
end
|
57
|
+
|
58
|
+
# Dumps detailed information about each example failure.
|
59
|
+
def dump_failures
|
60
|
+
end
|
61
|
+
|
62
|
+
# This method is invoked after the dumping of examples and failures.
|
63
|
+
def dump_summary(duration, example_count, failure_count, pending_count)
|
64
|
+
end
|
65
|
+
|
66
|
+
# This gets invoked after the summary if option is set to do so.
|
67
|
+
def dump_pending
|
68
|
+
end
|
69
|
+
|
70
|
+
# This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
|
71
|
+
def close
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Micronaut
|
2
|
+
module Formatters
|
3
|
+
|
4
|
+
class BaseTextFormatter < BaseFormatter
|
5
|
+
attr_reader :output, :pending_examples, :failed_examples
|
6
|
+
|
7
|
+
def initialize(options, output_to)
|
8
|
+
super
|
9
|
+
@output = output_to
|
10
|
+
@pending_examples = []
|
11
|
+
@failed_examples = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def example_pending(example, message)
|
15
|
+
super
|
16
|
+
# @pending_examples << [example.full_description, message, pending_caller]
|
17
|
+
@pending_examples << [example, message]
|
18
|
+
end
|
19
|
+
|
20
|
+
def example_failed(example, exception)
|
21
|
+
super
|
22
|
+
@failed_examples << [example, exception]
|
23
|
+
end
|
24
|
+
|
25
|
+
def dump_failures
|
26
|
+
@output.puts
|
27
|
+
@failed_examples.each_with_index do |examples_with_exception, index|
|
28
|
+
@output.puts "#{index.next})"
|
29
|
+
example, exception = examples_with_exception.first, examples_with_exception.last
|
30
|
+
@output.puts colorise("#{example}\n#{exception.message}", exception)
|
31
|
+
@output.puts format_backtrace(exception.backtrace)
|
32
|
+
@output.puts "\n"
|
33
|
+
@output.flush
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def colorise(s, failure)
|
38
|
+
if failure.is_a?(Micronaut::Expectations::ExpectationNotMetError)
|
39
|
+
red(s)
|
40
|
+
else
|
41
|
+
magenta(s)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def dump_summary(duration, example_count, failure_count, pending_count)
|
46
|
+
@output.puts
|
47
|
+
@output.puts "Finished in #{duration} seconds"
|
48
|
+
@output.puts
|
49
|
+
|
50
|
+
summary = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}"
|
51
|
+
summary << ", #{pending_count} pending" if pending_count > 0
|
52
|
+
|
53
|
+
if failure_count == 0
|
54
|
+
if pending_count > 0
|
55
|
+
@output.puts yellow(summary)
|
56
|
+
else
|
57
|
+
@output.puts green(summary)
|
58
|
+
end
|
59
|
+
else
|
60
|
+
@output.puts red(summary)
|
61
|
+
end
|
62
|
+
@output.flush
|
63
|
+
end
|
64
|
+
|
65
|
+
def dump_pending
|
66
|
+
unless @pending_examples.empty?
|
67
|
+
@output.puts
|
68
|
+
@output.puts "Pending:"
|
69
|
+
@pending_examples.each do |pending_example, message|
|
70
|
+
@output.puts "\n #{pending_example.last.class.name} #{pending_example.first}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
@output.flush
|
74
|
+
end
|
75
|
+
|
76
|
+
def close
|
77
|
+
if IO === @output && @output != $stdout
|
78
|
+
@output.close
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def format_backtrace(backtrace)
|
83
|
+
return "" if backtrace.nil?
|
84
|
+
backtrace.map { |line| backtrace_line(line) }.join("\n")
|
85
|
+
end
|
86
|
+
|
87
|
+
protected
|
88
|
+
|
89
|
+
def enable_color_in_output?
|
90
|
+
@options.enable_color_in_output?
|
91
|
+
end
|
92
|
+
|
93
|
+
def backtrace_line(line)
|
94
|
+
line.sub(/\A([^:]+:\d+)$/, '\\1:')
|
95
|
+
end
|
96
|
+
|
97
|
+
def color(text, color_code)
|
98
|
+
return text unless enable_color_in_output? && output_to_tty?
|
99
|
+
"#{color_code}#{text}\e[0m"
|
100
|
+
end
|
101
|
+
|
102
|
+
def output_to_tty?
|
103
|
+
begin
|
104
|
+
@output.tty? || ENV.has_key?("AUTOTEST")
|
105
|
+
rescue NoMethodError
|
106
|
+
false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def green(text); color(text, "\e[32m"); end
|
111
|
+
def red(text); color(text, "\e[31m"); end
|
112
|
+
def magenta(text); color(text, "\e[35m"); end
|
113
|
+
def yellow(text); color(text, "\e[33m"); end
|
114
|
+
def blue(text); color(text, "\e[34m"); end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Micronaut
|
2
|
+
module Formatters
|
3
|
+
|
4
|
+
class ProgressFormatter < BaseTextFormatter
|
5
|
+
|
6
|
+
def example_failed(example, exception)
|
7
|
+
super
|
8
|
+
@output.print colorise('F',exception)
|
9
|
+
@output.flush
|
10
|
+
end
|
11
|
+
|
12
|
+
def example_passed(example)
|
13
|
+
@output.print green('.')
|
14
|
+
@output.flush
|
15
|
+
end
|
16
|
+
|
17
|
+
def example_pending(example, message)
|
18
|
+
super
|
19
|
+
@output.print yellow('*')
|
20
|
+
@output.flush
|
21
|
+
end
|
22
|
+
|
23
|
+
def start_dump
|
24
|
+
@output.puts
|
25
|
+
@output.flush
|
26
|
+
end
|
27
|
+
|
28
|
+
def method_missing(sym, *args)
|
29
|
+
# ignore
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/micronaut/matchers.rb
CHANGED
@@ -19,7 +19,7 @@ require 'micronaut/matchers/operator_matcher'
|
|
19
19
|
|
20
20
|
module Micronaut
|
21
21
|
|
22
|
-
# We ship (courtesy of OSS and
|
22
|
+
# We ship (courtesy of OSS and Micronaut) with a number of useful Expression Matchers. An Expression Matcher
|
23
23
|
# is any object that responds to the following methods:
|
24
24
|
#
|
25
25
|
# matches?(actual)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Micronaut
|
2
|
+
|
3
|
+
class Runner
|
4
|
+
|
5
|
+
@@installed_at_exit ||= false
|
6
|
+
|
7
|
+
def self.options
|
8
|
+
@options ||= Micronaut::RunnerOptions.new(:color => true, :formatter => :progress)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.autorun
|
12
|
+
at_exit {
|
13
|
+
Micronaut::Runner.new.run(ARGV) ? exit(0) : exit(1)
|
14
|
+
} unless @@installed_at_exit
|
15
|
+
@@installed_at_exit = true
|
16
|
+
end
|
17
|
+
|
18
|
+
def options
|
19
|
+
self.class.options
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(args = [])
|
23
|
+
@verbose = args.delete('-v')
|
24
|
+
|
25
|
+
filter = if args.first =~ /^(-n|--name)$/ then
|
26
|
+
args.shift
|
27
|
+
arg = args.shift
|
28
|
+
arg =~ /\/(.*)\// ? Regexp.new($1) : arg
|
29
|
+
else
|
30
|
+
/./ # anything - ^example_ already filtered by #examples
|
31
|
+
end
|
32
|
+
|
33
|
+
total_examples = Micronaut::ExampleWorld.example_groups.inject(0) { |sum, eg| sum + eg.examples.size }
|
34
|
+
|
35
|
+
old_sync, options.formatter.output.sync = options.formatter.output.sync, true if options.formatter.output.respond_to?(:sync=)
|
36
|
+
|
37
|
+
options.formatter.start(total_examples)
|
38
|
+
|
39
|
+
suite_success = true
|
40
|
+
|
41
|
+
starts_at = Time.now
|
42
|
+
Micronaut::ExampleWorld.example_groups.each do |example_group|
|
43
|
+
suite_success &= example_group.run(options.formatter)
|
44
|
+
end
|
45
|
+
duration = Time.now - starts_at
|
46
|
+
|
47
|
+
options.formatter.end
|
48
|
+
options.formatter.dump
|
49
|
+
|
50
|
+
options.formatter.start_dump
|
51
|
+
options.formatter.dump_pending
|
52
|
+
options.formatter.dump_failures
|
53
|
+
options.formatter.dump_summary(duration, total_examples, options.formatter.failed_examples.size, options.formatter.pending_examples.size)
|
54
|
+
|
55
|
+
options.formatter.output.sync = old_sync if options.formatter.output.respond_to? :sync=
|
56
|
+
|
57
|
+
suite_success
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Micronaut
|
2
|
+
|
3
|
+
class RunnerOptions
|
4
|
+
|
5
|
+
attr_accessor :color, :formatter
|
6
|
+
|
7
|
+
def initialize(options={})
|
8
|
+
@color = options.delete(:color)
|
9
|
+
@formatter = options.delete(:formatter)
|
10
|
+
end
|
11
|
+
|
12
|
+
def enable_color_in_output?
|
13
|
+
@color
|
14
|
+
end
|
15
|
+
|
16
|
+
def output
|
17
|
+
$stdout
|
18
|
+
end
|
19
|
+
|
20
|
+
def formatter
|
21
|
+
@formatter_instance ||= Micronaut::Formatters::ProgressFormatter.new(self, output)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spicycode-micronaut
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chad Humphries
|
@@ -9,7 +9,7 @@ autorequire: micronaut
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-11-
|
12
|
+
date: 2008-11-27 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -40,7 +40,6 @@ files:
|
|
40
40
|
- lib/micronaut
|
41
41
|
- lib/micronaut/behaviour_group.rb
|
42
42
|
- lib/micronaut/behaviour_group_class_methods.rb
|
43
|
-
- lib/micronaut/example_runner.rb
|
44
43
|
- lib/micronaut/example_world.rb
|
45
44
|
- lib/micronaut/expectations
|
46
45
|
- lib/micronaut/expectations/differs
|
@@ -55,6 +54,11 @@ files:
|
|
55
54
|
- lib/micronaut/expectations.rb
|
56
55
|
- lib/micronaut/extensions
|
57
56
|
- lib/micronaut/extensions/kernel.rb
|
57
|
+
- lib/micronaut/formatters
|
58
|
+
- lib/micronaut/formatters/base_formatter.rb
|
59
|
+
- lib/micronaut/formatters/base_text_formatter.rb
|
60
|
+
- lib/micronaut/formatters/progress_formatter.rb
|
61
|
+
- lib/micronaut/formatters.rb
|
58
62
|
- lib/micronaut/matchers
|
59
63
|
- lib/micronaut/matchers/be.rb
|
60
64
|
- lib/micronaut/matchers/be_close.rb
|
@@ -78,6 +82,8 @@ files:
|
|
78
82
|
- lib/micronaut/matchers.rb
|
79
83
|
- lib/micronaut/mocking
|
80
84
|
- lib/micronaut/mocking/with_mocha.rb
|
85
|
+
- lib/micronaut/runner.rb
|
86
|
+
- lib/micronaut/runner_options.rb
|
81
87
|
- lib/micronaut.rb
|
82
88
|
- examples/example_helper.rb
|
83
89
|
- examples/lib
|
@@ -91,6 +97,9 @@ files:
|
|
91
97
|
- examples/lib/micronaut/expectations/extensions/object_example.rb
|
92
98
|
- examples/lib/micronaut/expectations/fail_with_example.rb
|
93
99
|
- examples/lib/micronaut/expectations/wrap_expectation_example.rb
|
100
|
+
- examples/lib/micronaut/formatters
|
101
|
+
- examples/lib/micronaut/formatters/base_formatter_example.rb
|
102
|
+
- examples/lib/micronaut/formatters/progress_formatter_example.rb
|
94
103
|
- examples/lib/micronaut/matchers
|
95
104
|
- examples/lib/micronaut/matchers/be_close_example.rb
|
96
105
|
- examples/lib/micronaut/matchers/be_example.rb
|
@@ -1,106 +0,0 @@
|
|
1
|
-
module Micronaut
|
2
|
-
class ExampleRunner
|
3
|
-
|
4
|
-
attr_accessor :report, :failures, :errors
|
5
|
-
attr_accessor :example_count
|
6
|
-
|
7
|
-
@@installed_at_exit ||= false
|
8
|
-
@@out = $stdout
|
9
|
-
|
10
|
-
def initialize
|
11
|
-
@report = []
|
12
|
-
@errors, @failures = 0, 0
|
13
|
-
@verbose = false
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.autorun
|
17
|
-
at_exit {
|
18
|
-
exit_code = Micronaut::ExampleRunner.new.run(ARGV)
|
19
|
-
exit false if exit_code && exit_code != 0
|
20
|
-
} unless @@installed_at_exit
|
21
|
-
@@installed_at_exit = true
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.output=(stream)
|
25
|
-
@@out = stream
|
26
|
-
end
|
27
|
-
|
28
|
-
def location(e)
|
29
|
-
e.backtrace.find { |s| s !~ /in .(expectations|fail)/ }.sub(/:in .*$/, '')
|
30
|
-
end
|
31
|
-
|
32
|
-
def complain(group, e)
|
33
|
-
bt = Micronaut::filter_backtrace(e.backtrace).join("\n ")
|
34
|
-
|
35
|
-
e = case e.class.to_s
|
36
|
-
when /Micronaut::Expectations/, 'Mocha::ExpectationError' then
|
37
|
-
@failures += 1
|
38
|
-
"Failure:\n#{group.class.name}(#{group.class}) [#{location(e)}]:\n#{e.message}\n #{bt}\n"
|
39
|
-
else
|
40
|
-
puts e.to_s
|
41
|
-
@errors += 1
|
42
|
-
"Error:\n#{group.class.name}(#{group.class}):\n#{e.class}: #{e.message}\n #{bt}\n"
|
43
|
-
end
|
44
|
-
@report << e
|
45
|
-
e[0, 1]
|
46
|
-
end
|
47
|
-
|
48
|
-
##
|
49
|
-
# Top level driver, controls all output and filtering.
|
50
|
-
def run(args = [])
|
51
|
-
@verbose = args.delete('-v')
|
52
|
-
|
53
|
-
filter = if args.first =~ /^(-n|--name)$/ then
|
54
|
-
args.shift
|
55
|
-
arg = args.shift
|
56
|
-
arg =~ /\/(.*)\// ? Regexp.new($1) : arg
|
57
|
-
else
|
58
|
-
/./ # anything - ^example_ already filtered by #examples
|
59
|
-
end
|
60
|
-
|
61
|
-
@@out.puts "Loading examples from #{$0}\nStarted"
|
62
|
-
|
63
|
-
start = Time.now
|
64
|
-
run_examples filter
|
65
|
-
|
66
|
-
@@out.puts
|
67
|
-
@@out.puts "Finished in #{'%.6f' % (Time.now - start)} seconds."
|
68
|
-
|
69
|
-
@report.each_with_index do |msg, i|
|
70
|
-
@@out.puts "\n%3d) %s" % [i + 1, msg]
|
71
|
-
end
|
72
|
-
|
73
|
-
@@out.puts
|
74
|
-
|
75
|
-
format = "%d examples, %d failures, %d errors"
|
76
|
-
@@out.puts format % [example_count, failures, errors]
|
77
|
-
|
78
|
-
return failures + errors if @example_count > 0 # or return nil...
|
79
|
-
end
|
80
|
-
|
81
|
-
def run_examples(filter = /./)
|
82
|
-
@example_count = 0
|
83
|
-
old_sync, @@out.sync = @@out.sync, true if @@out.respond_to?(:sync=)
|
84
|
-
|
85
|
-
Micronaut::ExampleWorld.example_groups.each do |example_group|
|
86
|
-
# example_group.examples.grep(filter).each do |test|
|
87
|
-
# example_group.examples.each do |example|
|
88
|
-
@@out.print "#{example_group.name}: " if @verbose
|
89
|
-
|
90
|
-
t = Time.now if @verbose
|
91
|
-
result = example_group.run(self)
|
92
|
-
|
93
|
-
@example_count += example_group.examples.size
|
94
|
-
|
95
|
-
@@out.print "%.6fs: " % (Time.now - t) if @verbose
|
96
|
-
@@out.print(result) if result
|
97
|
-
@@out.puts if @verbose
|
98
|
-
# end
|
99
|
-
end
|
100
|
-
|
101
|
-
@@out.sync = old_sync if @@out.respond_to? :sync=
|
102
|
-
@example_count
|
103
|
-
end
|
104
|
-
|
105
|
-
end
|
106
|
-
end
|