journo 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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