openlogic-turn 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,116 @@
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
+ test_name = underscore(fault.test_name.match(/\((.*)\)/)[1])
73
+ better_location = fault.location.detect{|line|line.include?(test_name)} || fault.location[0]
74
+ turn_out.puts " #{FAIL}"
75
+ msg << better_location.to_s << "\n\t"
76
+ msg << fault.message.gsub("\n","\n\t")
77
+ end
78
+
79
+ msg = ::ANSI::Code.magenta msg if COLORIZE
80
+ turn_out.puts msg
81
+ end
82
+
83
+ private
84
+
85
+ # Taken from ActiveSupport::Inflector
86
+ def underscore(camel_cased_word)
87
+ word = camel_cased_word.to_s.dup
88
+ word.gsub!(/::/, '/')
89
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
90
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
91
+ word.tr!("-", "_")
92
+ word.downcase!
93
+ word
94
+ end
95
+
96
+ def setup_mediator
97
+ @mediator = create_mediator(@suite)
98
+ suite_name = @suite.to_s
99
+ if ( @suite.kind_of?(Module) )
100
+ suite_name = @suite.name
101
+ end
102
+ msg = rails? ? "\n" : "Loaded suite #{suite_name}" #always same in rails so scrap it
103
+ output(msg)
104
+ end
105
+
106
+ def rails?
107
+ $:.to_s.include? "rails"
108
+ end
109
+
110
+
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ # 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
+
@@ -0,0 +1,65 @@
1
+ begin
2
+ require 'ansi/code'
3
+ rescue LoadError
4
+ begin
5
+ require 'rubygems'
6
+ require 'ansi/code'
7
+ rescue LoadError
8
+ end
9
+ end
10
+
11
+ module Turn
12
+
13
+ module Colorize
14
+
15
+ COLORIZE = defined?(::ANSI::Code) && ENV.has_key?('TERM')
16
+
17
+ def self.red(string)
18
+ COLORIZE ? ::ANSI::Code.red{ string } : string
19
+ end
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
+
62
+ end
63
+
64
+ end
65
+
@@ -0,0 +1,210 @@
1
+ require 'optparse'
2
+ require 'turn/controller'
3
+
4
+ module Turn
5
+
6
+ # Turn - Pretty Unit Test Runner for Ruby
7
+ #
8
+ # SYNOPSIS
9
+ # turn [OPTIONS] [RUN MODE] [OUTPUT MODE] [test globs...]
10
+ #
11
+ # OPTIONS
12
+ # -h --help display this help information
13
+ # --live don't use loadpath
14
+ # --log log results to a file
15
+ # -n --name=PATTERN only run tests that match regexp PATTERN
16
+ # -I --loadpath=PATHS add given PATHS to the $LOAD_PATH
17
+ # -r --requires=LIBS require given LIBS before running tests
18
+ # -m --minitest Force use of MiniTest framework.
19
+ #
20
+ # RUN MODES
21
+ # --normal run all tests in a single process [default]
22
+ # --solo run each test in a separate process
23
+ # --cross run each pair of test files in a separate process
24
+ #
25
+ # OUTPUT MODES
26
+ # -O --outline turn's original case/test outline mode [default]
27
+ # -P --progress indicates progress with progress bar
28
+ # -D --dotted test/unit's traditonal dot-progress mode
29
+ # --pretty new pretty reporter
30
+ # -M --marshal dump output as YAML (normal run mode only)
31
+ # -Q --queued interactive testing
32
+ #
33
+ class Command
34
+
35
+ # Shortcut for new.main(*argv)
36
+ def self.main(*argv)
37
+ new.main(*argv)
38
+ end
39
+
40
+ # Log output.
41
+ attr :log
42
+
43
+ # Do not use local loadpath.
44
+ attr :live
45
+
46
+ # Only run tests matching this pattern.
47
+ attr :pattern
48
+
49
+ # List of paths to add to $LOAD_PATH
50
+ attr :loadpath
51
+
52
+ # Libraries to require before running tests.
53
+ attr :requires
54
+
55
+ # Framework to use, :minitest or :testunit.
56
+ attr :framework
57
+
58
+ # Run mode.
59
+ attr :runmode
60
+
61
+ # Output mode.
62
+ attr :outmode
63
+
64
+ #
65
+ def initialize
66
+ @live = nil
67
+ @log = nil
68
+ @pattern = nil
69
+ @loadpath = []
70
+ @requires = []
71
+ @runmode = nil
72
+ @outmode = nil
73
+ @framework = RUBY_VERSION >= "1.9" ? :minitest : :testunit
74
+ end
75
+
76
+ #
77
+ def option_parser
78
+ OptionParser.new do |opts|
79
+
80
+ opts.banner = "Turn - Pretty Unit Test Runner for Ruby"
81
+
82
+ opts.separator " "
83
+ opts.separator "SYNOPSIS"
84
+ opts.separator " turn [OPTIONS] [RUN MODE] [OUTPUT MODE] [TEST GLOBS ...]"
85
+
86
+ opts.separator " "
87
+ opts.separator "GENERAL OPTIONS"
88
+
89
+ opts.on('-I', '--loadpath=PATHS', "add paths to $LOAD_PATH") do |path|
90
+ @loadpath.concat(path.split(':'))
91
+ end
92
+
93
+ opts.on('-r', '--require=LIBS', "require libraries") do |lib|
94
+ @requires.concat(lib.split(':'))
95
+ end
96
+
97
+ opts.on('-n', '--name=PATTERN', "only run tests that match PATTERN") do |pattern|
98
+ @pattern = Regexp.new(pattern, Regexp::IGNORECASE)
99
+ end
100
+
101
+ opts.on('-m', '--minitest', "Force use of MiniTest framework") do
102
+ @framework = :minitest
103
+ end
104
+
105
+ # Turn does not support Test::Unit 2.0+
106
+ #opts.on('-u', '--testunit', "Force use of TestUnit framework") do
107
+ # @framework = :testunit
108
+ #end
109
+
110
+ opts.on('--log', "log results to a file") do #|path|
111
+ @log = true # TODO: support path/file
112
+ end
113
+
114
+ opts.on('--live', "do not use local load path") do
115
+ @live = true
116
+ end
117
+
118
+ opts.separator " "
119
+ opts.separator "RUN MODES"
120
+
121
+ opts.on('--normal', "run all tests in a single process [default]") do
122
+ @runmode = nil
123
+ end
124
+
125
+ opts.on('--solo', "run each test in a separate process") do
126
+ @runmode = :solo
127
+ end
128
+
129
+ opts.on('--cross', "run each pair of test files in a separate process") do
130
+ @runmode = :cross
131
+ end
132
+
133
+ #opts.on('--load', "") do
134
+ #end
135
+
136
+ opts.separator " "
137
+ opts.separator "OUTPUT MODES"
138
+
139
+ opts.on('--outline', '-O', "turn's original case/test outline mode [default]") do
140
+ @outmode = :outline
141
+ end
142
+
143
+ opts.on('--progress', '-P', "indicates progress with progress bar") do
144
+ @outmode = :progress
145
+ end
146
+
147
+ opts.on('--dotted', '-D', "test-unit's traditonal dot-progress mode") do
148
+ @outmode = :dotted
149
+ end
150
+
151
+ opts.on('--pretty', '-T', "new pretty output mode") do
152
+ @outmode = :pretty
153
+ end
154
+
155
+ opts.on('--cue', '-C', "cue for action on each failure/error") do
156
+ @outmode = :cue
157
+ end
158
+
159
+ opts.on('--marshal', '-M', "dump output as YAML (normal run mode only)") do
160
+ @runmode = :marshal
161
+ @outmode = :marshal
162
+ end
163
+
164
+ opts.separator " "
165
+ opts.separator "COMMAND OPTIONS"
166
+
167
+ opts.on('--debug', "turn debug mode on") do
168
+ $VERBOSE = true
169
+ $DEBUG = true
170
+ end
171
+
172
+ opts.on_tail('--help', '-h', "display this help information") do
173
+ puts opts
174
+ exit
175
+ end
176
+ end
177
+ end
178
+
179
+ # Run command.
180
+ def main(*argv)
181
+ option_parser.parse!(argv)
182
+
183
+ @loadpath = ['lib'] if loadpath.empty?
184
+
185
+ tests = ARGV.empty? ? nil : ARGV.dup
186
+
187
+ controller = Turn::Controller.new do |c|
188
+ c.live = live
189
+ c.log = log
190
+ c.loadpath = loadpath
191
+ c.requires = requires
192
+ c.tests = tests
193
+ c.runmode = runmode
194
+ c.format = outmode
195
+ c.pattern = pattern
196
+ c.framework = framework
197
+ end
198
+
199
+ result = controller.start
200
+
201
+ if result
202
+ exit result.passed?
203
+ else # no tests
204
+ exit
205
+ end
206
+ end
207
+
208
+ end
209
+
210
+ end
@@ -0,0 +1,104 @@
1
+ module Turn
2
+
3
+ #
4
+ class TestCase
5
+ include Enumerable
6
+
7
+ # Name of test case.
8
+ attr_accessor :name
9
+
10
+ # Test methods.
11
+ attr_accessor :tests
12
+
13
+ # Some runners marshal tests per file.
14
+ attr_accessor :files
15
+
16
+ #attr_accessor :count_passes
17
+ #attr_accessor :count_failures
18
+ #attr_accessor :count_errors
19
+ #attr_accessor :count_tests
20
+
21
+ # This can't be calculated, so it must be
22
+ # assigned by the runner.
23
+ attr_accessor :count_assertions
24
+
25
+ # Holds dump of test output (optional depending on runner).
26
+ attr_accessor :message
27
+
28
+ # Command used to run test (optional depending on runner).
29
+ #attr_accessor :command
30
+
31
+ #
32
+ def initialize(name, *files)
33
+ @name = name
34
+ @files = (files.empty? ? [name] : files)
35
+ @tests = []
36
+
37
+ @message = nil
38
+ @count_assertions = 0
39
+
40
+ #@count_tests = 0
41
+ #@count_failures = 0
42
+ #@count_errors = 0
43
+
44
+ #@command = command
45
+ end
46
+
47
+ def new_test(name)
48
+ c = TestMethod.new(name)
49
+ @tests << c
50
+ c
51
+ end
52
+
53
+ # Whne used by a per-file runner.
54
+ #alias_method :file, :name
55
+
56
+ # Were there any errors?
57
+ def error?
58
+ count_errors != 0
59
+ end
60
+
61
+ # Were there any failures?
62
+ def fail?
63
+ count_failures != 0
64
+ end
65
+
66
+ # Did all tests/assertion pass?
67
+ def pass?
68
+ not(fail? or error?)
69
+ end
70
+
71
+ def count_tests
72
+ tests.size
73
+ end
74
+
75
+ alias_method :size, :count_tests
76
+
77
+ def count_failures
78
+ sum = 0; tests.each{ |t| sum += 1 if t.fail? }; sum
79
+ end
80
+
81
+ def count_errors
82
+ sum = 0; tests.each{ |t| sum += 1 if t.error? }; sum
83
+ end
84
+
85
+ def count_passes
86
+ sum = 0; tests.each{ |t| sum += 1 if t.pass? }; sum
87
+ end
88
+
89
+ #
90
+ def counts
91
+ return count_tests, count_assertions, count_failures, count_errors
92
+ end
93
+
94
+ def message
95
+ tests.collect{ |t| t.message }.join("\n")
96
+ end
97
+
98
+ def each(&block)
99
+ tests.each(&block)
100
+ end
101
+ end
102
+
103
+ end
104
+