turn 0.8.3 → 0.9.0

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