micronaut 0.2.9
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +15 -0
- data/LICENSE +45 -0
- data/README.markdown +66 -0
- data/RSPEC-LICENSE +23 -0
- data/Rakefile +78 -0
- data/VERSION.yml +4 -0
- data/bin/micronaut +4 -0
- data/examples/example_helper.rb +54 -0
- data/examples/lib/micronaut/behaviour_example.rb +351 -0
- data/examples/lib/micronaut/configuration_example.rb +133 -0
- data/examples/lib/micronaut/example_example.rb +67 -0
- data/examples/lib/micronaut/expectations/extensions/object_example.rb +146 -0
- data/examples/lib/micronaut/expectations/fail_with_example.rb +17 -0
- data/examples/lib/micronaut/expectations/wrap_expectation_example.rb +27 -0
- data/examples/lib/micronaut/formatters/base_formatter_example.rb +117 -0
- data/examples/lib/micronaut/formatters/documentation_formatter_example.rb +5 -0
- data/examples/lib/micronaut/formatters/progress_formatter_example.rb +29 -0
- data/examples/lib/micronaut/kernel_extensions_example.rb +13 -0
- data/examples/lib/micronaut/matchers/be_close_example.rb +52 -0
- data/examples/lib/micronaut/matchers/be_example.rb +298 -0
- data/examples/lib/micronaut/matchers/change_example.rb +360 -0
- data/examples/lib/micronaut/matchers/description_generation_example.rb +175 -0
- data/examples/lib/micronaut/matchers/eql_example.rb +35 -0
- data/examples/lib/micronaut/matchers/equal_example.rb +35 -0
- data/examples/lib/micronaut/matchers/has_example.rb +69 -0
- data/examples/lib/micronaut/matchers/have_example.rb +392 -0
- data/examples/lib/micronaut/matchers/include_example.rb +103 -0
- data/examples/lib/micronaut/matchers/match_example.rb +43 -0
- data/examples/lib/micronaut/matchers/matcher_methods_example.rb +78 -0
- data/examples/lib/micronaut/matchers/operator_matcher_example.rb +193 -0
- data/examples/lib/micronaut/matchers/raise_error_example.rb +348 -0
- data/examples/lib/micronaut/matchers/respond_to_example.rb +54 -0
- data/examples/lib/micronaut/matchers/satisfy_example.rb +36 -0
- data/examples/lib/micronaut/matchers/simple_matcher_example.rb +93 -0
- data/examples/lib/micronaut/matchers/throw_symbol_example.rb +125 -0
- data/examples/lib/micronaut/mocha_example.rb +29 -0
- data/examples/lib/micronaut/runner_example.rb +41 -0
- data/examples/lib/micronaut/world_example.rb +98 -0
- data/examples/lib/micronaut_example.rb +43 -0
- data/examples/resources/example_classes.rb +67 -0
- data/lib/micronaut.rb +40 -0
- data/lib/micronaut/behaviour.rb +217 -0
- data/lib/micronaut/configuration.rb +162 -0
- data/lib/micronaut/example.rb +112 -0
- data/lib/micronaut/expectations.rb +45 -0
- data/lib/micronaut/expectations/extensions/object.rb +92 -0
- data/lib/micronaut/expectations/handler.rb +51 -0
- data/lib/micronaut/expectations/wrap_expectation.rb +52 -0
- data/lib/micronaut/formatters.rb +12 -0
- data/lib/micronaut/formatters/base_formatter.rb +127 -0
- data/lib/micronaut/formatters/base_text_formatter.rb +139 -0
- data/lib/micronaut/formatters/documentation_formatter.rb +78 -0
- data/lib/micronaut/formatters/progress_formatter.rb +30 -0
- data/lib/micronaut/kernel_extensions.rb +11 -0
- data/lib/micronaut/matchers.rb +141 -0
- data/lib/micronaut/matchers/be.rb +204 -0
- data/lib/micronaut/matchers/be_close.rb +37 -0
- data/lib/micronaut/matchers/change.rb +148 -0
- data/lib/micronaut/matchers/eql.rb +26 -0
- data/lib/micronaut/matchers/equal.rb +26 -0
- data/lib/micronaut/matchers/generated_descriptions.rb +36 -0
- data/lib/micronaut/matchers/has.rb +19 -0
- data/lib/micronaut/matchers/have.rb +153 -0
- data/lib/micronaut/matchers/include.rb +80 -0
- data/lib/micronaut/matchers/match.rb +22 -0
- data/lib/micronaut/matchers/method_missing.rb +9 -0
- data/lib/micronaut/matchers/operator_matcher.rb +50 -0
- data/lib/micronaut/matchers/raise_error.rb +128 -0
- data/lib/micronaut/matchers/respond_to.rb +50 -0
- data/lib/micronaut/matchers/satisfy.rb +50 -0
- data/lib/micronaut/matchers/simple_matcher.rb +135 -0
- data/lib/micronaut/matchers/throw_symbol.rb +108 -0
- data/lib/micronaut/mocking/with_absolutely_nothing.rb +11 -0
- data/lib/micronaut/mocking/with_mocha.rb +15 -0
- data/lib/micronaut/mocking/with_rr.rb +24 -0
- data/lib/micronaut/rake_task.rb +84 -0
- data/lib/micronaut/runner.rb +60 -0
- data/lib/micronaut/world.rb +75 -0
- metadata +165 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
module Micronaut
|
2
|
+
|
3
|
+
class Example
|
4
|
+
|
5
|
+
attr_reader :behaviour, :description, :metadata, :example_block
|
6
|
+
|
7
|
+
def initialize(behaviour, desc, options, example_block=nil)
|
8
|
+
@behaviour, @description, @options, @example_block = behaviour, desc, options, example_block
|
9
|
+
@metadata = @behaviour.metadata.dup
|
10
|
+
@metadata[:description] = description
|
11
|
+
@metadata[:execution_result] = {}
|
12
|
+
@metadata[:caller] = options.delete(:caller)
|
13
|
+
if @metadata[:caller]
|
14
|
+
@metadata[:file_path] = @metadata[:caller].split(":")[0].strip
|
15
|
+
@metadata[:line_number] = @metadata[:caller].split(":")[1].to_i
|
16
|
+
end
|
17
|
+
@metadata.update(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def record_results(results={})
|
21
|
+
@metadata[:execution_result].update(results)
|
22
|
+
end
|
23
|
+
|
24
|
+
def execution_result
|
25
|
+
@metadata[:execution_result]
|
26
|
+
end
|
27
|
+
|
28
|
+
def file_path
|
29
|
+
@metadata[:file_path] || behaviour.file_path
|
30
|
+
end
|
31
|
+
|
32
|
+
def run_started
|
33
|
+
record_results :started_at => Time.now
|
34
|
+
end
|
35
|
+
|
36
|
+
def run_passed
|
37
|
+
run_finished 'passed'
|
38
|
+
end
|
39
|
+
|
40
|
+
def run_pending(message='Not yet implemented')
|
41
|
+
run_finished 'pending', :pending_message => message
|
42
|
+
end
|
43
|
+
|
44
|
+
def run_failed(exception)
|
45
|
+
run_finished 'failed', :exception_encountered => exception
|
46
|
+
end
|
47
|
+
|
48
|
+
def run_finished(status, results={})
|
49
|
+
record_results results.update(:status => status)
|
50
|
+
finish_time = Time.now
|
51
|
+
record_results :finished_at => finish_time, :run_time => (finish_time - execution_result[:started_at])
|
52
|
+
Micronaut.configuration.formatter.example_finished(self)
|
53
|
+
end
|
54
|
+
|
55
|
+
def run_before_each
|
56
|
+
@behaviour_instance._setup_mocks if @behaviour_instance.respond_to?(:_setup_mocks)
|
57
|
+
@behaviour.eval_before_eachs(@behaviour_instance)
|
58
|
+
end
|
59
|
+
|
60
|
+
def run_after_each
|
61
|
+
@behaviour.eval_after_eachs(@behaviour_instance)
|
62
|
+
@behaviour_instance._verify_mocks if @behaviour_instance.respond_to?(:_verify_mocks)
|
63
|
+
ensure
|
64
|
+
@behaviour_instance._teardown_mocks if @behaviour_instance.respond_to?(:_teardown_mocks)
|
65
|
+
end
|
66
|
+
|
67
|
+
def run(behaviour_instance)
|
68
|
+
@behaviour_instance = behaviour_instance
|
69
|
+
@behaviour_instance.running_example = self
|
70
|
+
|
71
|
+
run_started
|
72
|
+
|
73
|
+
all_systems_nominal = true
|
74
|
+
exception_encountered = nil
|
75
|
+
|
76
|
+
begin
|
77
|
+
run_before_each
|
78
|
+
@behaviour_instance.instance_eval(&example_block) if example_block
|
79
|
+
rescue Exception => e
|
80
|
+
exception_encountered = e
|
81
|
+
all_systems_nominal = false
|
82
|
+
end
|
83
|
+
|
84
|
+
begin
|
85
|
+
run_after_each
|
86
|
+
rescue Exception => e
|
87
|
+
exception_encountered ||= e
|
88
|
+
all_systems_nominal = false
|
89
|
+
ensure
|
90
|
+
@behaviour_instance.running_example = nil
|
91
|
+
end
|
92
|
+
|
93
|
+
if exception_encountered
|
94
|
+
run_failed(exception_encountered)
|
95
|
+
else
|
96
|
+
example_block ? run_passed : run_pending
|
97
|
+
end
|
98
|
+
|
99
|
+
all_systems_nominal
|
100
|
+
end
|
101
|
+
|
102
|
+
def inspect
|
103
|
+
"#{@metadata[:behaviour][:name]} - #{@metadata[:description]}"
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_s
|
107
|
+
inspect
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'micronaut/matchers'
|
2
|
+
require 'micronaut/expectations/extensions/object'
|
3
|
+
require 'micronaut/expectations/handler'
|
4
|
+
require 'micronaut/expectations/wrap_expectation'
|
5
|
+
|
6
|
+
module Micronaut
|
7
|
+
|
8
|
+
# Micronaut::Expectations lets you set expectations on your objects.
|
9
|
+
#
|
10
|
+
# result.should == 37
|
11
|
+
# team.should have(11).players_on_the_field
|
12
|
+
#
|
13
|
+
# == How Expectations work.
|
14
|
+
#
|
15
|
+
# Micronaut::Expectations adds two methods to Object:
|
16
|
+
#
|
17
|
+
# should(matcher=nil)
|
18
|
+
# should_not(matcher=nil)
|
19
|
+
#
|
20
|
+
# Both methods take an optional Expression Matcher (See Micronaut::Matchers).
|
21
|
+
#
|
22
|
+
# When +should+ receives an Expression Matcher, it calls <tt>matches?(self)</tt>. If
|
23
|
+
# it returns +true+, the spec passes and execution continues. If it returns
|
24
|
+
# +false+, then the spec fails with the message returned by <tt>matcher.failure_message</tt>.
|
25
|
+
#
|
26
|
+
# Similarly, when +should_not+ receives a matcher, it calls <tt>matches?(self)</tt>. If
|
27
|
+
# it returns +false+, the spec passes and execution continues. If it returns
|
28
|
+
# +true+, then the spec fails with the message returned by <tt>matcher.negative_failure_message</tt>.
|
29
|
+
#
|
30
|
+
# Micronaut ships with a standard set of useful matchers, and writing your own
|
31
|
+
# matchers is quite simple. See Micronaut::Matchers for details.
|
32
|
+
module Expectations
|
33
|
+
|
34
|
+
class ExpectationNotMetError < ::StandardError; end
|
35
|
+
|
36
|
+
def self.fail_with(message, expected=nil, target=nil) # :nodoc:
|
37
|
+
if Array === message && message.length == 3
|
38
|
+
message, expected, target = message[0], message[1], message[2]
|
39
|
+
end
|
40
|
+
Kernel::raise(Micronaut::Expectations::ExpectationNotMetError.new(message))
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Micronaut
|
2
|
+
module Expectations
|
3
|
+
class InvalidMatcherError < ArgumentError; end
|
4
|
+
|
5
|
+
module ObjectExpectations
|
6
|
+
# :call-seq:
|
7
|
+
# should(matcher)
|
8
|
+
# should == expected
|
9
|
+
# should === expected
|
10
|
+
# should =~ expected
|
11
|
+
#
|
12
|
+
# receiver.should(matcher)
|
13
|
+
# => Passes if matcher.matches?(receiver)
|
14
|
+
#
|
15
|
+
# receiver.should == expected #any value
|
16
|
+
# => Passes if (receiver == expected)
|
17
|
+
#
|
18
|
+
# receiver.should === expected #any value
|
19
|
+
# => Passes if (receiver === expected)
|
20
|
+
#
|
21
|
+
# receiver.should =~ regexp
|
22
|
+
# => Passes if (receiver =~ regexp)
|
23
|
+
#
|
24
|
+
# See Micronaut::Matchers for more information about matchers
|
25
|
+
#
|
26
|
+
# == Warning
|
27
|
+
# NOTE that this does NOT support receiver.should != expected.
|
28
|
+
# Instead, use receiver.should_not == expected
|
29
|
+
def should(matcher=nil, &block)
|
30
|
+
::Micronaut::Matchers.last_should = "should"
|
31
|
+
return ::Micronaut::Matchers::PositiveOperatorMatcher.new(self) if matcher.nil?
|
32
|
+
|
33
|
+
unless matcher.respond_to?(:matches?)
|
34
|
+
raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
|
35
|
+
end
|
36
|
+
|
37
|
+
match_found = matcher.matches?(self, &block)
|
38
|
+
::Micronaut::Matchers.last_matcher = matcher
|
39
|
+
|
40
|
+
::Micronaut::Expectations.fail_with(matcher.failure_message) unless match_found
|
41
|
+
match_found
|
42
|
+
end
|
43
|
+
|
44
|
+
# :call-seq:
|
45
|
+
# should_not(matcher)
|
46
|
+
# should_not == expected
|
47
|
+
# should_not === expected
|
48
|
+
# should_not =~ expected
|
49
|
+
#
|
50
|
+
# receiver.should_not(matcher)
|
51
|
+
# => Passes unless matcher.matches?(receiver)
|
52
|
+
#
|
53
|
+
# receiver.should_not == expected
|
54
|
+
# => Passes unless (receiver == expected)
|
55
|
+
#
|
56
|
+
# receiver.should_not === expected
|
57
|
+
# => Passes unless (receiver === expected)
|
58
|
+
#
|
59
|
+
# receiver.should_not =~ regexp
|
60
|
+
# => Passes unless (receiver =~ regexp)
|
61
|
+
#
|
62
|
+
# See Micronaut::Matchers for more information about matchers
|
63
|
+
def should_not(matcher=nil, &block)
|
64
|
+
::Micronaut::Matchers.last_should = "should not"
|
65
|
+
return ::Micronaut::Matchers::NegativeOperatorMatcher.new(self) if matcher.nil?
|
66
|
+
|
67
|
+
unless matcher.respond_to?(:matches?)
|
68
|
+
raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
|
69
|
+
end
|
70
|
+
|
71
|
+
unless matcher.respond_to?(:negative_failure_message)
|
72
|
+
::Micronaut::Expectations.fail_with(
|
73
|
+
<<-EOF
|
74
|
+
Matcher does not support should_not.
|
75
|
+
See Micronaut::Matchers for more information about matchers.
|
76
|
+
EOF
|
77
|
+
)
|
78
|
+
end
|
79
|
+
match_found = matcher.matches?(self, &block)
|
80
|
+
::Micronaut::Matchers.last_matcher = matcher
|
81
|
+
|
82
|
+
::Micronaut::Expectations.fail_with(matcher.negative_failure_message) if match_found
|
83
|
+
match_found
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class Object
|
91
|
+
include Micronaut::Expectations::ObjectExpectations
|
92
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Micronaut
|
2
|
+
module Expectations
|
3
|
+
|
4
|
+
|
5
|
+
# class ExpectationMatcherHandler
|
6
|
+
#
|
7
|
+
# def self.handle_matcher(actual, matcher, &block)
|
8
|
+
# ::Micronaut::Matchers.last_should = "should"
|
9
|
+
# return Micronaut::Matchers::PositiveOperatorMatcher.new(actual) if matcher.nil?
|
10
|
+
#
|
11
|
+
# unless matcher.respond_to?(:matches?)
|
12
|
+
# raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# match = matcher.matches?(actual, &block)
|
16
|
+
# ::Micronaut::Matchers.last_matcher = matcher
|
17
|
+
# Micronaut::Expectations.fail_with(matcher.failure_message) unless match
|
18
|
+
# match
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# end
|
22
|
+
|
23
|
+
# class NegativeExpectationMatcherHandler
|
24
|
+
#
|
25
|
+
# def self.handle_matcher(actual, matcher, &block)
|
26
|
+
# ::Micronaut::Matchers.last_should = "should not"
|
27
|
+
# return Micronaut::Matchers::NegativeOperatorMatcher.new(actual) if matcher.nil?
|
28
|
+
#
|
29
|
+
# unless matcher.respond_to?(:matches?)
|
30
|
+
# raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# unless matcher.respond_to?(:negative_failure_message)
|
34
|
+
# Micronaut::Expectations.fail_with(
|
35
|
+
# <<-EOF
|
36
|
+
# Matcher does not support should_not.
|
37
|
+
# See Micronaut::Matchers for more information
|
38
|
+
# about matchers.
|
39
|
+
# EOF
|
40
|
+
# )
|
41
|
+
# end
|
42
|
+
# match = matcher.matches?(actual, &block)
|
43
|
+
# ::Micronaut::Matchers.last_matcher = matcher
|
44
|
+
# Micronaut::Expectations.fail_with(matcher.negative_failure_message) if match
|
45
|
+
# match
|
46
|
+
# end
|
47
|
+
|
48
|
+
# end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Micronaut
|
2
|
+
module Matchers
|
3
|
+
|
4
|
+
# wraps an expectation in a block that will return true if the
|
5
|
+
# expectation passes and false if it fails (without bubbling up
|
6
|
+
# the failure).
|
7
|
+
#
|
8
|
+
# This is intended to be used in the context of a simple matcher,
|
9
|
+
# and is especially useful for wrapping multiple expectations or
|
10
|
+
# one or more assertions from test/unit extensions when running
|
11
|
+
# with test/unit.
|
12
|
+
#
|
13
|
+
# == Examples
|
14
|
+
#
|
15
|
+
# def eat_cheese(cheese)
|
16
|
+
# simple_matcher do |mouse, matcher|
|
17
|
+
# matcher.negative_failure_message = "expected #{mouse} not to eat cheese"
|
18
|
+
# wrap_expectation do |matcher|
|
19
|
+
# assert_eats_cheese(mouse)
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# describe Mouse do
|
25
|
+
# it "eats cheese" do
|
26
|
+
# Mouse.new.should eat_cheese
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# The other benefit you get is that you can use the negative version
|
31
|
+
# of the matcher:
|
32
|
+
#
|
33
|
+
# describe Cat do
|
34
|
+
# it "does not eat cheese" do
|
35
|
+
# Cat.new.should_not eat_cheese
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# So in the event there is no assert_does_not_eat_cheese available,
|
40
|
+
# you're all set!
|
41
|
+
def wrap_expectation(matcher, &block)
|
42
|
+
begin
|
43
|
+
block.call(matcher)
|
44
|
+
return true
|
45
|
+
rescue Exception => e
|
46
|
+
matcher.failure_message = e.message
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'micronaut/formatters/base_formatter'
|
2
|
+
require 'micronaut/formatters/base_text_formatter'
|
3
|
+
require 'micronaut/formatters/documentation_formatter'
|
4
|
+
require 'micronaut/formatters/progress_formatter'
|
5
|
+
|
6
|
+
module Micronaut
|
7
|
+
|
8
|
+
module Formatters
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module Micronaut
|
2
|
+
module Formatters
|
3
|
+
|
4
|
+
class BaseFormatter
|
5
|
+
attr_accessor :behaviour
|
6
|
+
attr_reader :example_count, :duration, :examples
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@example_count = 0
|
10
|
+
@examples = []
|
11
|
+
@behaviour = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def configuration
|
15
|
+
Micronaut.configuration
|
16
|
+
end
|
17
|
+
|
18
|
+
def output
|
19
|
+
Micronaut.configuration.output
|
20
|
+
end
|
21
|
+
|
22
|
+
def trace(&blk)
|
23
|
+
Micronaut.configuration.trace(trace_override_flag, &blk)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Allow setting trace at the behaviour level as well globally
|
27
|
+
def trace_override_flag
|
28
|
+
behaviour && behaviour.metadata[:trace]
|
29
|
+
end
|
30
|
+
|
31
|
+
def profile_examples?
|
32
|
+
Micronaut.configuration.profile_examples
|
33
|
+
end
|
34
|
+
|
35
|
+
def color_enabled?
|
36
|
+
configuration.color_enabled?
|
37
|
+
end
|
38
|
+
|
39
|
+
def pending_examples
|
40
|
+
@pending_examples ||= ::Micronaut.world.find(examples, :execution_result => { :status => 'pending' })
|
41
|
+
end
|
42
|
+
|
43
|
+
def failed_examples
|
44
|
+
@failed_examples ||= ::Micronaut.world.find(examples, :execution_result => { :status => 'failed' })
|
45
|
+
end
|
46
|
+
|
47
|
+
# This method is invoked before any examples are run, right after
|
48
|
+
# they have all been collected. This can be useful for special
|
49
|
+
# formatters that need to provide progress on feedback (graphical ones)
|
50
|
+
#
|
51
|
+
# This method will only be invoked once, and the next one to be invoked
|
52
|
+
# is #add_behaviour
|
53
|
+
def start(example_count)
|
54
|
+
@example_count = example_count
|
55
|
+
end
|
56
|
+
|
57
|
+
def example_finished(example)
|
58
|
+
examples << example
|
59
|
+
end
|
60
|
+
|
61
|
+
# This method is invoked at the beginning of the execution of each behaviour.
|
62
|
+
# +behaviour+ is the behaviour.
|
63
|
+
#
|
64
|
+
# The next method to be invoked after this is #example_failed or #example_finished
|
65
|
+
def add_behaviour(behaviour)
|
66
|
+
@behaviour = behaviour
|
67
|
+
end
|
68
|
+
|
69
|
+
# This method is invoked after all of the examples have executed. The next method
|
70
|
+
# to be invoked after this one is #dump_failure (once for each failed example),
|
71
|
+
def start_dump(duration)
|
72
|
+
@duration = duration
|
73
|
+
end
|
74
|
+
|
75
|
+
# Dumps detailed information about each example failure.
|
76
|
+
def dump_failures
|
77
|
+
end
|
78
|
+
|
79
|
+
# This method is invoked after the dumping of examples and failures.
|
80
|
+
def dump_summary
|
81
|
+
end
|
82
|
+
|
83
|
+
# This gets invoked after the summary if option is set to do so.
|
84
|
+
def dump_pending
|
85
|
+
end
|
86
|
+
|
87
|
+
# This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
|
88
|
+
def close
|
89
|
+
end
|
90
|
+
|
91
|
+
def format_backtrace(backtrace, example)
|
92
|
+
return "" unless backtrace
|
93
|
+
return backtrace if example.metadata[:full_backtrace] == true
|
94
|
+
|
95
|
+
cleansed = backtrace.select { |line| backtrace_line(line) }
|
96
|
+
# Kick the describe stack info off the list, just keep the line the problem happened on from that file
|
97
|
+
# cleansed = [cleansed.detect { |line| line.split(':').first == example.metadata[:caller].split(':').first }] if cleansed.size > 1
|
98
|
+
cleansed.empty? ? backtrace : cleansed
|
99
|
+
end
|
100
|
+
|
101
|
+
protected
|
102
|
+
|
103
|
+
def backtrace_line(line)
|
104
|
+
return nil if configuration.cleaned_from_backtrace?(line)
|
105
|
+
line.sub!(/\A([^:]+:\d+)$/, '\\1')
|
106
|
+
return nil if line == '-e:1'
|
107
|
+
line
|
108
|
+
end
|
109
|
+
|
110
|
+
def read_failed_line(exception, example)
|
111
|
+
original_file = example.file_path.to_s.downcase
|
112
|
+
matching_line = exception.backtrace.detect { |line| line.split(':').first.downcase == original_file.downcase }
|
113
|
+
|
114
|
+
return "Unable to find matching line from backtrace" if matching_line.nil?
|
115
|
+
|
116
|
+
file_path, line_number = matching_line.split(':')
|
117
|
+
if File.exist?(file_path)
|
118
|
+
open(file_path, 'r') { |f| f.readlines[line_number.to_i - 1] }
|
119
|
+
else
|
120
|
+
"Unable to find #{file_path} to read failed line"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|