turn 0.8.3 → 0.9.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.
Files changed (44) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +1 -8
  3. data/History.txt +16 -0
  4. data/{license/GPLv2.txt → LICENSE-GPL2.txt} +0 -0
  5. data/{license/MIT-LICENSE.txt → LICENSE-MIT.txt} +0 -0
  6. data/{license/RUBY-LICENSE.txt → LICENSE-RUBY.txt} +0 -0
  7. data/{NOTICE.txt → LICENSE.txt} +1 -1
  8. data/README.md +26 -0
  9. data/Rakefile +1 -0
  10. data/Version.txt +1 -1
  11. data/bin/turn +7 -1
  12. data/lib/turn.rb +20 -11
  13. data/lib/turn/autoload.rb +1 -1
  14. data/lib/turn/autorun.rb +8 -0
  15. data/lib/turn/bin.rb +7 -1
  16. data/lib/turn/colorize.rb +26 -10
  17. data/lib/turn/command.rb +32 -13
  18. data/lib/turn/components.rb +4 -0
  19. data/lib/turn/components/case.rb +1 -1
  20. data/lib/turn/components/suite.rb +9 -3
  21. data/lib/turn/configuration.rb +197 -0
  22. data/lib/turn/controller.rb +15 -206
  23. data/lib/turn/{autorun/minitest.rb → minitest.rb} +7 -3
  24. data/lib/turn/reporter.rb +65 -10
  25. data/lib/turn/reporters/cue_reporter.rb +13 -2
  26. data/lib/turn/reporters/dot_reporter.rb +12 -11
  27. data/lib/turn/reporters/outline_reporter.rb +57 -36
  28. data/lib/turn/reporters/pretty_reporter.rb +37 -24
  29. data/lib/turn/reporters/progress_reporter.rb +64 -26
  30. data/lib/turn/runners/minirunner.rb +7 -32
  31. data/lib/turn/testunit.rb +5 -0
  32. data/test/helper.rb +11 -2
  33. data/test/test_framework.rb +39 -30
  34. data/test/test_runners.rb +9 -7
  35. data/{demo → try}/test_autorun_minitest.rb +0 -0
  36. data/{demo → try}/test_autorun_testunit.rb +0 -0
  37. data/{demo → try}/test_counts.rb +0 -0
  38. data/{demo → try}/test_sample.rb +0 -0
  39. data/{demo → try}/test_sample2.rb +0 -0
  40. data/turn.gemspec +2 -2
  41. metadata +42 -29
  42. data/lib/turn/autorun/minitest0.rb +0 -163
  43. data/lib/turn/autorun/testunit.rb +0 -9
  44. data/lib/turn/autorun/testunit0.rb +0 -116
@@ -1,197 +1,6 @@
1
- require 'fileutils'
2
-
3
1
  module Turn
4
2
 
5
- require 'turn/version'
6
- require 'turn/autoload'
7
- require 'turn/components/suite.rb'
8
- require 'turn/components/case.rb'
9
- require 'turn/components/method.rb'
10
-
11
- # Configure Turn
12
- def self.config(&block)
13
- @config ||= Configuration.new
14
- block.call(@config) if block
15
- @config
16
- end
17
-
18
- #
19
- #
20
- #--
21
- # TODO: Add support to test run loggging.
22
- #++
23
- class Configuration
24
-
25
- # List of if file names or glob pattern of tests to run.
26
- attr_accessor :tests
27
-
28
- # List of file names or globs to exclude from +tests+ list.
29
- attr_accessor :exclude
30
-
31
- # Regexp pattern that all test name's must
32
- # match to be eligible to run.
33
- attr_accessor :pattern
34
-
35
- # Regexp pattern that all test cases must
36
- # match to be eligible to run.
37
- attr_accessor :matchcase
38
-
39
- # Add these folders to the $LOAD_PATH.
40
- attr_accessor :loadpath
41
-
42
- # Libs to require when running tests.
43
- attr_accessor :requires
44
-
45
- # Reporter type.
46
- attr_accessor :format
47
-
48
- # Run mode.
49
- attr_accessor :runmode
50
-
51
- # Test against live install (i.e. Don't use loadpath option)
52
- attr_accessor :live
53
-
54
- # Log results? May be true/false or log file name. (TODO)
55
- attr_accessor :log
56
-
57
- # Verbose output?
58
- attr_accessor :verbose
59
-
60
- # Test framework, either :minitest or :testunit
61
- attr_accessor :framework
62
-
63
- # Enable full backtrace
64
- attr_accessor :trace
65
-
66
- # Use natural language case names.
67
- attr_accessor :natural
68
-
69
- def verbose? ; @verbose ; end
70
- def live? ; @live ; end
71
- def natural? ; @natural ; end
72
-
73
- private
74
-
75
- def initialize
76
- yield(self) if block_given?
77
- initialize_defaults
78
- end
79
-
80
- #
81
- def initialize_defaults
82
- @loadpath ||= ['lib']
83
- @tests ||= ["test/**/{test,}*{,test}.rb"]
84
- @exclude ||= []
85
- @requires ||= []
86
- @live ||= false
87
- @log ||= true
88
- #@format ||= nil
89
- #@runner ||= RUBY_VERSION >= "1.9" ? MiniRunner : TestRunner
90
- @matchcase ||= nil
91
- @pattern ||= /.*/
92
- @natural ||= false
93
-
94
- @files = nil # reset files just in case
95
- end
96
-
97
- # Collect test configuation.
98
- #def test_configuration(options={})
99
- # #options = configure_options(options, 'test')
100
- # #options['loadpath'] ||= metadata.loadpath
101
- # options['tests'] ||= self.tests
102
- # options['loadpath'] ||= self.loadpath
103
- # options['requires'] ||= self.requires
104
- # options['live'] ||= self.live
105
- # options['exclude'] ||= self.exclude
106
- # #options['tests'] = list_option(options['tests'])
107
- # options['loadpath'] = list_option(options['loadpath'])
108
- # options['exclude'] = list_option(options['exclude'])
109
- # options['require'] = list_option(options['require'])
110
- # return options
111
- #end
112
-
113
- #
114
- def list_option(list)
115
- case list
116
- when nil
117
- []
118
- when Array
119
- list
120
- else
121
- list.split(/[:;]/)
122
- end
123
- end
124
-
125
- public
126
-
127
- def tests=(paths)
128
- @tests = list_option(paths)
129
- end
130
-
131
- def loadpath=(paths)
132
- @loadpath = list_option(paths)
133
- end
134
-
135
- def exclude=(paths)
136
- @exclude = list_option(paths)
137
- end
138
-
139
- def requires=(paths)
140
- @requires = list_option(paths)
141
- end
142
-
143
- # Test files.
144
- def files
145
- @files ||= (
146
- fs = tests.map do |t|
147
- File.directory?(t) ? Dir[File.join(t, '**', '*')] : Dir[t]
148
- end
149
- fs = fs.flatten.reject{ |f| File.directory?(f) }
150
-
151
- ex = exclude.map do |x|
152
- File.directory?(x) ? Dir[File.join(x, '**', '*')] : Dir[x]
153
- end
154
- ex = ex.flatten.reject{ |f| File.directory?(f) }
155
-
156
- (fs - ex).uniq.map{ |f| File.expand_path(f) }
157
- ).flatten
158
- end
159
-
160
- # TODO: Better name ?
161
- def suite_name
162
- files.map{ |path| File.dirname(path).sub(Dir.pwd+'/','') }.uniq.join(',')
163
- end
164
-
165
- # Select reporter based on output mode.
166
- def reporter
167
- @reporter ||= (
168
- opts = { :trace=>trace, :natural=>natural? }
169
- case format
170
- when :marshal
171
- require 'turn/reporters/marshal_reporter'
172
- Turn::MarshalReporter.new($stdout, opts)
173
- when :progress
174
- require 'turn/reporters/progress_reporter'
175
- Turn::ProgressReporter.new($stdout, opts)
176
- when :dotted
177
- require 'turn/reporters/dot_reporter'
178
- Turn::DotReporter.new($stdout, opts)
179
- when :pretty
180
- require 'turn/reporters/pretty_reporter'
181
- Turn::PrettyReporter.new($stdout, opts)
182
- when :cue
183
- require 'turn/reporters/cue_reporter'
184
- Turn::CueReporter.new($stdout, opts)
185
- else
186
- require 'turn/reporters/outline_reporter'
187
- Turn::OutlineReporter.new($stdout, opts)
188
- end
189
- )
190
- end
191
-
192
- end
193
-
194
- # = Controller
3
+ # Controls execution of test run.
195
4
  #
196
5
  class Controller
197
6
 
@@ -223,23 +32,23 @@ module Turn
223
32
  config.files.each{ |path| require(path) }
224
33
  end
225
34
 
226
- # # Insatance of Runner, selected based on format and runmode.
35
+ # Insatance of Runner, selected based on format and runmode.
227
36
  def runner
228
37
  @runner ||= (
229
- case config.framework
230
- when :minitest
38
+ #case config.framework
39
+ #when :minitest
231
40
  require 'turn/runners/minirunner'
232
- else
233
- require 'turn/runners/testrunner'
234
- end
41
+ #else
42
+ # require 'turn/runners/testrunner'
43
+ #end
235
44
 
236
45
  case config.runmode
237
46
  when :marshal
238
- if config.framework == :minitest
47
+ #if config.framework == :minitest
239
48
  Turn::MiniRunner
240
- else
241
- Turn::TestRunner
242
- end
49
+ #else
50
+ # Turn::TestRunner
51
+ #end
243
52
  when :solo
244
53
  require 'turn/runners/solorunner'
245
54
  Turn::SoloRunner
@@ -247,11 +56,11 @@ module Turn
247
56
  require 'turn/runners/crossrunner'
248
57
  Turn::CrossRunner
249
58
  else
250
- if config.framework == :minitest
59
+ #if config.framework == :minitest
251
60
  Turn::MiniRunner
252
- else
253
- Turn::TestRunner
254
- end
61
+ #else
62
+ # Turn::TestRunner
63
+ #end
255
64
  end
256
65
  )
257
66
  end
@@ -1,12 +1,16 @@
1
- require 'turn/autoload'
1
+ #require 'turn'
2
2
 
3
+ # make sure latest verison is used, rather than ruby's built-in
4
+ begin; gem 'minitest'; rescue Exception; end
5
+
6
+ # we save the developer the trouble of having to load these (TODO: should we?)
3
7
  require 'minitest/unit'
4
8
  require 'minitest/spec'
5
9
 
6
- require 'turn/colorize'
7
- require 'turn/controller'
10
+ # load Turn's minitest runner
8
11
  require 'turn/runners/minirunner'
9
12
 
13
+ # set MiniTest's runner to Turn::MiniRunner instance
10
14
  if MiniTest::Unit.respond_to?(:runner=)
11
15
  MiniTest::Unit.runner = Turn::MiniRunner.new
12
16
  else
@@ -2,8 +2,6 @@ module Turn
2
2
  require 'turn/colorize'
3
3
  require 'turn/core_ext'
4
4
 
5
- # = Reporter
6
- #
7
5
  # There are two distinct way in which a report may be utilized
8
6
  # by a Runner: per-call or per-file. The method #pass, #fail
9
7
  # and #error are generic, and will be used in either case.
@@ -16,6 +14,7 @@ module Turn
16
14
 
17
15
  include Colorize
18
16
 
17
+ # Where to send report, defaults to `$stdout`.
19
18
  attr :io
20
19
 
21
20
  def initialize(io, opts={})
@@ -26,46 +25,102 @@ module Turn
26
25
 
27
26
  # These methods are called in the process of running the tests.
28
27
 
28
+ # At the very start, before any testcases are run, this is called.
29
29
  def start_suite(test_suite)
30
30
  end
31
31
 
32
+ # Invoked before a testcase is run.
32
33
  def start_case(test_case)
33
34
  end
34
35
 
36
+ # Invoked before a test is run.
35
37
  def start_test(test)
36
38
  end
37
39
 
40
+ # Invoked when a test passes.
38
41
  def pass(message=nil)
39
42
  end
40
43
 
44
+ # Invoked when a test raises an assertion.
41
45
  def fail(assertion, message=nil)
42
46
  end
43
47
 
48
+ # Invoked when a test raises an exception.
44
49
  def error(exception, message=nil)
45
50
  end
46
51
 
52
+ # Invoked when a test is skipped.
53
+ def skip(exception, message=nil)
54
+ end
55
+
56
+ # Invoked after a test has been run.
47
57
  def finish_test(test)
48
58
  end
49
59
 
60
+ # Invoked after all tests in a testcase have ben run.
50
61
  def finish_case(test_case)
51
62
  end
52
63
 
64
+ # After all tests are run, this is the last observable action.
53
65
  def finish_suite(test_suite)
54
66
  end
55
67
 
56
68
  private
57
69
 
58
- # TODO: backtrace filter probably could use some refinement.
59
- def filter_backtrace(bt)
60
- return [] unless bt
61
- bt.reject!{ |line| line.rindex('minitest') }
62
- bt.reject!{ |line| line.rindex('test/unit') }
63
- bt.reject!{ |line| line.rindex('lib/turn') }
64
- bt.reject!{ |line| line.rindex('bin/turn') }
70
+ # Apply filter_backtrace and limit_backtrace in one go.
71
+ def clean_backtrace(backtrace)
72
+ limit_backtrace(filter_backtrace(backtrace))
73
+ end
74
+
75
+ $RUBY_IGNORE_CALLERS ||= []
76
+ $RUBY_IGNORE_CALLERS.concat([
77
+ /\/turn.*\.rb/,
78
+ /\/bin\/turn/,
79
+ /\/minitest.*\.rb/,
80
+ /\/test\/unit.*\.rb/
81
+ ])
82
+
83
+ # Filter backtrace of unimportant entries, and applies count limit if set in
84
+ # configuration. Setting $DEBUG to true will deactivate filter, or if the filter
85
+ # happens to remove all backtrace entries it will revert to the full backtrace,
86
+ # as that probably means there was an issue with the test harness itself.
87
+ def filter_backtrace(backtrace)
88
+ return [] unless backtrace
89
+ bt = backtrace.dup
90
+ bt.reject!{ |line| $RUBY_IGNORE_CALLERS.any?{ |re| re =~ line } } unless $DEBUG
91
+ #bt.reject!{ |line| line.rindex('minitest') }
92
+ #bt.reject!{ |line| line.rindex('test/unit') }
93
+ #bt.reject!{ |line| line.rindex('lib/turn') }
94
+ #bt.reject!{ |line| line.rindex('bin/turn') }
95
+ bt = backtrace if bt.empty? # if empty just dump the whole thing
65
96
  bt.map{ |line| line.sub(Dir.pwd+'/', '') }
66
97
  end
67
98
 
99
+ # Limit backtrace to number of lines if `trace` configuration option is set.
100
+ def limit_backtrace(backtrace)
101
+ return [] unless backtrace
102
+ @trace ? backtrace[0, @trace.to_i] : backtrace
103
+ end
104
+
105
+ #
106
+ def naturalized_name(test)
107
+ if @natural
108
+ " #{test.name.gsub("test_", "").gsub(/_/, " ")}"
109
+ else
110
+ " #{test.name}"
111
+ end
112
+ end
113
+
114
+ #
115
+ def ticktock
116
+ t = Time.now - @time
117
+ h, t = t.divmod(60)
118
+ m, t = t.divmod(60)
119
+ s = t.truncate
120
+ f = ((t - s) * 1000).to_i
121
+
122
+ "%01d:%02d:%02d:%03d" % [h,m,s,f]
123
+ end
68
124
  end
69
125
 
70
126
  end
71
-
@@ -67,6 +67,15 @@ module Turn
67
67
  prompt
68
68
  end
69
69
 
70
+ def skip(exception, message=nil)
71
+ message = message || exception.to_s
72
+ io.puts("#{SKIP}")
73
+ io.puts(message) #if message
74
+
75
+ #prompt
76
+ end
77
+
78
+
70
79
  def finish_test(test)
71
80
  $stdout = STDOUT
72
81
  $stderr = STDERR
@@ -130,9 +139,11 @@ module Turn
130
139
  when 'c', ''
131
140
  when 'r'
132
141
  # how to reload and start over?
142
+ io.puts "restart has not been implemented yet"
133
143
  when 'i'
134
144
  # how to drop into an interactive console?
135
- when 't'
145
+ io.puts "irb support has not been implemented yet"
146
+ when 'b', 't'
136
147
  io.puts $@
137
148
  raise ArgumentError
138
149
  when /^\d+$/
@@ -155,7 +166,7 @@ module Turn
155
166
  c continue
156
167
  r restart
157
168
  i irb
158
- t backtrace
169
+ b backtrace
159
170
  # backtrace lines
160
171
  q quit
161
172
  ? help
@@ -19,17 +19,21 @@ module Turn
19
19
  end
20
20
 
21
21
  def pass(message=nil)
22
- io.print Colorize.pass('.'); io.flush
22
+ io.print Colorize.pass('S'); io.flush
23
23
  end
24
24
 
25
- def fail(message=nil)
25
+ def fail(assertion, message=nil)
26
26
  io.print Colorize.fail('F'); io.flush
27
27
  end
28
28
 
29
- def error(message=nil)
29
+ def error(exception, message=nil)
30
30
  io.print Colorize.error('E'); io.flush
31
31
  end
32
32
 
33
+ def skip(exception, message=nil)
34
+ io.print Colorize.skip('-'); io.flush
35
+ end
36
+
33
37
  def finish_test(test)
34
38
  end
35
39
 
@@ -53,14 +57,11 @@ module Turn
53
57
  unless list.empty? # or verbose?
54
58
  #report << "\n\n-- Failures and Errors --\n\n"
55
59
  list.uniq.each do |testunit|
56
- message = testunit.fail? ? ' ' + FAIL : ERROR
57
- message = message + ' ' + testunit.message.tabto(0)
58
- backtrace = filter_backtrace(testunit.backtrace)
59
- message << "\n" + (backtrace.shift || '')
60
- if @trace
61
- message << "\n" + backtrace.join("\n")
62
- end
63
- report << "\n" << message << "\n"
60
+ message = []
61
+ message << (testunit.fail? ? FAIL : ERROR)
62
+ message << testunit.message.tabto(2)
63
+ message << clean_backtrace(testunit.backtrace).join("\n").tabto(2)
64
+ report << "\n" << message.join("\n") << "\n"
64
65
  end
65
66
  report << "\n"
66
67
  end