openlogic-turn 0.8.2

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,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
+