turn 0.8.2 → 0.9.7

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 (52) hide show
  1. data/CONTRIBUTING.md +40 -0
  2. data/History.txt +81 -1
  3. data/Index.rb +34 -0
  4. data/LICENSE.txt +21 -0
  5. data/NOTICE.md +12 -0
  6. data/README.md +176 -0
  7. data/Release.txt +21 -1
  8. data/Version.txt +1 -1
  9. data/bin/turn +8 -2
  10. data/lib/turn/autoload.rb +6 -0
  11. data/lib/turn/autorun.rb +4 -0
  12. data/lib/turn/bin.rb +8 -2
  13. data/lib/turn/colorize.rb +50 -19
  14. data/lib/turn/command.rb +102 -39
  15. data/lib/turn/components/case.rb +7 -2
  16. data/lib/turn/components/method.rb +13 -2
  17. data/lib/turn/components/suite.rb +15 -6
  18. data/lib/turn/components.rb +4 -0
  19. data/lib/turn/configuration.rb +271 -0
  20. data/lib/turn/controller.rb +18 -176
  21. data/lib/turn/decorators/topten_decorator.rb +67 -0
  22. data/lib/turn/minitest.rb +25 -0
  23. data/lib/turn/reporter.rb +75 -13
  24. data/lib/turn/reporters/cue_reporter.rb +27 -11
  25. data/lib/turn/reporters/dot_reporter.rb +24 -28
  26. data/lib/turn/reporters/outline_reporter.rb +76 -39
  27. data/lib/turn/reporters/pretty_reporter.rb +110 -129
  28. data/lib/turn/reporters/progress_reporter.rb +70 -33
  29. data/lib/turn/runners/crossrunner.rb +2 -2
  30. data/lib/turn/runners/isorunner.rb +12 -10
  31. data/lib/turn/runners/minirunner.rb +51 -81
  32. data/lib/turn/runners/solorunner.rb +0 -1
  33. data/lib/turn/runners/testrunner.rb +12 -15
  34. data/lib/turn/testunit.rb +24 -0
  35. data/lib/turn/version.rb +1 -1
  36. data/lib/turn.rb +10 -15
  37. data/test/helper.rb +81 -5
  38. data/test/reporter_test.rb +35 -0
  39. data/test/test_framework.rb +81 -38
  40. data/test/test_reporters.rb +14 -14
  41. data/test/test_runners.rb +57 -19
  42. data/{demo → try}/test_autorun_minitest.rb +5 -4
  43. data/{demo → try}/test_autorun_testunit.rb +1 -2
  44. metadata +135 -112
  45. data/README.txt +0 -116
  46. data/Rakefile +0 -39
  47. data/lib/turn/autorun/minitest.rb +0 -173
  48. data/lib/turn/autorun/testunit.rb +0 -116
  49. data/turn.gemspec +0 -49
  50. /data/{demo → try}/test_counts.rb +0 -0
  51. /data/{demo → try}/test_sample.rb +0 -0
  52. /data/{demo → try}/test_sample2.rb +0 -0
@@ -19,14 +19,15 @@ module Turn
19
19
 
20
20
  private
21
21
 
22
- def initialize(controller)
23
- @controller = controller
24
- @reporter = controller.reporter
22
+ def initialize
23
+ @config = Turn.config
24
+
25
+ @reporter = @config.reporter
25
26
  #yield(self) if block_given?
26
- @loadpath = controller.loadpath
27
- @requires = controller.requires
28
- @live = controller.live?
29
- @minitest = controller.framework == :minitest
27
+ @loadpath = @config.loadpath
28
+ @requires = @config.requires
29
+ @live = @config.live?
30
+ @minitest = @config.framework == :minitest
30
31
  end
31
32
 
32
33
  public
@@ -36,7 +37,7 @@ module Turn
36
37
  #
37
38
  def start
38
39
  suite = TestSuite.new
39
- testruns = @controller.files.collect do |file|
40
+ testruns = @config.files.collect do |file|
40
41
  name = file.sub(Dir.pwd+'/','')
41
42
  suite.new_case(name, file)
42
43
  end
@@ -79,6 +80,7 @@ module Turn
79
80
  #err = ''
80
81
 
81
82
  out, err = nil, nil
83
+ #p cmd
82
84
  Open3.popen3(cmd) do |stdin, stdout, stderr|
83
85
  stdin.close
84
86
  out = stdout.read.chomp
@@ -95,7 +97,8 @@ module Turn
95
97
  files = kase.files
96
98
 
97
99
  # remove any unexpected output injected at the beginning
98
- yaml = out[out.index(/^---/)..-1]
100
+ b = out.index(/^---/m)
101
+ yaml = out[b..-1]
99
102
  sub_suite = YAML.load(yaml)
100
103
 
101
104
  # TODO: How to handle pairs?
@@ -164,4 +167,3 @@ module Turn
164
167
  end#class IsoRunner
165
168
 
166
169
  end#module Turn
167
-
@@ -1,76 +1,66 @@
1
1
  require 'stringio'
2
2
 
3
- # Becuase of some wierdness in MiniTest
4
- debug, $DEBUG = $DEBUG, false
5
- require 'minitest/unit'
6
- $DEBUG = debug
7
-
8
- Test = MiniTest
3
+ # Because of some wierdness in MiniTest
4
+ #debug, $DEBUG = $DEBUG, false
5
+ #require 'minitest/unit'
6
+ #$DEBUG = debug
9
7
 
10
8
  module Turn
11
9
 
12
- # = MiniTest TestRunner
10
+ # Turn's MiniTest test runner class.
13
11
  #
14
12
  class MiniRunner < ::MiniTest::Unit
15
13
 
16
- # Override initialize to take controller argument.
17
- def initialize(controller)
18
- @turn_controller = controller
19
-
20
- controller.loadpath.each{ |path| $: << path } unless controller.live?
21
- controller.requires.each{ |path| require(path) }
22
-
23
- [controller.files].flatten.each{ |path| require(path) }
24
-
25
- files = [controller.files].flatten
26
- files.each{ |path| require(path) }
27
-
28
- # TODO: Better name ?
29
- @turn_suite_name = files.map{ |path| File.dirname(path).sub(Dir.pwd+'/','') }.uniq.join(',')
14
+ #
15
+ def initialize
16
+ @turn_config = Turn.config
30
17
 
31
- #sub_suites = []
32
- #ObjectSpace.each_object(Class) do |klass|
33
- # if(Test::Unit::TestCase > klass)
34
- # sub_suites << klass.suite
35
- # end
36
- #end
37
- #suite = Test::Unit::TestSuite.new('') # FIXME: Name?
38
- #sub_suites.sort_by{|s|s.name}.each{|s| suite << s}
39
-
40
- #suite.tests.each do |c|
41
- # pattern = controller.pattern
42
- # c.tests.reject! { |t| pattern !~ t.method_name }
43
- #end
18
+ super()
44
19
 
45
- @turn_logger = controller.reporter
20
+ # a stream we will use to route minitests traditional output
21
+ @out = ::StringIO.new
22
+ end
46
23
 
47
- super()
24
+ # route minitests traditional output to nowhere
25
+ def output
26
+ @out
27
+ end
48
28
 
49
- # route minitests traditional output to nowhere
50
- # (instead of overriding #puts and #print)
51
- @@out = ::StringIO.new
29
+ #
30
+ def turn_reporter
31
+ @turn_config.reporter
52
32
  end
53
33
 
54
34
  # Turn calls this method to start the test run.
55
35
  def start(args=[])
36
+ # minitest changed #run in 6023c879cf3d5169953e on April 6th, 2011
37
+ if ::MiniTest::Unit.respond_to?(:runner=)
38
+ ::MiniTest::Unit.runner = self
39
+ end
40
+ # FIXME: why isn't @test_count set?
56
41
  run(args)
57
42
  return @turn_suite
58
43
  end
59
44
 
60
45
  # Override #_run_suite to setup Turn.
61
46
  def _run_suites suites, type
62
- @turn_suite = Turn::TestSuite.new(@turn_suite_name)
63
- @turn_suite.size = ::MiniTest::Unit::TestCase.test_suites.size
47
+ # Someone want to explain to me why these are fucking here?
48
+ suites = suites - [MiniTest::Spec]
49
+ suites = suites - [Test::Unit::TestCase] if defined?(Test::Unit::TestCase)
50
+
51
+ @turn_suite = Turn::TestSuite.new(@turn_config.suite_name)
52
+ @turn_suite.size = suites.size #::MiniTest::Unit::TestCase.test_suites.size
53
+ @turn_suite.seed = ::MiniTest::Unit.runner.options[:seed]
64
54
 
65
- @turn_logger.start_suite(@turn_suite)
55
+ turn_reporter.start_suite(@turn_suite)
66
56
 
67
- if @turn_controller.matchcase
68
- suites = suites.select{ |suite| @turn_controller.matchcase =~ suite.name }
57
+ if @turn_config.matchcase
58
+ suites = suites.select{ |suite| @turn_config.matchcase =~ suite.name }
69
59
  end
70
60
 
71
61
  result = suites.map { |suite| _run_suite(suite, type) }
72
62
 
73
- @turn_logger.finish_suite(@turn_suite)
63
+ turn_reporter.finish_suite(@turn_suite)
74
64
 
75
65
  return result
76
66
  end
@@ -80,20 +70,20 @@ module Turn
80
70
  # suites are cases in minitest
81
71
  @turn_case = @turn_suite.new_case(suite.name)
82
72
 
83
- filter = @turn_controller.pattern || /./
73
+ filter = normalize_filter(@options[:filter]) || @turn_config.pattern || /./
84
74
 
85
- suite.send("#{type}_methods").grep(filter).each do |test|
75
+ suite.send("#{type}_methods").grep(/#{filter}/).each do |test|
86
76
  @turn_case.new_test(test)
87
77
  end
88
78
 
89
- @turn_logger.start_case(@turn_case)
79
+ turn_reporter.start_case(@turn_case)
90
80
 
91
81
  header = "#{type}_suite_header"
92
82
  puts send(header, suite) if respond_to? header
93
83
 
94
84
  assertions = @turn_case.tests.map do |test|
95
85
  @turn_test = test
96
- @turn_logger.start_test(@turn_test)
86
+ turn_reporter.start_test(@turn_test)
97
87
 
98
88
  inst = suite.new(test.name) #method
99
89
  inst._assertions = 0
@@ -101,17 +91,17 @@ module Turn
101
91
  result = inst.run self
102
92
 
103
93
  if result == "."
104
- @turn_logger.pass
94
+ turn_reporter.pass
105
95
  end
106
96
 
107
- @turn_logger.finish_test(@turn_test)
97
+ turn_reporter.finish_test(@turn_test)
108
98
 
109
99
  inst._assertions
110
100
  end
111
101
 
112
102
  @turn_case.count_assertions = assertions.inject(0) { |sum, n| sum + n }
113
103
 
114
- @turn_logger.finish_case(@turn_case)
104
+ turn_reporter.finish_case(@turn_case)
115
105
 
116
106
  return assertions.size, assertions.inject(0) { |sum, n| sum + n }
117
107
  end
@@ -120,44 +110,24 @@ module Turn
120
110
  def puke(klass, meth, err)
121
111
  case err
122
112
  when MiniTest::Skip
123
- @turn_test.skip!
124
- @turn_logger.skip #(e)
113
+ @turn_test.skip!(err)
114
+ turn_reporter.skip(err)
125
115
  when MiniTest::Assertion
126
116
  @turn_test.fail!(err)
127
- @turn_logger.fail(err)
117
+ turn_reporter.fail(err)
128
118
  else
129
119
  @turn_test.error!(err)
130
- @turn_logger.error(err)
120
+ turn_reporter.error(err)
131
121
  end
132
122
  super(klass, meth, err)
133
123
  end
134
124
 
135
- # To maintain compatibility with old versions of MiniTest.
136
- if ::MiniTest::Unit::VERSION < '2.0'
137
-
138
- #attr_accessor :options
139
-
140
- #
141
- def run(args=[])
142
- suites = ::MiniTest::Unit::TestCase.test_suites
143
- return if suites.empty?
144
-
145
- @test_count, @assertion_count = 0, 0
146
- sync = @@out.respond_to? :"sync=" # stupid emacs
147
- old_sync, @@out.sync = @@out.sync, true if sync
148
-
149
- results = _run_suites suites, :test #type
150
-
151
- @test_count = results.inject(0) { |sum, (tc, _)| sum + tc }
152
- @assertion_count = results.inject(0) { |sum, (_, ac)| sum + ac }
153
-
154
- @@out.sync = old_sync if sync
155
-
156
- return failures + errors if @test_count > 0 # or return nil...
157
- rescue Interrupt
158
- abort 'Interrupted'
159
- end
125
+ private
160
126
 
127
+ # regex gets turned into a string literal with leading/trailing slashes
128
+ # so remove them
129
+ def normalize_filter(filter)
130
+ filter.sub(/^(\/)/, '').sub(/(\/)$/, '') if filter
161
131
  end
162
132
 
163
133
  end
@@ -3,6 +3,5 @@ module Turn
3
3
 
4
4
  class SoloRunner < IsoRunner
5
5
  end
6
-
7
6
  end
8
7
 
@@ -14,22 +14,20 @@ end
14
14
 
15
15
  module Turn
16
16
 
17
- # = TestUnit TestRunner
17
+ # Turn's Test::Unit console test runner.
18
18
  #
19
19
  class TestRunner < ::Test::Unit::UI::Console::TestRunner
20
20
 
21
- def initialize(controller)
22
- output_level = 2 # 2-NORMAL 3-VERBOSE
21
+ #
22
+ def initialize(suite, output_level, stdout=$stdout)
23
+ turn_config = Turn.config
23
24
 
24
- controller.loadpath.each{ |path| $: << path } unless controller.live?
25
- controller.requires.each{ |path| require(path) }
25
+ #output_level = 2 # 2-NORMAL 3-VERBOSE
26
26
 
27
- files = [controller.files].flatten
28
- files.each{ |path| require(path) }
29
-
30
- # TODO: Better name ?
31
- name = files.map{ |path| File.dirname(path).sub(Dir.pwd+'/','') }.uniq.join(',')
27
+ name = turn_config.suite_name
32
28
 
29
+ # TODO: instead of building up a new suite, filter the suite
30
+ # passed into initialize.
33
31
  sub_suites = []
34
32
  ObjectSpace.each_object(Class) do |klass|
35
33
  if(Test::Unit::TestCase > klass)
@@ -38,8 +36,8 @@ module Turn
38
36
  end
39
37
  suite = Test::Unit::TestSuite.new(name)
40
38
 
41
- matchcase = controller.matchcase
42
- pattern = controller.pattern
39
+ matchcase = turn_config.matchcase
40
+ pattern = turn_config.pattern
43
41
 
44
42
  if matchcase
45
43
  sub_suites = sub_suites.select{|s| matchcase =~ s.name}
@@ -50,9 +48,9 @@ module Turn
50
48
  c.tests.reject!{ |t| pattern !~ t.method_name }
51
49
  end
52
50
 
53
- @t_reporter = controller.reporter
51
+ @t_reporter = turn_config.reporter
54
52
 
55
- super(suite, output_level, $stdout)
53
+ super(suite, output_level, stdout)
56
54
  end
57
55
 
58
56
  # Is this needed?
@@ -168,4 +166,3 @@ module Turn
168
166
  end#class TestRunner
169
167
 
170
168
  end#module Turn
171
-
@@ -0,0 +1,24 @@
1
+ module Turn
2
+
3
+ # For TestUnit 1.x, completely outdated.
4
+ def self.bootstrap_legacy(autorun=false)
5
+ require 'fileutils'
6
+
7
+ require 'turn/version'
8
+ require 'turn/autoload'
9
+ require 'turn/configuration'
10
+ require 'turn/colorize'
11
+ require 'turn/components'
12
+ require 'turn/controller'
13
+
14
+ require 'test/unit'
15
+ require 'turn/runners/testrunner'
16
+
17
+ # need to turn this off unless autorun mode
18
+ Test::Unit.run = autorun
19
+ end
20
+
21
+ end
22
+
23
+ Turn.bootstrap_legacy(true)
24
+
data/lib/turn/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Turn
2
- VERSION = "0.8.2"
2
+ VERSION = "0.9.7"
3
3
  end
data/lib/turn.rb CHANGED
@@ -1,19 +1,14 @@
1
1
  module Turn
2
- # Returns +true+ if the ruby version supports minitest.
3
- # Otherwise, +false+ is returned.
4
- def self.minitest?
5
- RUBY_VERSION >= '1.9'
6
- end
7
2
  end
8
3
 
9
- unless defined?(Turn::Command)
10
- if Turn.minitest?
11
- require 'turn/autorun/minitest'
12
- MiniTest::Unit.autorun
13
- else
14
- require 'turn/autorun/testunit'
15
- end
16
- #autoload :Test, 'turn/autorun/testunit'
17
- #autoload :MiniTest, 'turn/autorun/minitest'
18
- end
4
+ require 'fileutils'
5
+
6
+ require 'turn/version'
7
+ require 'turn/autoload'
8
+ require 'turn/configuration'
9
+ require 'turn/colorize'
10
+ require 'turn/components'
11
+ require 'turn/controller'
12
+ require 'turn/command'
13
+ require 'turn/minitest'
19
14
 
data/test/helper.rb CHANGED
@@ -1,19 +1,42 @@
1
+ $:.unshift './lib'
2
+
3
+ #require 'turn/colorize'
1
4
  require 'fileutils'
2
5
 
3
6
  if RUBY_VERSION < "1.9"
4
7
  require 'test/unit'
5
8
  else
9
+ gem 'minitest'
6
10
  require 'minitest/unit'
11
+ require 'test/unit'
7
12
  end
8
13
 
14
+ require 'turn'
15
+
16
+ #
17
+ #Turn.config.format = :pretty
18
+
9
19
  #
10
20
  def turn(*args)
11
- `ruby -Ilib bin/turn -Ilib #{args.join(' ')} 2>&1`
21
+ if RUBY_VERSION < '1.9'
22
+ `ruby1.8 -Ilib bin/turn -Ilib #{args.join(' ')} 2>&1`
23
+ else
24
+ `ruby -Ilib bin/turn -Ilib #{args.join(' ')} 2>&1`
25
+ end
12
26
  end
13
27
 
14
28
  #
15
29
  def turn2(*args)
16
- `ruby -Ilib bin/turn -Ilib #{args.join(' ')}`
30
+ if RUBY_VERSION < '1.9'
31
+ `ruby1.8 -Ilib bin/turn -Ilib #{args.join(' ')}`
32
+ else
33
+ `ruby -Ilib bin/turn -Ilib #{args.join(' ')}`
34
+ end
35
+ end
36
+
37
+ #
38
+ def turn_with_term(term, *args)
39
+ `TERM="#{term}" ruby -Ilib bin/turn -Ilib #{args.join(' ')} 2>&1`
17
40
  end
18
41
 
19
42
  #
@@ -30,10 +53,24 @@ end
30
53
  save_test(text, name)
31
54
  end
32
55
 
56
+ #
57
+ def setup_testunit(required=false, name=nil)
58
+ text = ''
59
+ text << "require '#{required}'\n" if required
60
+ text << <<-HERE
61
+ class TestTest < Test::Unit::TestCase
62
+ #{standard_test_body}
63
+ end
64
+ HERE
65
+ #name = framwwork.downcase
66
+ #name = name + '_required' if requires
67
+ save_test(text, name)
68
+ end
69
+
33
70
  #
34
71
  def save_test(text, name=nil)
35
72
  file = File.join('tmp', name || 'test.rb')
36
- FileUtils.mkdir_p('tmp')
73
+ FileUtils.mkdir_p('tmp') unless File.directory?('tmp')
37
74
  File.open(file, 'w'){ |f| f << text }
38
75
  return file
39
76
  end
@@ -65,7 +102,7 @@ HERE
65
102
  end
66
103
 
67
104
  #
68
- def setup_outline_test
105
+ def setup_testunit_outline
69
106
  text = <<-HERE
70
107
  class OutlineTest < Test::Unit::TestCase
71
108
  def test_sample_pass
@@ -81,11 +118,31 @@ end
81
118
  save_test(text, 'outline_test.rb')
82
119
  end
83
120
 
121
+ def setup_minispec
122
+ text = <<-HERE
123
+ require 'turn'
124
+ require 'minitest/autorun'
125
+
126
+ describe 'multiple tests' do
127
+ it 'should pass' do
128
+ assert true
129
+ end
130
+
131
+ it 'should fail' do
132
+ assert false
133
+ end
134
+ end
135
+ HERE
136
+ save_test(text, 'minispec_test.rb')
137
+ end
138
+
84
139
  #
85
140
  def setup_minitest_autorun
86
141
  text = <<-HERE
87
- require 'minitest/unit'
142
+ require 'turn'
143
+ MiniTest::Unit.runner = Turn::MiniRunner.new
88
144
  MiniTest::Unit.autorun
145
+ #require 'minitest/unit'
89
146
  class TestTest < MiniTest::Unit::TestCase
90
147
  def test_sample_pass
91
148
  assert_equal(1,1)
@@ -95,3 +152,22 @@ end
95
152
  save_test(text, 'minitest_autorun_test.rb')
96
153
  end
97
154
 
155
+
156
+ def setup_minitest_autorun_with_trace
157
+ text = <<-HERE
158
+ #require 'minitest/unit'
159
+ #require 'rubygems'
160
+ require 'turn'
161
+ MiniTest::Unit.runner = Turn::MiniRunner.new
162
+ MiniTest::Unit.autorun
163
+ Turn.config do |c|
164
+ c.trace = 1
165
+ end
166
+ class TestTest < MiniTest::Unit::TestCase
167
+ def test_sample_pass
168
+ assert_equal(0,1)
169
+ end
170
+ end
171
+ HERE
172
+ save_test(text, 'minitest_autorun_test_with_fail.rb')
173
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.dirname(__FILE__)) + '/helper.rb'
2
+ require File.expand_path(File.dirname(__FILE__) + '/..') + '/lib/turn/reporter'
3
+
4
+ class TestReporter < Turn::Reporter
5
+ end
6
+
7
+ class TestReporters < Test::Unit::TestCase
8
+ def test_unit_test_files_are_not_filtered_out_if_ending_in_test
9
+ reporter = TestReporter.new(nil)
10
+
11
+ # If you follow the convention of naming your test files with _test.rb, do not filter that
12
+ # test file from the stack trace
13
+ filtered_lines = ["/Users/testman/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/test/unit/assertions.rb:185:in `assert_equal'"]
14
+ unfiltered_lines = ["/Users/testman/source/campaign_manager/test/unit/omg_test.rb:145:in `block in <class:OmgTest>'",
15
+ "/Users/testman/source/campaign_manager/app/models/omg.rb:145:in `in double_rainbows'" ]
16
+ stack_trace = filtered_lines + unfiltered_lines
17
+
18
+ assert_equal unfiltered_lines, reporter.send(:filter_backtrace, stack_trace)
19
+ end
20
+
21
+ def test_unit_test_files_are_not_filtered_out_if_file_name_starts_with_test_underscore
22
+ reporter = TestReporter.new(nil)
23
+
24
+ # If you follow the convention of naming your test files with _test.rb, do not filter that
25
+ # test file from the stack trace
26
+ filtered_lines = ["/Users/testman/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/test/unit/assertions.rb:185:in `assert_equal'"]
27
+ unfiltered_lines = ["/Users/testman/source/campaign_manager/test/unit/test_omgs.rb:145:in `block in <class:OmgTest>'",
28
+ "/Users/testman/source/campaign_manager/app/models/omg.rb:145:in `in double_rainbows'" ]
29
+ stack_trace = filtered_lines + unfiltered_lines
30
+
31
+ assert_equal unfiltered_lines, reporter.send(:filter_backtrace, stack_trace)
32
+ end
33
+
34
+
35
+ end