turn 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.8.0 / 2010-06-02
2
+ * Mintest support
3
+ * Two new reporters
4
+
5
+ == 0.7.1 / 2009-12-25
6
+ * Copied String#tab from Facets.
7
+ * Facets is no longer needed as direct dependency.
8
+
1
9
  == 0.7.0 / 2009-10-13
2
10
  * Fix typo and potential bug.
3
11
  * Running ruby with /usr/bin/env for portability
data/README.txt CHANGED
@@ -10,7 +10,7 @@ all the tests finish before you can see what the exact failure was. TURN
10
10
  displays each test on a separate line with failures being displayed
11
11
  immediately instead of at the end of the tests.
12
12
 
13
- If you have the 'facets' gem installed, then TURN output will be displayed in
13
+ If you have the 'ansi' gem installed, then TURN output will be displayed in
14
14
  wonderful technicolor (but only if your terminal supports ANSI color codes).
15
15
  Well, the only colors are green and red, but that is still color.
16
16
 
@@ -40,12 +40,8 @@ application.
40
40
 
41
41
  == SYNOPSIS:
42
42
 
43
- If you have the 'facets' gem installed, then TURN output will be displayed in
44
- wonderful technicolor (but only if your terminal supports ANSI color codes).
45
- Well, the only colors are green and red, but that is still color.
46
-
47
- Note that the 'facets' gem is also required if you wish to use the
48
- progressbar output mode.
43
+ Turn can be using from the command-line or via require. The command-line tool
44
+ offers additional options for how one runs tests.
49
45
 
50
46
  === Command Line
51
47
 
@@ -87,7 +83,7 @@ scipt. Now your Rails tests will use TURN formatting.
87
83
 
88
84
  == REQUIREMENTS:
89
85
 
90
- * facets 2.0+ (for colorized output and progressbar output mode)
86
+ * ansi 1.1+ (for colorized output and progressbar output mode)
91
87
 
92
88
  == INSTALL:
93
89
 
data/Rakefile CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  begin
3
2
  require 'bones'
4
3
  rescue LoadError
@@ -13,7 +12,7 @@ Bones {
13
12
  authors 'Tim Pease'
14
13
  email 'tim.pease@gmail.com'
15
14
  url 'http://gemcutter.org/gems/turn'
16
- version File.read('.meta/version').strip
15
+ version File.read('Version.txt').strip
17
16
  ignore_file '.gitignore'
18
17
  rubyforge.name 'codeforpeople'
19
18
 
@@ -21,11 +20,21 @@ Bones {
21
20
  rdoc.exclude << '^lib'
22
21
 
23
22
  use_gmail
24
- enable_sudo
25
23
 
26
24
  depend_on 'ansi'
27
- depend_on 'facets'
28
25
  depend_on 'bones-git', :development => true
29
26
  }
30
27
 
28
+ # Might be useful one day, so we'll leave it here.
29
+ #
30
+ # Rake::TaskManager.class_eval do
31
+ # def remove_task(task_name)
32
+ # @tasks.delete(task_name.to_s)
33
+ # end
34
+ # end
35
+ #
36
+ # def remove_task(task_name)
37
+ # Rake.application.remove_task(task_name)
38
+ # end
39
+
31
40
  # EOF
data/Release.txt CHANGED
@@ -1,50 +1,33 @@
1
- = Turn 0.6.1
2
-
3
- The facets/ansicode.rb library has been spun off as a separate
4
- project called 'ansi'. So this version swaps out its optional
5
- color support for the new project as well. You can install it via:
6
-
7
- gem install ansi
8
-
9
- You might want to take at the library, it has a few other
10
- interesting ANSI-related classes as well.
11
-
12
- == As of 0.6.0
13
-
14
- Turn 0.6 is now compatible with Test/Unit 2.0.
15
-
16
- A instance variable name change made between 1.x and 2.0 series
17
- of test/unit prevent the Turn modified Testrunner from working
18
- correctly.
19
-
20
- Other than that this release is the same as the 0.5.1 release.
21
-
22
- == As of 0.5.0
23
-
24
- As of 0.5.0, Turn has some signifficant new features:
25
-
26
- While Turn still provides the exact same functionality for running
27
- tests via ruby or testrb as previous versions. The turn commandline
28
- utility has been completely rewritten with expanded capabilites.
29
-
30
- The turn command now features three run modes:
31
-
32
- * Solo runner for running each test file in a separate process.
33
- * Cross runner for running test file pairs in separate processes.
34
- * Normal runner, which of course runs all test in a single process.
35
-
36
- It also support three report modes:
37
-
38
- * Progress reporter which uses a progress bar.
39
- * Minimal reporter which provides traditional "dot" progress.
40
- * Outline reporter populaized by turn.
41
-
42
- The is also a special Marshal Mode which dumps test results as YAML.
43
- And the underlying API makes it easy create new reporters.
44
-
45
- To get a quick rundown on how to use the new commandline:
46
-
47
- $ turn --help
1
+ = Turn 0.8.0
2
+
3
+ Version 0.8.0 is a fairly significant release for Turn. This release
4
+ adds support for Ruby 1.9's Minitest framework. You can even use
5
+ minitest with Ruby 1.8 by supplying the --minitest option on the turn
6
+ command line.
7
+
8
+ In addition, two new reporters have been a added, a new "pretty" reporter
9
+ which provides a more a modern "OSX" look (thanks Paydro) and a Cue
10
+ reporter which seeks user input with each failure or error (thanks
11
+ Shindo).
12
+
13
+ With this release we are encouraging users to move away from using
14
+ autorun modes. Autorunning is when your test script includes code
15
+ that "automagically" sets up a test runner, e.g. require 'test/unit'
16
+ and MiniTest::Unit.autorun, and by simply running the scripts
17
+ through the ruby interpretor the tests get run. There are a number
18
+ of problems with this approach. To begin with, running tests this way
19
+ limits Turn of a single mode of operation (that's no fun!) More
20
+ importantly it prevents interoperability between the old TestUnit
21
+ and the new MiniTest systems. By leaving these out and using a
22
+ commandline runner you can use the same tests for each version of
23
+ Ruby. This may require some adjutments to build tools, but hell,
24
+ why not use Turn there too. The Turn::Controller class makes it
25
+ damn easy.
26
+
27
+ One last note. Turn is no longer compatible with TestUnit 2.0+.
28
+ TestUnit and MiniTest are deverging and after some consideration
29
+ it was decided that Turn's goal is to support Ruby's native test
30
+ framework, whatever it may be.
48
31
 
49
32
  Enjoy!
50
33
 
data/Version.txt ADDED
@@ -0,0 +1 @@
1
+ 0.8.0
data/bin/turn CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- load 'turn/command.rb'
2
+ require 'turn/command'
3
+ Turn::Command.main(*ARGV)
4
4
 
@@ -0,0 +1,26 @@
1
+ require 'minitest/unit'
2
+ require 'turn'
3
+
4
+ class SampleCase1 < MiniTest::Unit::TestCase
5
+ def test_sample_pass1
6
+ assert_equal(1,1)
7
+ end
8
+ def test_sample_pass2
9
+ assert_equal(2,2)
10
+ end
11
+
12
+ def test_sample_fail1
13
+ assert_equal(1,2)
14
+ end
15
+ def test_sample_fail2
16
+ assert_include(1,[])
17
+ end
18
+
19
+ def test_sample_error1
20
+ raise StandardError, "Raised exception!"
21
+ end
22
+ def test_sample_error2
23
+ raise StandardError, "Raised another exception!"
24
+ end
25
+ end
26
+
@@ -0,0 +1,26 @@
1
+ require 'test/unit'
2
+ require 'turn'
3
+
4
+ class SampleCase1 < Test::Unit::TestCase
5
+ def test_sample_pass1
6
+ assert_equal(1,1)
7
+ end
8
+ def test_sample_pass2
9
+ assert_equal(2,2)
10
+ end
11
+
12
+ def test_sample_fail1
13
+ assert_equal(1,2)
14
+ end
15
+ def test_sample_fail2
16
+ assert_include(1,[])
17
+ end
18
+
19
+ def test_sample_error1
20
+ raise StandardError, "Raised exception!"
21
+ end
22
+ def test_sample_error2
23
+ raise StandardError, "Raised another exception!"
24
+ end
25
+ end
26
+
@@ -0,0 +1,35 @@
1
+ class SampleCase1 < Test::Unit::TestCase
2
+ def test_sample_pass1
3
+ assert_equal(1,1)
4
+ end
5
+ def test_sample_pass2
6
+ assert_equal(2,2)
7
+ end
8
+
9
+ def test_sample_fail1
10
+ assert_equal(1,2)
11
+ end
12
+ def test_sample_fail2
13
+ assert_include(1,[])
14
+ end
15
+
16
+ def test_sample_error1
17
+ raise StandardError, "Raised exception!"
18
+ end
19
+ def test_sample_error2
20
+ raise StandardError, "Raised another exception!"
21
+ end
22
+ end
23
+
24
+
25
+ class SampleCase2 < Test::Unit::TestCase
26
+ def test_sample_pass1
27
+ assert_equal(1,1)
28
+ end
29
+ def test_sample_pass2
30
+ assert_equal(1,1)
31
+ end
32
+ end
33
+
34
+ class EmptyCase < Test::Unit::TestCase
35
+ end
@@ -0,0 +1,155 @@
1
+ require 'minitest/unit'
2
+ require 'minitest/spec'
3
+ #require 'rubygems'
4
+ require 'ansi'
5
+
6
+ class MiniTest::Unit
7
+ include ANSI::Code
8
+
9
+ PADDING_SIZE = 4
10
+
11
+ def run(args = [])
12
+ @verbose = true
13
+
14
+ filter = if args.first =~ /^(-n|--name)$/ then
15
+ args.shift
16
+ arg = args.shift
17
+ arg =~ /\/(.*)\// ? Regexp.new($1) : arg
18
+ else
19
+ /./ # anything - ^test_ already filtered by #tests
20
+ end
21
+
22
+ @@out.puts "Loaded suite #{$0.sub(/\.rb$/, '')}\nStarted"
23
+
24
+ start = Time.now
25
+ run_test_suites filter
26
+
27
+ @@out.puts
28
+ @@out.puts "Finished in #{'%.6f' % (Time.now - start)} seconds."
29
+
30
+ @@out.puts
31
+
32
+ @@out.print "%d tests, " % test_count
33
+ @@out.print "%d assertions, " % assertion_count
34
+ @@out.print red { "%d failures, " % failures }
35
+ @@out.print yellow { "%d errors, " % errors }
36
+ @@out.puts cyan { "%d skips" % skips}
37
+
38
+ return failures + errors if @test_count > 0 # or return nil...
39
+ end
40
+
41
+ # Overwrite #run_test_suites so that it prints out reports
42
+ # as errors are generated.
43
+ def run_test_suites(filter = /./)
44
+ @test_count, @assertion_count = 0, 0
45
+ old_sync, @@out.sync = @@out.sync, true if @@out.respond_to? :sync=
46
+ TestCase.test_suites.each do |suite|
47
+ test_cases = suite.test_methods.grep(filter)
48
+ if test_cases.size > 0
49
+ @@out.print "\n#{suite}:\n"
50
+ end
51
+
52
+ test_cases.each do |test|
53
+ inst = suite.new test
54
+ inst._assertions = 0
55
+
56
+ t = Time.now
57
+
58
+ @broken = nil
59
+
60
+ @@out.print(case inst.run(self)
61
+ when :pass
62
+ @broken = false
63
+ green { pad_with_size "PASS" }
64
+ when :error
65
+ @broken = true
66
+ yellow { pad_with_size "ERROR" }
67
+ when :fail
68
+ @broken = true
69
+ red { pad_with_size "FAIL" }
70
+ when :skip
71
+ @broken = false
72
+ cyan { pad_with_size "SKIP" }
73
+ end)
74
+
75
+
76
+ @@out.print " #{test}"
77
+ @@out.print " (%.2fs) " % (Time.now - t)
78
+
79
+ if @broken
80
+ @@out.puts
81
+
82
+ report = @report.last
83
+ @@out.puts pad(report[:message], 10)
84
+ trace = MiniTest::filter_backtrace(report[:exception].backtrace).first
85
+ @@out.print pad(trace, 10)
86
+
87
+ @@out.puts
88
+ end
89
+
90
+ @@out.puts
91
+ @test_count += 1
92
+ @assertion_count += inst._assertions
93
+ end
94
+ end
95
+ @@out.sync = old_sync if @@out.respond_to? :sync=
96
+ [@test_count, @assertion_count]
97
+ end
98
+
99
+ def pad(str, size=PADDING_SIZE)
100
+ " " * size + str
101
+ end
102
+
103
+ def pad_with_size(str)
104
+ pad("%5s" % str)
105
+ end
106
+
107
+ # Overwrite #puke method so that is stores a hash
108
+ # with :message and :exception keys.
109
+ def puke(klass, meth, e)
110
+ result = nil
111
+ msg = case e
112
+ when MiniTest::Skip
113
+ @skips += 1
114
+ result = :skip
115
+ e.message
116
+ when MiniTest::Assertion
117
+ @failures += 1
118
+ result = :fail
119
+ e.message
120
+ else
121
+ @errors += 1
122
+ result = :error
123
+ "#{e.class}: #{e.message}\n"
124
+ end
125
+
126
+ @report << {:message => msg, :exception => e}
127
+ result
128
+ end
129
+
130
+
131
+ class TestCase
132
+ # Overwrite #run method so that is uses symbols
133
+ # as return values rather than characters.
134
+ def run(runner)
135
+ result = :pass
136
+ begin
137
+ @passed = nil
138
+ self.setup
139
+ self.__send__ self.__name__
140
+ @passed = true
141
+ rescue Exception => e
142
+ @passed = false
143
+ result = runner.puke(self.class, self.__name__, e)
144
+ ensure
145
+ begin
146
+ self.teardown
147
+ rescue Exception => e
148
+ result = runner.puke(self.class, self.__name__, e)
149
+ end
150
+ end
151
+ result
152
+ end
153
+ end
154
+ end
155
+
@@ -0,0 +1,102 @@
1
+ require 'test/unit/ui/console/testrunner'
2
+ require 'turn/colorize'
3
+
4
+ module ::Test::Unit
5
+ module UI
6
+ module Console
7
+ class TestRunner
8
+ include Turn::Colorize
9
+
10
+ # 1.x of test/unut used @io, where as 2.x uses @output.
11
+ def turn_out
12
+ @turn_out ||= (@io || @output)
13
+ end
14
+
15
+ alias :t_attach_to_mediator :attach_to_mediator
16
+ def attach_to_mediator
17
+ @mediator.add_listener(TestRunnerMediator::STARTED, &method(:t_started))
18
+ @mediator.add_listener(TestRunnerMediator::FINISHED, &method(:t_finished))
19
+ @mediator.add_listener(TestCase::STARTED, &method(:t_test_started))
20
+ @mediator.add_listener(TestCase::FINISHED, &method(:t_test_finished))
21
+ @mediator.add_listener(TestResult::FAULT, &method(:t_fault))
22
+ turn_out.sync = true
23
+ @t_cur_file, @t_fault = nil
24
+ end
25
+
26
+ def t_started( result )
27
+ @t_result = result
28
+ end
29
+
30
+ def t_finished( elapsed_time )
31
+ failure = @t_result.failure_count
32
+ error = @t_result.error_count
33
+ total = @t_result.run_count
34
+ pass = total - failure - error
35
+
36
+ bar = '=' * 78
37
+ if COLORIZE
38
+ bar = if pass == total then ::ANSI::Code.green bar
39
+ else ::ANSI::Code.red bar end
40
+ end
41
+
42
+ turn_out.puts bar
43
+ turn_out.puts " pass: %d, fail: %d, error: %d" % [pass, failure, error]
44
+ turn_out.puts " total: %d tests with %d assertions in #{elapsed_time} seconds" % [total, @t_result.assertion_count]
45
+ turn_out.puts bar
46
+ end
47
+
48
+ def t_test_started( name )
49
+ method, file = name.scan(%r/^([^\(]+)\(([^\)]+)\)/o).flatten!
50
+ if @t_cur_file != file
51
+ @t_cur_file = file
52
+ file = COLORIZE ? ::ANSI::Code.yellow(file) : file
53
+ turn_out.puts file
54
+ end
55
+ turn_out.print " %-69s" % method
56
+ end
57
+
58
+ def t_test_finished( name )
59
+ turn_out.puts " #{PASS}" unless @t_fault
60
+ @t_fault = false
61
+ end
62
+
63
+ def t_fault( fault )
64
+ @t_fault = true
65
+ msg = "\t"
66
+
67
+ case fault
68
+ when ::Test::Unit::Error
69
+ turn_out.puts ERROR
70
+ msg << fault.to_s.split("\n")[2..-1].join("\n\t")
71
+ when ::Test::Unit::Failure
72
+ turn_out.puts " #{FAIL}"
73
+ msg << fault.location[0].to_s << "\n\t"
74
+ msg << fault.message.gsub("\n","\n\t")
75
+ end
76
+
77
+ msg = ::ANSI::Code.magenta msg if COLORIZE
78
+ turn_out.puts msg
79
+ end
80
+
81
+ private
82
+ def setup_mediator
83
+ @mediator = create_mediator(@suite)
84
+ suite_name = @suite.to_s
85
+ if ( @suite.kind_of?(Module) )
86
+ suite_name = @suite.name
87
+ end
88
+ msg = rails? ? "\n" : "Loaded suite #{suite_name}" #always same in rails so scrap it
89
+ output(msg)
90
+ end
91
+
92
+ def rails?
93
+ $:.to_s.include? "rails"
94
+ end
95
+
96
+
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ # EOF
data/lib/turn/bin.rb ADDED
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift(File.dirname(File.dirname(__FILE__)))
2
+ require 'turn/command'
3
+ Turn::Command.main(*ARGV)
4
+
data/lib/turn/colorize.rb CHANGED
@@ -14,16 +14,52 @@ module Turn
14
14
 
15
15
  COLORIZE = defined?(::ANSI::Code) && ENV.has_key?('TERM')
16
16
 
17
- if COLORIZE
18
- PASS = ::ANSI::Code.green('PASS')
19
- FAIL = ::ANSI::Code.red('FAIL')
20
- ERROR = ::ANSI::Code.white(::ANSI::Code.on_red('ERROR'))
21
- else
22
- PASS = "PASS"
23
- FAIL = "FAIL"
24
- ERROR = "ERROR"
17
+ def self.red(string)
18
+ COLORIZE ? ::ANSI::Code.red{ string } : string
25
19
  end
26
20
 
21
+ def self.green(string)
22
+ COLORIZE ? ::ANSI::Code.green{ string } : string
23
+ end
24
+
25
+ def self.blue(string)
26
+ COLORIZE ? ::ANSI::Code.blue{ string } : string
27
+ end
28
+
29
+ def self.magenta(string)
30
+ COLORIZE ? ::ANSI::Code.magenta{ string } : string
31
+ end
32
+
33
+ def self.bold(string)
34
+ COLORIZE ? ::ANSI::Code.bold{ string } : string
35
+ end
36
+
37
+ def self.pass(string)
38
+ COLORIZE ? ::ANSI::Code.green{ string } : string
39
+ end
40
+
41
+ def self.fail(string)
42
+ COLORIZE ? ::ANSI::Code.red{ string } : string
43
+ end
44
+
45
+ #def self.error(string)
46
+ # COLORIZE ? ::ANSI::Code.white{ ::ANSI::Code.on_red{ string } } : string
47
+ #end
48
+
49
+ def self.error(string)
50
+ COLORIZE ? ::ANSI::Code.yellow{ string } : string
51
+ end
52
+
53
+ def self.skip(string)
54
+ COLORIZE ? ::ANSI::Code.cyan{ string } : string
55
+ end
56
+
57
+ PASS = pass('PASS')
58
+ FAIL = fail('FAIL')
59
+ ERROR = error('ERROR')
60
+ SKIP = skip('SKIP')
61
+
27
62
  end
28
63
 
29
64
  end
65
+