journo 0.2.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.
@@ -0,0 +1,22 @@
1
+ coverage
2
+ rdoc
3
+ pkg
4
+ test/tmp
5
+ test/version_tmp
6
+ tmp
7
+ pkg
8
+ *.gem
9
+ *.rbc
10
+ lib/bundler/man
11
+ spec/reports
12
+ .config
13
+ InstalledFiles
14
+ .bundle
15
+
16
+ # YARD artifacts
17
+ .yardoc
18
+ _yardoc
19
+ doc/
20
+
21
+ # Gem-specific
22
+ Gemfile.lock
@@ -0,0 +1,7 @@
1
+ script: 'rake test'
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - ree
6
+ - rbx
7
+ - jruby
@@ -0,0 +1,6 @@
1
+ --readme README.md
2
+ --markup markdown
3
+ --markup-provider maruku
4
+ --default-return ""
5
+ --title "Minitest-reporter Documentation"
6
+ --hide-void-return
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Alexander Kern
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,45 @@
1
+ # journo - reporters for MiniTest [![StillMaintained Status](http://stillmaintained.com/CapnKernul/journo.png)](http://stillmaintained.com/CapnKernul/journo) [![Build Status](http://travis-ci.org/CapnKernul/journo.png)](http://travis-ci.org/CapnKernul/journo) #
2
+
3
+ Allows you to extend MiniTest using reporters rather than monkey-patching.
4
+
5
+ ## Installation ##
6
+
7
+ gem install journo
8
+
9
+ ## Usage ##
10
+
11
+ In your `test_helper.rb` file, add the following lines:
12
+
13
+ require 'journo'
14
+ MiniTest::Unit.runner = Journo::SuiteRunner.new
15
+ MiniTest::Unit.runner.reporters << Journo::Reporters::ProgressReporter.new
16
+
17
+ Now, just run your tests; the reporter you specified will be used and make your
18
+ output look absolutely gorgeous! If you feel the need to write your own
19
+ reporter, just subclass `Journo::Reporter` and override the methods you'd
20
+ like. Take a look at the provided reporters for examples.
21
+
22
+ The following reporters are provided:
23
+
24
+ Journo::Reporters::DefaultReporter # => Identical to the standard MiniTest reporter
25
+ Journo::Reporters::SpecReporter # => Turn-like output that reads like a spec
26
+ Journo::Reporters::ProgressReporter # => Fuubar-like output with a progress bar
27
+
28
+ I really like `ProgressReporter`.
29
+
30
+ ## Note on Patches/Pull Requests ##
31
+
32
+ * Fork the project.
33
+ * Make your feature addition or bug fix.
34
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
35
+ * Commit, but do not mess with the `Rakefile`. 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.
36
+ * Send me a pull request. Bonus points for git flow feature branches.
37
+
38
+ ## Resources ##
39
+
40
+ * [GitHub Repository](https://github.com/CapnKernul/journo)
41
+ * [Documentation](http://rubydoc.info/github/CapnKernul/journo)
42
+
43
+ ## License ##
44
+
45
+ Journo is licensed under the MIT License. See `LICENSE` for details.
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ task :default => :test
5
+
6
+ require 'rake/testtask'
7
+ Rake::TestTask.new do |t|
8
+ t.ruby_opts += ['-rubygems']
9
+ t.libs << 'test'
10
+ t.pattern = 'test/**/*_test.rb'
11
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'journo/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'journo'
7
+ s.version = Journo::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Alexander Kern']
10
+ s.email = ['alex@kernul.com']
11
+ s.homepage = 'https://github.com/CapnKernul/journo'
12
+ s.summary = %q{Reporters for MiniTest}
13
+ s.description = %q{Allows you to extend MiniTest using reporters rather than monkey-patching}
14
+
15
+ s.rubyforge_project = 'journo'
16
+
17
+ s.add_dependency 'minitest', '~> 2.0'
18
+ s.add_dependency 'ansi'
19
+ s.add_dependency 'ruby-progressbar'
20
+
21
+ s.add_development_dependency 'mocha'
22
+ s.add_development_dependency 'maruku'
23
+ s.add_development_dependency 'test_declarative'
24
+
25
+ s.files = `git ls-files`.split("\n")
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
+ s.require_paths = ['lib']
29
+ end
@@ -0,0 +1,15 @@
1
+ require 'minitest/unit'
2
+
3
+ module Journo
4
+ require 'journo/version'
5
+
6
+ autoload :Reporter, 'journo/reporter'
7
+ autoload :SuiteRunner, 'journo/suite_runner'
8
+ autoload :TestRunner, 'journo/test_runner'
9
+
10
+ module Reporters
11
+ autoload :DefaultReporter, 'journo/reporters/default_reporter'
12
+ autoload :SpecReporter, 'journo/reporters/spec_reporter'
13
+ autoload :ProgressReporter, 'journo/reporters/progress_reporter'
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ module Journo
2
+ class Reporter
3
+ VERSION = '0.1.0'
4
+
5
+ def runner
6
+ MiniTest::Unit.runner
7
+ end
8
+
9
+ def output
10
+ runner.output
11
+ end
12
+
13
+ def verbose?
14
+ runner.verbose
15
+ end
16
+
17
+ def print(*args)
18
+ runner.output.print(*args)
19
+ end
20
+
21
+ def puts(*args)
22
+ runner.output.puts(*args)
23
+ end
24
+
25
+ def before_suites(suites, type); end
26
+ def after_suites(suites, type); end
27
+ def before_suite(suite); end
28
+ def after_suite(suite); end
29
+ def before_test(suite, test); end
30
+ def pass(suite, test, test_runner); end
31
+ def skip(suite, test, test_runner); end
32
+ def failure(suite, test, test_runner); end
33
+ def error(suite, test, test_runner); end
34
+ end
35
+ end
@@ -0,0 +1,103 @@
1
+ require 'ansi'
2
+
3
+ module Journo
4
+ module Reporters
5
+ # A reporter identical to the standard MiniTest reporter.
6
+ #
7
+ # Based upon Ryan Davis of Seattle.rb's MiniTest (MIT License).
8
+ #
9
+ # @see https://github.com/seattlerb/minitest MiniTest
10
+ class DefaultReporter < Journo::Reporter
11
+ def before_suites(suites, type)
12
+ puts
13
+ puts "# Running #{type}s:"
14
+ puts
15
+ end
16
+
17
+ def before_test(suite, test)
18
+ print "#{suite}##{method} = " if verbose?
19
+ end
20
+
21
+ def pass(suite, test, test_runner)
22
+ after_test('.')
23
+ end
24
+
25
+ def skip(suite, test, test_runner)
26
+ after_test('S')
27
+ end
28
+
29
+ def failure(suite, test, test_runner)
30
+ after_test('F')
31
+ end
32
+
33
+ def error(suite, test, test_runner)
34
+ after_test('E')
35
+ end
36
+
37
+ def after_suites(suites, type)
38
+ time = Time.now - runner.start_time
39
+
40
+ puts
41
+ puts
42
+ puts "Finished #{type}s in %.6fs, %.4f tests/s, %.4f assertions/s." %
43
+ [time, runner.test_count / time, runner.assertion_count / time]
44
+
45
+ i = 0
46
+ runner.report.each do |suite, tests|
47
+ tests.each do |test, test_runner|
48
+ message = message_for(test_runner)
49
+ if message
50
+ i += 1
51
+ puts "\n%3d) %s" % [i, message]
52
+ end
53
+ end
54
+ end
55
+
56
+ puts
57
+
58
+ puts status
59
+ end
60
+
61
+ private
62
+
63
+ def after_test(result)
64
+ time = Time.now - runner.test_start_time
65
+
66
+ print '%.2f s = ' % time if verbose?
67
+ print result
68
+ puts if verbose?
69
+ end
70
+
71
+ def location(exception)
72
+ last_before_assertion = ''
73
+
74
+ exception.backtrace.reverse_each do |s|
75
+ break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
76
+ last_before_assertion = s
77
+ end
78
+
79
+ last_before_assertion.sub(/:in .*$/, '')
80
+ end
81
+
82
+ def message_for(test_runner)
83
+ suite = test_runner.suite
84
+ test = test_runner.test
85
+ e = test_runner.exception
86
+
87
+ case test_runner.result
88
+ when :pass then nil
89
+ when :skip then "Skipped:\n#{test}(#{suite}) [#{location(e)}]:\n#{e.message}\n"
90
+ when :failure then "Failure:\n#{test}(#{suite}) [#{location(e)}]:\n#{e.message}\n"
91
+ when :error
92
+ bt = MiniTest::filter_backtrace(test_runner.exception.backtrace).join "\n "
93
+ "Error:\n#{test}(#{suite}):\n#{e.class}: #{e.message}\n #{bt}\n"
94
+ end
95
+ end
96
+
97
+ def status
98
+ '%d tests, %d assertions, %d failures, %d errors, %d skips' %
99
+ [runner.test_count, runner.assertion_count, runner.failures, runner.errors, runner.skips]
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,107 @@
1
+ require 'ansi'
2
+ require 'progressbar'
3
+
4
+ module Journo
5
+ module Reporters
6
+ # Fuubar-like reporter with a progress bar.
7
+ #
8
+ # Based upon Jeff Kreefmeijer's Fuubar (MIT License) and paydro's
9
+ # monkey-patch.
10
+ #
11
+ # @see https://github.com/jeffkreeftmeijer/fuubar Fuubar
12
+ # @see https://gist.github.com/356945 paydro's monkey-patch
13
+ class ProgressReporter < Journo::Reporter
14
+ include ANSI::Code
15
+
16
+ INFO_PADDING = 2
17
+
18
+ def before_suites(suites, type)
19
+ puts 'Started'
20
+ puts
21
+
22
+ @color = GREEN
23
+ @finished_count = 0
24
+ @progress = ProgressBar.new("0/#{runner.test_count}", runner.test_count, runner.output)
25
+ @progress.bar_mark = '='
26
+ end
27
+
28
+ def increment
29
+ with_color do
30
+ @finished_count += 1
31
+ @progress.instance_variable_set('@title', "#{@finished_count}/#{runner.test_count}")
32
+ @progress.inc
33
+ end
34
+ end
35
+
36
+ def pass(suite, test, test_runner)
37
+ increment
38
+ end
39
+
40
+ def skip(suite, test, test_runner)
41
+ @color = YELLOW unless @color == RED
42
+ print(yellow { 'SKIP' })
43
+ print_test_with_time(suite, test)
44
+ puts
45
+ puts
46
+ increment
47
+ end
48
+
49
+ def failure(suite, test, test_runner)
50
+ @color = RED
51
+ print(red { 'FAIL' })
52
+ print_test_with_time(suite, test)
53
+ puts
54
+ print_info(test_runner.exception)
55
+ puts
56
+ increment
57
+ end
58
+
59
+ def error(suite, test, test_runner)
60
+ @color = RED
61
+ print(red { 'ERROR' })
62
+ print_test_with_time(suite, test)
63
+ puts
64
+ print_info(test_runner.exception)
65
+ puts
66
+ increment
67
+ end
68
+
69
+ def after_suites(suites, type)
70
+ with_color { @progress.finish }
71
+
72
+ total_time = Time.now - runner.start_time
73
+
74
+ puts
75
+ puts('Finished in %.5fs' % total_time)
76
+ print('%d tests, %d assertions, ' % [runner.test_count, runner.assertion_count])
77
+ print(red { '%d failures, %d errors, ' } % [runner.failures, runner.errors])
78
+ print(yellow { '%d skips' } % runner.skips)
79
+ puts
80
+ end
81
+
82
+ private
83
+
84
+ def print_test_with_time(suite, test)
85
+ total_time = Time.now - runner.test_start_time
86
+ print(" #{suite}##{test} (%.2fs)#{clr}" % total_time)
87
+ end
88
+
89
+ def print_info(e)
90
+ e.message.each_line { |line| puts pad(line) }
91
+
92
+ trace = MiniTest.filter_backtrace(e.backtrace)
93
+ trace.each { |line| puts pad(line) }
94
+ end
95
+
96
+ def pad(str)
97
+ ' ' * INFO_PADDING + str
98
+ end
99
+
100
+ def with_color
101
+ print @color
102
+ yield
103
+ print CLEAR
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,92 @@
1
+ require 'ansi'
2
+
3
+ module Journo
4
+ module Reporters
5
+ # Turn-like reporter that reads like a spec.
6
+ #
7
+ # Based upon TwP's turn (MIT License) and paydro's monkey-patch.
8
+ #
9
+ # @see https://github.com/TwP/turn turn
10
+ # @see https://gist.github.com/356945 paydro's monkey-patch
11
+ class SpecReporter < Journo::Reporter
12
+ include ANSI::Code
13
+
14
+ TEST_PADDING = 2
15
+ INFO_PADDING = 8
16
+ MARK_SIZE = 5
17
+
18
+ def before_suites(suites, type)
19
+ puts 'Started'
20
+ puts
21
+ end
22
+
23
+ def after_suites(suites, type)
24
+ total_time = Time.now - runner.start_time
25
+
26
+ puts('Finished in %.5fs' % total_time)
27
+ print('%d tests, %d assertions, ' % [runner.test_count, runner.assertion_count])
28
+ print(red { '%d failures, %d errors, ' } % [runner.failures, runner.errors])
29
+ print(yellow { '%d skips' } % runner.skips)
30
+ puts
31
+ end
32
+
33
+ def before_suite(suite)
34
+ puts suite
35
+ end
36
+
37
+ def after_suite(suite)
38
+ puts
39
+ end
40
+
41
+ def pass(suite, test, test_runner)
42
+ print(green { pad_mark('PASS') })
43
+ print_test_with_time(test)
44
+ puts
45
+ end
46
+
47
+ def skip(suite, test, test_runner)
48
+ print(yellow { pad_mark('SKIP') })
49
+ print_test_with_time(test)
50
+ puts
51
+ end
52
+
53
+ def failure(suite, test, test_runner)
54
+ print(red { pad_mark('FAIL') })
55
+ print_test_with_time(test)
56
+ puts
57
+ print_info(test_runner.exception)
58
+ puts
59
+ end
60
+
61
+ def error(suite, test, test_runner)
62
+ print(red { pad_mark('ERROR') })
63
+ print_test_with_time(test)
64
+ puts
65
+ print_info(test_runner.exception)
66
+ puts
67
+ end
68
+
69
+ private
70
+
71
+ def print_test_with_time(test)
72
+ total_time = Time.now - runner.test_start_time
73
+ print(" #{test} (%.2fs)" % total_time)
74
+ end
75
+
76
+ def print_info(e)
77
+ e.message.each_line { |line| puts pad(line, INFO_PADDING) }
78
+
79
+ trace = MiniTest.filter_backtrace(e.backtrace)
80
+ trace.each { |line| puts pad(line, INFO_PADDING) }
81
+ end
82
+
83
+ def pad(str, size)
84
+ ' ' * size + str
85
+ end
86
+
87
+ def pad_mark(str)
88
+ pad("%#{MARK_SIZE}s" % str, TEST_PADDING)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,110 @@
1
+ module Journo
2
+ # Runner for MiniTest suites.
3
+ #
4
+ # This is a heavily refactored version of the built-in MiniTest runner. It's
5
+ # about the same speed, from what I can tell, but is significantly easier to
6
+ # extend.
7
+ #
8
+ # Based upon Ryan Davis of Seattle.rb's MiniTest (MIT License).
9
+ #
10
+ # @see https://github.com/seattlerb/minitest MiniTest
11
+ class SuiteRunner < MiniTest::Unit
12
+ attr_accessor :suite_start_time, :test_start_time, :reporters
13
+
14
+ def initialize
15
+ self.report = {}
16
+ self.errors = 0
17
+ self.failures = 0
18
+ self.skips = 0
19
+ self.test_count = 0
20
+ self.assertion_count = 0
21
+ self.verbose = false
22
+ self.reporters = []
23
+ end
24
+
25
+ def _run_anything(type)
26
+ self.start_time = Time.now
27
+
28
+ suites = suites_of_type(type)
29
+ tests = suites.inject({}) do |acc, suite|
30
+ acc[suite] = filtered_tests(suite, type)
31
+ acc
32
+ end
33
+
34
+ self.test_count = tests.inject(0) { |acc, suite| acc + suite[1].length }
35
+
36
+ if test_count > 0
37
+ trigger(:before_suites, suites, type)
38
+
39
+ fix_sync do
40
+ suites.each { |suite| _run_suite(suite, tests[suite]) }
41
+ end
42
+
43
+ trigger(:after_suites, suites, type)
44
+ end
45
+ end
46
+
47
+ def _run_suite(suite, tests)
48
+ unless tests.empty?
49
+ begin
50
+ self.suite_start_time = Time.now
51
+
52
+ trigger(:before_suite, suite)
53
+ suite.startup if suite.respond_to?(:startup)
54
+
55
+ tests.each { |test| _run_test(suite, test) }
56
+ ensure
57
+ suite.shutdown if suite.respond_to?(:shutdown)
58
+ trigger(:after_suite, suite)
59
+ end
60
+ end
61
+ end
62
+
63
+ def _run_test(suite, test)
64
+ self.test_start_time = Time.now
65
+ trigger(:before_test, suite, test)
66
+
67
+ test_runner = TestRunner.new(suite, test)
68
+ test_runner.run
69
+ add_test_result(suite, test, test_runner)
70
+
71
+ trigger(test_runner.result, suite, test, test_runner)
72
+ end
73
+
74
+ def trigger(callback, *args)
75
+ reporters.each { |reporter| reporter.send(callback, *args) }
76
+ end
77
+
78
+ private
79
+
80
+ def filtered_tests(suite, type)
81
+ filter = options[:filter] || '/./'
82
+ filter = Regexp.new($1) if filter =~ /\/(.*)\//
83
+ suite.send("#{type}_methods").grep(filter)
84
+ end
85
+
86
+ def suites_of_type(type)
87
+ TestCase.send("#{type}_suites")
88
+ end
89
+
90
+ def add_test_result(suite, test, test_runner)
91
+ self.report[suite] ||= {}
92
+ self.report[suite][test.to_sym] = test_runner
93
+
94
+ self.assertion_count += test_runner.assertions
95
+
96
+ case test_runner.result
97
+ when :skip then self.skips += 1
98
+ when :failure then self.failures += 1
99
+ when :error then self.errors += 1
100
+ end
101
+ end
102
+
103
+ def fix_sync
104
+ sync = output.respond_to?(:'sync=') # stupid emacs
105
+ old_sync, output.sync = output.sync, true if sync
106
+ yield
107
+ output.sync = old_sync if sync
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,39 @@
1
+ module Journo
2
+ # Runner for individual MiniTest tests.
3
+ #
4
+ # You *should not* create instances of this class directly. Instances of
5
+ # {SuiteRunner} will create these and send them to the reporters.
6
+ #
7
+ # Based upon Ryan Davis of Seattle.rb's MiniTest (MIT License).
8
+ #
9
+ # @see https://github.com/seattlerb/minitest MiniTest
10
+ class TestRunner
11
+ attr_reader :suite, :test, :assertions, :result, :exception
12
+
13
+ def initialize(suite, test)
14
+ @suite = suite
15
+ @test = test
16
+ @assertions = 0
17
+ end
18
+
19
+ def run
20
+ suite_instance = suite.new(test)
21
+ @result, @exception = fix_result(suite_instance.run(self))
22
+ @assertions = suite_instance._assertions
23
+ end
24
+
25
+ def puke(suite, test, exception)
26
+ case exception
27
+ when MiniTest::Skip then [:skip, exception]
28
+ when MiniTest::Assertion then [:failure, exception]
29
+ else [:error, exception]
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def fix_result(result)
36
+ result == '.' ? [:pass, nil] : result
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Journo
2
+ VERSION = '0.2.0'
3
+ end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ module JournoTest
4
+ class ReporterTest < TestCase
5
+ def setup
6
+ @reporter = Journo::Reporter.new
7
+ end
8
+
9
+ test 'callbacks' do
10
+ [
11
+ :before_suites, :after_suite, :before_suite, :after_suite, :before_test,
12
+ :pass, :skip, :failure, :error
13
+ ].each { |method| assert_respond_to @reporter, method }
14
+ end
15
+
16
+ test '#runner' do
17
+ assert_kind_of MiniTest::Unit, @reporter.runner
18
+ end
19
+
20
+ test '#output' do
21
+ assert_equal MiniTest::Unit.output, @reporter.output
22
+ end
23
+
24
+ test '#verbose?' do
25
+ refute @reporter.verbose?
26
+
27
+ begin
28
+ @reporter.runner.verbose = true
29
+ assert @reporter.verbose?
30
+ ensure
31
+ @reporter.runner.verbose = false
32
+ end
33
+ end
34
+
35
+ test '#print' do
36
+ @reporter.output.expects(:print).with('foo')
37
+ @reporter.print('foo')
38
+ end
39
+
40
+ test '#puts' do
41
+ @reporter.output.expects(:puts).with('foo')
42
+ @reporter.puts('foo')
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,160 @@
1
+ require 'test_helper'
2
+
3
+ module JournoTest
4
+ class SuiteRunnerTest < TestCase
5
+ def setup
6
+ @runner = Journo::SuiteRunner.new
7
+ @reporter = add_reporter
8
+ end
9
+
10
+ test '#report' do
11
+ assert_equal({}, @runner.report)
12
+ end
13
+
14
+ test '#reporters' do
15
+ assert_equal [@reporter], @runner.reporters
16
+
17
+ reporter2 = add_reporter
18
+ assert_equal [@reporter, reporter2], @runner.reporters
19
+ end
20
+
21
+ test '#_run_anything with no suites' do
22
+ stub_suites([])
23
+
24
+ @reporter.expects(:before_suites).never
25
+ @reporter.expects(:after_suites).never
26
+
27
+ @runner._run_anything(:test)
28
+
29
+ assert_equal 0, @runner.test_count
30
+ assert_equal 0, @runner.assertion_count
31
+ assert_instance_of Time, @runner.start_time
32
+ assert_equal({}, @runner.report)
33
+ end
34
+
35
+ test '#_run_anything with suites' do
36
+ suites = [Fixtures::PassTestFixture, Fixtures::SkipTestFixture]
37
+ stub_suites(suites)
38
+
39
+ @reporter.expects(:before_suites).with(suites, :test)
40
+ @reporter.expects(:after_suites).with(suites, :test)
41
+
42
+ @runner._run_anything(:test)
43
+
44
+ assert_equal 3, @runner.test_count
45
+ assert_equal 3, @runner.assertion_count
46
+ assert_instance_of Time, @runner.start_time
47
+ assert_equal :pass, @runner.report[Fixtures::PassTestFixture][:test_pass].result
48
+ assert_equal :pass, @runner.report[Fixtures::PassTestFixture][:test_foo].result
49
+ assert_equal :skip, @runner.report[Fixtures::SkipTestFixture][:test_skip].result
50
+ end
51
+
52
+ test '#_run_anything with a filter' do
53
+ @runner.options[:filter] = '/foo/'
54
+ stub_suites([Fixtures::PassTestFixture])
55
+
56
+ @runner._run_anything(:test)
57
+ assert_equal 2, @runner.assertion_count
58
+ end
59
+
60
+ test '#_run_suite without tests' do
61
+ @reporter.expects(:before_suite).never
62
+ @reporter.expects(:after_suite).never
63
+
64
+ @runner._run_suite(Fixtures::EmptyTestFixture, [])
65
+ end
66
+
67
+ test '#_run_suite with tests' do
68
+ @reporter.expects(:before_suite).with(Fixtures::PassTestFixture)
69
+ @reporter.expects(:after_suite).with(Fixtures::PassTestFixture)
70
+
71
+ @runner._run_suite(Fixtures::PassTestFixture, [:test_pass, :test_foo])
72
+
73
+ assert_equal 3, @runner.assertion_count
74
+ assert_instance_of Time, @runner.suite_start_time
75
+ end
76
+
77
+ test '#_run_suite with a suite .startup and .shutdown' do
78
+ suite = Fixtures::SuiteCallbackTestFixture
79
+ suite.expects(:startup)
80
+ suite.expects(:shutdown)
81
+ @runner._run_suite(suite, [:test_foo])
82
+ end
83
+
84
+ test '#_run_test with a passing test' do
85
+ suite = Fixtures::PassTestFixture
86
+ test = :test_pass
87
+
88
+ @reporter.expects(:before_test).with(suite, test)
89
+ @reporter.expects(:pass).with(suite, test, instance_of(Journo::TestRunner))
90
+
91
+ @runner._run_test(suite, test)
92
+
93
+ assert_equal 1, @runner.assertion_count
94
+ assert_instance_of Time, @runner.test_start_time
95
+ assert_equal :pass, @runner.report[suite][test].result
96
+ end
97
+
98
+ test '#_run_test with a skipped test' do
99
+ suite = Fixtures::SkipTestFixture
100
+ test = :test_skip
101
+
102
+ @reporter.expects(:before_test).with(suite, test)
103
+ @reporter.expects(:skip).with(suite, test, instance_of(Journo::TestRunner))
104
+
105
+ @runner._run_test(suite, test)
106
+
107
+ assert_equal 0, @runner.assertion_count
108
+ assert_instance_of Time, @runner.test_start_time
109
+ assert_equal :skip, @runner.report[suite][test].result
110
+ end
111
+
112
+ test '#_run_test with a failing test' do
113
+ suite = Fixtures::FailureTestFixture
114
+ test = :test_failure
115
+
116
+ @reporter.expects(:before_test).with(suite, test)
117
+ @reporter.expects(:failure).with(suite, test, instance_of(Journo::TestRunner))
118
+
119
+ @runner._run_test(suite, test)
120
+
121
+ assert_equal 0, @runner.assertion_count
122
+ assert_instance_of Time, @runner.test_start_time
123
+ assert_equal :failure, @runner.report[suite][test].result
124
+ end
125
+
126
+ test '#_run_test with an error test' do
127
+ suite = Fixtures::ErrorTestFixture
128
+ test = :test_error
129
+
130
+ @reporter.expects(:before_test).with(suite, test)
131
+ @reporter.expects(:error).with(suite, test, instance_of(Journo::TestRunner))
132
+
133
+ @runner._run_test(suite, test)
134
+
135
+ assert_equal 0, @runner.assertion_count
136
+ assert_instance_of Time, @runner.test_start_time
137
+ assert_equal :error, @runner.report[suite][test].result
138
+ end
139
+
140
+ test '#trigger' do
141
+ reporter2 = add_reporter
142
+ @reporter.expects(:before_suite).with(Fixtures::PassTestFixture)
143
+ reporter2.expects(:before_suite).with(Fixtures::PassTestFixture)
144
+
145
+ @runner.trigger(:before_suite, Fixtures::PassTestFixture)
146
+ end
147
+
148
+ private
149
+
150
+ def add_reporter
151
+ reporter = Journo::Reporter.new
152
+ @runner.reporters << reporter
153
+ reporter
154
+ end
155
+
156
+ def stub_suites(suites)
157
+ MiniTest::Unit::TestCase.stubs(:test_suites).returns(suites)
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,91 @@
1
+ require 'test_helper'
2
+
3
+ module JournoTest
4
+ class TestRunnerTest < TestCase
5
+ def setup
6
+ @suite = stub
7
+ @test = :test_foo
8
+ @runner = Journo::TestRunner.new(@suite, @test)
9
+ end
10
+
11
+ test '#suite' do
12
+ assert_equal @suite, @runner.suite
13
+ end
14
+
15
+ test '#test' do
16
+ assert_equal @test, @runner.test
17
+ end
18
+
19
+ test '#run with a passing test' do
20
+ suite_instance = stub(:_assertions => 3)
21
+ suite_instance.expects(:run).with(@runner).returns('.')
22
+ @suite.stubs(:new).with(@test).returns(suite_instance)
23
+
24
+ @runner.run
25
+
26
+ assert_equal :pass, @runner.result
27
+ assert_nil @runner.exception
28
+ assert_equal 3, @runner.assertions
29
+ end
30
+
31
+ test '#run with an skipped test' do
32
+ error = stub
33
+ suite_instance = stub(:_assertions => 3)
34
+ suite_instance.expects(:run).with(@runner).returns([:skip, error])
35
+ @suite.stubs(:new).with(@test).returns(suite_instance)
36
+
37
+ @runner.run
38
+
39
+ assert_equal :skip, @runner.result
40
+ assert_equal error, @runner.exception
41
+ assert_equal 3, @runner.assertions
42
+ end
43
+
44
+ test '#run with a failing test' do
45
+ error = stub
46
+ suite_instance = stub(:_assertions => 3)
47
+ suite_instance.expects(:run).with(@runner).returns([:failure, error])
48
+ @suite.stubs(:new).with(@test).returns(suite_instance)
49
+
50
+ @runner.run
51
+
52
+ assert_equal :failure, @runner.result
53
+ assert_equal error, @runner.exception
54
+ assert_equal 3, @runner.assertions
55
+ end
56
+
57
+ test '#run with an errored test' do
58
+ error = stub
59
+ suite_instance = stub(:_assertions => 3)
60
+ suite_instance.expects(:run).with(@runner).returns([:error, error])
61
+ @suite.stubs(:new).with(@test).returns(suite_instance)
62
+
63
+ @runner.run
64
+
65
+ assert_equal :error, @runner.result
66
+ assert_equal error, @runner.exception
67
+ assert_equal 3, @runner.assertions
68
+ end
69
+
70
+ test '#puke with a skip' do
71
+ skip = MiniTest::Skip.new
72
+ result = @runner.puke(@suite, @test, skip)
73
+
74
+ assert_equal [:skip, skip], result
75
+ end
76
+
77
+ test '#puke with a failure' do
78
+ failure = MiniTest::Assertion.new
79
+ result = @runner.puke(@suite, @test, failure)
80
+
81
+ assert_equal [:failure, failure], result
82
+ end
83
+
84
+ test '#puke with an error' do
85
+ error = RuntimeError.new
86
+ result = @runner.puke(@suite, @test, error)
87
+
88
+ assert_equal [:error, error], result
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,5 @@
1
+ module JournoTest
2
+ module Fixtures
3
+ class EmptyTestFixture < TestCaseFixture; end
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ module JournoTest
2
+ module Fixtures
3
+ class ErrorTestFixture < TestCaseFixture
4
+ def test_error
5
+ raise RuntimeError.new
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module JournoTest
2
+ module Fixtures
3
+ class FailureTestFixture < TestCaseFixture
4
+ def test_failure
5
+ flunk
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module JournoTest
2
+ module Fixtures
3
+ class PassTestFixture < TestCaseFixture
4
+ def test_pass
5
+ assert true
6
+ end
7
+
8
+ def test_foo
9
+ assert true
10
+ assert true
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module JournoTest
2
+ module Fixtures
3
+ class SkipTestFixture < TestCaseFixture
4
+ def test_skip
5
+ skip
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module JournoTest
2
+ module Fixtures
3
+ class SuiteCallbackTestFixture < TestCaseFixture
4
+ def self.startup; end
5
+ def self.shutdown; end
6
+ def test_foo; end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,38 @@
1
+ module JournoTest
2
+ module Fixtures
3
+ class TestCaseFixture
4
+ attr_writer :_assertions
5
+
6
+ def self.test_methods
7
+ public_instance_methods(true).grep(/^test/)
8
+ end
9
+
10
+ def initialize(test)
11
+ @test = test
12
+ end
13
+
14
+ def run(runner)
15
+ send(@test)
16
+ '.'
17
+ rescue MiniTest::Assertion, RuntimeError => e
18
+ runner.puke(self, @test, e)
19
+ end
20
+
21
+ def skip
22
+ raise MiniTest::Skip.new
23
+ end
24
+
25
+ def flunk
26
+ raise MiniTest::Assertion.new
27
+ end
28
+
29
+ def assert(value)
30
+ self._assertions += 1
31
+ end
32
+
33
+ def _assertions
34
+ @_assertions ||= 0
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,4 @@
1
+ module JournoTest
2
+ class TestCase < MiniTest::Unit::TestCase
3
+ end
4
+ end
@@ -0,0 +1,33 @@
1
+ require 'bundler/setup'
2
+ require 'minitest/autorun'
3
+ require 'mocha'
4
+ require 'test_declarative'
5
+ require 'journo'
6
+
7
+ module JournoTest
8
+ require File.expand_path('../support/test_case', __FILE__)
9
+
10
+ module Fixtures
11
+ require File.expand_path('../support/fixtures/test_case_fixture', __FILE__)
12
+ require File.expand_path('../support/fixtures/empty_test_fixture', __FILE__)
13
+ require File.expand_path('../support/fixtures/error_test_fixture', __FILE__)
14
+ require File.expand_path('../support/fixtures/failure_test_fixture', __FILE__)
15
+ require File.expand_path('../support/fixtures/pass_test_fixture', __FILE__)
16
+ require File.expand_path('../support/fixtures/skip_test_fixture', __FILE__)
17
+ require File.expand_path('../support/fixtures/suite_callback_test_fixture', __FILE__)
18
+ end
19
+ end
20
+
21
+ MiniTest::Unit.runner = Journo::SuiteRunner.new
22
+
23
+ # Testing the built-in reporters using automated unit testing would be extremely
24
+ # brittle. Consequently, there are no unit tests for them. Instead, uncomment
25
+ # the reporter that you'd like to test and run the full test suite. Make sure to
26
+ # try them with skipped, failing, and error tests as well!
27
+ #
28
+ # Personally, I like the progress reporter. Make sure you don't change that line
29
+ # when you commit.
30
+ #
31
+ # MiniTest::Unit.runner.reporters << Journo::Reporters::DefaultReporter.new
32
+ # MiniTest::Unit.runner.reporters << Journo::Reporters::SpecReporter.new
33
+ MiniTest::Unit.runner.reporters << Journo::Reporters::ProgressReporter.new
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: journo
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.2.0
6
+ platform: ruby
7
+ authors:
8
+ - Alexander Kern
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-27 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: minitest
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: "2.0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: ansi
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: ruby-progressbar
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: mocha
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: maruku
62
+ prerelease: false
63
+ requirement: &id005 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ type: :development
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: test_declarative
73
+ prerelease: false
74
+ requirement: &id006 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ type: :development
81
+ version_requirements: *id006
82
+ description: Allows you to extend MiniTest using reporters rather than monkey-patching
83
+ email:
84
+ - alex@kernul.com
85
+ executables: []
86
+
87
+ extensions: []
88
+
89
+ extra_rdoc_files: []
90
+
91
+ files:
92
+ - .gitignore
93
+ - .travis.yml
94
+ - .yardopts
95
+ - Gemfile
96
+ - LICENSE
97
+ - README.md
98
+ - Rakefile
99
+ - journo.gemspec
100
+ - lib/journo.rb
101
+ - lib/journo/reporter.rb
102
+ - lib/journo/reporters/default_reporter.rb
103
+ - lib/journo/reporters/progress_reporter.rb
104
+ - lib/journo/reporters/spec_reporter.rb
105
+ - lib/journo/suite_runner.rb
106
+ - lib/journo/test_runner.rb
107
+ - lib/journo/version.rb
108
+ - test/journo/reporter_test.rb
109
+ - test/journo/suite_runner_test.rb
110
+ - test/journo/test_runner_test.rb
111
+ - test/support/fixtures/empty_test_fixture.rb
112
+ - test/support/fixtures/error_test_fixture.rb
113
+ - test/support/fixtures/failure_test_fixture.rb
114
+ - test/support/fixtures/pass_test_fixture.rb
115
+ - test/support/fixtures/skip_test_fixture.rb
116
+ - test/support/fixtures/suite_callback_test_fixture.rb
117
+ - test/support/fixtures/test_case_fixture.rb
118
+ - test/support/test_case.rb
119
+ - test/test_helper.rb
120
+ has_rdoc: true
121
+ homepage: https://github.com/CapnKernul/journo
122
+ licenses: []
123
+
124
+ post_install_message:
125
+ rdoc_options: []
126
+
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: "0"
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: "0"
141
+ requirements: []
142
+
143
+ rubyforge_project: journo
144
+ rubygems_version: 1.6.2
145
+ signing_key:
146
+ specification_version: 3
147
+ summary: Reporters for MiniTest
148
+ test_files:
149
+ - test/journo/reporter_test.rb
150
+ - test/journo/suite_runner_test.rb
151
+ - test/journo/test_runner_test.rb
152
+ - test/support/fixtures/empty_test_fixture.rb
153
+ - test/support/fixtures/error_test_fixture.rb
154
+ - test/support/fixtures/failure_test_fixture.rb
155
+ - test/support/fixtures/pass_test_fixture.rb
156
+ - test/support/fixtures/skip_test_fixture.rb
157
+ - test/support/fixtures/suite_callback_test_fixture.rb
158
+ - test/support/fixtures/test_case_fixture.rb
159
+ - test/support/test_case.rb
160
+ - test/test_helper.rb