minitest-fastfail 0.1.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.
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: []