minitest-fastfail 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ Current
2
+ =======
3
+
4
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Chirantan Mitra
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # MiniTest FastFail
2
+
3
+ Run minitests in dot-format. However if tests fail show full scope, description and the relevant stack-trace.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'minitest-fastfail'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install minitest-fastfail
18
+
19
+ ## Usage
20
+
21
+ Include the gem in your project
22
+
23
+ ## Contributing
24
+
25
+ * Fork the project.
26
+ * Make your feature addition or bug fix.
27
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
28
+ * Commit, but do not mess with the VERSION. If you want to have your own version, that is fine but bump the version in a commit by itself in another branch so I can ignore it when I pull.
29
+ * Send me a pull request.
@@ -0,0 +1,38 @@
1
+ require "minitest/unit"
2
+
3
+ module MiniTestFastFail
4
+ # Based upon Alexander Kern's minitest-reporters (MIT License)
5
+ # @see https://github.com/CapnKernul/minitest-reporters minitest-reporters
6
+
7
+ require "minitest-fastfail/reporter"
8
+ require "minitest-fastfail/fast_fail_reporter"
9
+ require "minitest-fastfail/reporter_runner"
10
+ require "minitest-fastfail/before_test_hook"
11
+ require "minitest-fastfail/test_runner"
12
+
13
+ module Reporters
14
+ def self.use!(console_reporters = DefaultReporter.new)
15
+ use_runner!(console_reporters)
16
+ use_before_test_hook!
17
+ use_parallel_length_method!
18
+ end
19
+
20
+ def self.use_runner!(console_reporters)
21
+ runner = MiniTestFastFail::ReporterRunner.new
22
+ runner.reporters = Array(console_reporters)
23
+ MiniTest::Unit.runner = runner
24
+ end
25
+
26
+ def self.use_before_test_hook!
27
+ # available since 3.3.0
28
+ MiniTest::Unit::TestCase.send(:include, MiniTestFastFail::BeforeTestHook)
29
+ end
30
+
31
+ def self.use_parallel_length_method!
32
+ # available since 4.2.0
33
+ ::ParallelEach.send(:define_method, :length) do
34
+ @queue.length
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ module MiniTestFastFail
2
+ # Based upon Alexander Kern's minitest-reporters (MIT License)
3
+ # @see https://github.com/CapnKernul/minitest-reporters minitest-reporters
4
+
5
+ module BeforeTestHook
6
+ def self.before_test(instance)
7
+ runner = MiniTest::Unit.runner
8
+
9
+ if runner.respond_to?(:before_test)
10
+ runner.before_test(instance.class, instance.__name__)
11
+ end
12
+ end
13
+
14
+ def before_setup
15
+ BeforeTestHook.before_test(self)
16
+ super
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,167 @@
1
+ module MiniTestFastFail
2
+ # Runner for MiniTest that supports reporters.
3
+ #
4
+ # Based upon Alexander Kern's minitest-reporters (MIT License)
5
+ # @see https://github.com/CapnKernul/minitest-reporters minitest-reporters
6
+ #
7
+ # which is in-turn
8
+ # Based upon Ryan Davis of Seattle.rb's MiniTest (MIT License).
9
+ #
10
+ # @see https://github.com/seattlerb/minitest MiniTest
11
+ class FastFailReporter < Reporter
12
+ TEST_PADDING = 2
13
+ TEST_SIZE = 76
14
+ MARK_SIZE = 3
15
+ INFO_PADDING = 5
16
+
17
+ def initialize(options = {})
18
+ @detailed_skip = options.fetch(:detailed_skip, true)
19
+ end
20
+
21
+ def before_suites(suites, type)
22
+ puts
23
+ puts "# Running #{type}s:"
24
+ puts
25
+ end
26
+
27
+ def before_test(suite, test)
28
+ @test_name = "#{suite}##{test}"
29
+ print "#{@test_name} = " if verbose?
30
+ end
31
+
32
+ def pass(suite, test, test_runner)
33
+ after_test('.')
34
+ end
35
+
36
+ def skip(suite, test, test_runner)
37
+ after_test('S')
38
+ end
39
+
40
+ def failure(suite, test, test_runner)
41
+ after_test('F')
42
+
43
+ puts
44
+ puts suite.name
45
+ print pad_test(naturalize(test))
46
+ print(pad_mark('FAIL'))
47
+ print_time(test)
48
+ puts
49
+ print_info(test_runner.exception)
50
+ puts
51
+ end
52
+
53
+ def error(suite, test, test_runner)
54
+ after_test('E')
55
+
56
+ puts
57
+ puts suite.name
58
+ print pad_test(naturalize(test))
59
+ print(pad_mark('ERROR'))
60
+ print_time(test)
61
+ puts
62
+ print_info(test_runner.exception)
63
+ puts
64
+ end
65
+
66
+ def after_suite(suite)
67
+ end
68
+
69
+ def after_suites(suites, type)
70
+ time = Time.now - runner.suites_start_time
71
+ status_line = "Finished %ss in %.6fs, %.4f tests/s, %.4f assertions/s." %
72
+ [type, time, runner.test_count / time, runner.assertion_count / time]
73
+
74
+ puts
75
+ puts
76
+ puts status_line
77
+
78
+ puts
79
+ print result_line
80
+ end
81
+
82
+ private
83
+
84
+ def suite_result
85
+ case
86
+ when runner.failures > 0; :failure
87
+ when runner.errors > 0; :error
88
+ when runner.skips > 0; :skip
89
+ else :pass
90
+ end
91
+ end
92
+
93
+ def after_test(result)
94
+ time = Time.now - runner.test_start_time
95
+
96
+ print '%.2f s = ' % time if verbose?
97
+ print result
98
+ puts if verbose?
99
+ end
100
+
101
+ def location(exception)
102
+ last_before_assertion = ''
103
+
104
+ exception.backtrace.reverse_each do |s|
105
+ break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
106
+ last_before_assertion = s
107
+ end
108
+
109
+ last_before_assertion.sub(/:in .*$/, '')
110
+ end
111
+
112
+ def message_for(test_runner)
113
+ suite = test_runner.suite
114
+ test = test_runner.test
115
+ e = test_runner.exception
116
+
117
+ case test_runner.result
118
+ when :pass then nil
119
+ when :skip
120
+ if @detailed_skip
121
+ "Skipped:\n#{test}(#{suite}) [#{location(e)}]:\n#{e.message}\n"
122
+ end
123
+ when :failure then "Failure:\n#{test}(#{suite}) [#{location(e)}]:\n#{e.message}\n"
124
+ when :error
125
+ bt = filter_backtrace(test_runner.exception.backtrace).join "\n "
126
+ "Error:\n#{test}(#{suite}):\n#{e.class}: #{e.message}\n #{bt}\n"
127
+ end
128
+ end
129
+
130
+ def result_line
131
+ "%d tests, %d assertions, %d failures, %d errors, %d skips\n\n" %
132
+ [runner.test_count, runner.assertion_count, runner.failures, runner.errors, runner.skips]
133
+ end
134
+
135
+ def print_time(test)
136
+ total_time = Time.now - runner.test_start_time
137
+ print(" (%.2fs)" % total_time)
138
+ end
139
+
140
+ def print_info(e)
141
+ e.message.each_line { |line| puts pad(line, INFO_PADDING) }
142
+
143
+ trace = filter_backtrace(e.backtrace)
144
+ trace.each { |line| puts pad(line, INFO_PADDING) }
145
+ end
146
+
147
+ def pad(str, size)
148
+ ' ' * size + str
149
+ end
150
+
151
+ def pad_mark(str)
152
+ "%#{MARK_SIZE}s" % str
153
+ end
154
+
155
+ def pad_test(str)
156
+ pad("%-#{TEST_SIZE}s" % str, TEST_PADDING)
157
+ end
158
+
159
+ # Natural names for tests (without underscore)
160
+ #
161
+ # Based upon Tim Pease's Turn
162
+ # @see https://github.com/TwP/turn
163
+ def naturalize(name)
164
+ name.gsub("test_", "").gsub(/_/, " ")
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,40 @@
1
+ module MiniTestFastFail
2
+ # Based upon Alexander Kern's minitest-reporters (MIT License)
3
+ # @see https://github.com/CapnKernul/minitest-reporters minitest-reporters
4
+
5
+ class Reporter
6
+ def runner
7
+ MiniTest::Unit.runner
8
+ end
9
+
10
+ def filter_backtrace(backtrace)
11
+ MiniTest.filter_backtrace(backtrace)
12
+ end
13
+
14
+ def output
15
+ runner.output
16
+ end
17
+
18
+ def verbose?
19
+ runner.verbose
20
+ end
21
+
22
+ def print(*args)
23
+ runner.output.print(*args)
24
+ end
25
+
26
+ def puts(*args)
27
+ runner.output.puts(*args)
28
+ end
29
+
30
+ def before_suites(suites, type); end
31
+ def before_suite(suite); end
32
+ def before_test(suite, test); end
33
+ def pass(suite, test, test_runner); end
34
+ def skip(suite, test, test_runner); end
35
+ def failure(suite, test, test_runner); end
36
+ def error(suite, test, test_runner); end
37
+ def after_suite(suite); end
38
+ def after_suites(suites, type); end
39
+ end
40
+ end
@@ -0,0 +1,93 @@
1
+ module MiniTestFastFail
2
+ # Runner for MiniTest that supports reporters.
3
+ #
4
+ # Based upon Alexander Kern's minitest-reporters (MIT License)
5
+ # @see https://github.com/CapnKernul/minitest-reporters minitest-reporters
6
+ #
7
+ # which is in-turn
8
+ # Based upon Ryan Davis of Seattle.rb's MiniTest (MIT License).
9
+ #
10
+ # @see https://github.com/seattlerb/minitest MiniTest
11
+ class ReporterRunner < MiniTest::Unit
12
+ attr_accessor :suites_start_time, :test_start_time, :reporters, :test_results
13
+
14
+ alias_method :suite_start_time, :start_time
15
+
16
+ def initialize
17
+ super
18
+ self.reporters = []
19
+ self.test_results = {}
20
+ end
21
+
22
+ def _run_suites(suites, type)
23
+ self.suites_start_time = Time.now
24
+ count_tests!(suites, type)
25
+ trigger_callback(:before_suites, suites, type)
26
+ super(suites, type)
27
+ ensure
28
+ trigger_callback(:after_suites, suites, type)
29
+ end
30
+
31
+ def _run_suite(suite, type)
32
+ trigger_callback(:before_suite, suite)
33
+ self.start_time = Time.now
34
+ super(suite, type)
35
+ ensure
36
+ trigger_callback(:after_suite, suite)
37
+ end
38
+
39
+ def before_test(suite, test)
40
+ self.test_start_time = Time.now
41
+ trigger_callback(:before_test, suite, test)
42
+ end
43
+
44
+ def record(suite, test, assertions, time, exception)
45
+ self.assertion_count += assertions
46
+
47
+ result = case exception
48
+ when nil then :pass
49
+ when MiniTest::Skip then :skip
50
+ when MiniTest::Assertion then :failure
51
+ else :error
52
+ end
53
+
54
+ test_runner = MiniTestFastFail::TestRunner.new(
55
+ suite,
56
+ test.to_sym,
57
+ assertions,
58
+ time,
59
+ result,
60
+ exception
61
+ )
62
+
63
+ test_results[suite] ||= {}
64
+ test_results[suite][test.to_sym] = test_runner
65
+ trigger_callback(result, suite, test, test_runner)
66
+ end
67
+
68
+ def puts(*args)
69
+ end
70
+
71
+ def print(*args)
72
+ end
73
+
74
+ def status(io = output)
75
+ end
76
+
77
+ private
78
+
79
+ def trigger_callback(callback, *args)
80
+ reporters.each do |reporter|
81
+ reporter.public_send(callback, *args)
82
+ end
83
+ end
84
+
85
+ def count_tests!(suites, type)
86
+ filter = options[:filter] || '/./'
87
+ filter = Regexp.new $1 if filter =~ /\/(.*)\//
88
+ self.test_count = suites.inject(0) do |acc, suite|
89
+ acc + suite.send("#{type}_methods").grep(filter).length
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,3 @@
1
+ module MiniTestFastFail
2
+ TestRunner = Struct.new(:suite, :test, :assertions, :time, :result, :exception)
3
+ end
@@ -0,0 +1,3 @@
1
+ module MiniTestFastFail
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: minitest-fastfail
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chirantan Mitra
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 4.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 4.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Report minitest errors and failures instantly
47
+ email:
48
+ - chirantan.mitra@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - lib/minitest-fastfail/before_test_hook.rb
54
+ - lib/minitest-fastfail/fast_fail_reporter.rb
55
+ - lib/minitest-fastfail/reporter.rb
56
+ - lib/minitest-fastfail/reporter_runner.rb
57
+ - lib/minitest-fastfail/test_runner.rb
58
+ - lib/minitest-fastfail/version.rb
59
+ - lib/minitest-fastfail.rb
60
+ - LICENSE
61
+ - README.md
62
+ - CHANGELOG.md
63
+ homepage:
64
+ licenses: []
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ segments:
76
+ - 0
77
+ hash: 760871107831015869
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ segments:
85
+ - 0
86
+ hash: 760871107831015869
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 1.8.25
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: Show a dot for each passing test. Show full description for each tests that
93
+ fail or have errors.
94
+ test_files: []