TwP-turn 0.5.1

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,64 @@
1
+ require 'yaml'
2
+
3
+ module Turn
4
+ require 'turn/reporter'
5
+
6
+ # = Marshal Reporter
7
+ #
8
+ class MarshalReporter < Reporter
9
+
10
+ #def start_suite(suite)
11
+ # #@suite = suite
12
+ # #@time = Time.now
13
+ # #files = suite.collect{ |s| s.file }.join(' ')
14
+ # #io.puts "Loaded suite #{suite.name}"
15
+ # #io.puts "Started"
16
+ #end
17
+
18
+ #def start_test(test)
19
+ # #if @file != test.file
20
+ # # @file = test.file
21
+ # # io.puts(test.file)
22
+ # #end
23
+ # io.print " %-69s" % test.name
24
+ #end
25
+
26
+ #def start_case(kase)
27
+ # io.puts(kase.name)
28
+ #end
29
+
30
+ #def pass(message=nil)
31
+ # io.puts " #{PASS}"
32
+ # if message
33
+ # message = ::ANSICode.magenta(message) if COLORIZE
34
+ # io.puts(message.to_s)
35
+ # end
36
+ #end
37
+
38
+ #def fail(message=nil)
39
+ # io.puts(" #{FAIL}")
40
+ # if message
41
+ # message = ::ANSICode.magenta(message) if COLORIZE
42
+ # io.puts(message.to_s)
43
+ # end
44
+ #end
45
+
46
+ #def error(message=nil)
47
+ # io.puts("#{ERROR}")
48
+ # io.puts(message.to_s) if message
49
+ #end
50
+
51
+ #def finish_test(test)
52
+ #end
53
+
54
+ #def finish_case(kase)
55
+ #end
56
+
57
+ def finish_suite(suite)
58
+ $stdout << suite.to_yaml
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
@@ -0,0 +1,85 @@
1
+ require 'turn/reporter'
2
+
3
+ module Turn
4
+
5
+ # = Outline Reporter (Turn's Original)
6
+ #
7
+ #--
8
+ # TODO: Should we fit reporter output to width of console?
9
+ # TODO: Running percentages?
10
+ #++
11
+ class OutlineReporter < Reporter
12
+
13
+ def start_suite(suite)
14
+ @suite = suite
15
+ @time = Time.now
16
+ #files = suite.collect{ |s| s.file }.join(' ')
17
+ io.puts "Loaded suite #{suite.name}"
18
+ #io.puts "Started"
19
+ end
20
+
21
+ def start_case(kase)
22
+ io.puts(kase.name)
23
+ end
24
+
25
+ def start_test(test)
26
+ #if @file != test.file
27
+ # @file = test.file
28
+ # io.puts(test.file)
29
+ #end
30
+ io.print " %-69s" % test.name
31
+ end
32
+
33
+ def pass(message=nil)
34
+ io.puts " #{PASS}"
35
+ if message
36
+ message = ::ANSICode.magenta(message) if COLORIZE
37
+ message = message.to_s.tabto(8)
38
+ io.puts(message)
39
+ end
40
+ end
41
+
42
+ def fail(message=nil)
43
+ io.puts(" #{FAIL}")
44
+ if message
45
+ message = ::ANSICode.magenta(message) if COLORIZE
46
+ message = message.to_s.tabto(8)
47
+ io.puts(message)
48
+ end
49
+ end
50
+
51
+ def error(message=nil)
52
+ io.puts("#{ERROR}")
53
+ io.puts(message.to_s) if message
54
+ end
55
+
56
+ def finish_test(test)
57
+ end
58
+
59
+ #def finish_case(kase)
60
+ #end
61
+
62
+ def finish_suite(suite)
63
+ total = suite.count_tests
64
+ failure = suite.count_failures
65
+ error = suite.count_errors
66
+ pass = total - failure - error
67
+
68
+ bar = '=' * 78
69
+ if COLORIZE
70
+ bar = if pass == total then ::ANSICode.green bar
71
+ else ::ANSICode.red bar end
72
+ end
73
+
74
+ tally = [total, suite.count_assertions]
75
+
76
+ io.puts bar
77
+ io.puts " pass: %d, fail: %d, error: %d" % [pass, failure, error]
78
+ io.puts " total: %d tests with %d assertions in #{Time.new - @time} seconds" % tally
79
+ io.puts bar
80
+ end
81
+
82
+ end
83
+
84
+ end
85
+
@@ -0,0 +1,117 @@
1
+ require 'turn/reporter'
2
+ require 'facets/progressbar'
3
+ require 'facets/string/tab'
4
+
5
+ module Turn
6
+
7
+ #
8
+ class ProgressReporter < Reporter
9
+
10
+ def start_suite(suite)
11
+ @pbar = ::ProgressBar.new('Testing', suite.size)
12
+ @pbar.inc
13
+ end
14
+
15
+ #def start_case(kase)
16
+ #end
17
+
18
+ #def start_test(test)
19
+ #end
20
+
21
+ #def pass(message=nil)
22
+ # #@pbar.inc
23
+ #end
24
+
25
+ #def fail(message=nil)
26
+ # #@pbar.inc
27
+ #end
28
+
29
+ #def error(message=nil)
30
+ # #@pbar.inc
31
+ #end
32
+
33
+ def finish_case(kase)
34
+ @pbar.inc
35
+ end
36
+
37
+ def finish_suite(suite)
38
+ @pbar.finish
39
+ post_report(suite)
40
+ end
41
+
42
+ #
43
+ def post_report(suite)
44
+ tally = test_tally(suite)
45
+
46
+ width = suite.collect{ |tr| tr.name.size }.max
47
+
48
+ headers = [ 'TESTCASE ', ' TESTS ', 'ASSERTIONS', ' FAILURES ', ' ERRORS ' ]
49
+ io.puts "\n%-#{width}s %10s %10s %10s %10s\n" % headers
50
+
51
+ files = nil
52
+
53
+ suite.each do |testrun|
54
+ if testrun.files != [testrun.name] && testrun.files != files
55
+ label = testrun.files.join(' ')
56
+ label = ::ANSICode.magenta(label) if COLORIZE
57
+ io.puts(label + "\n")
58
+ files = testrun.files
59
+ end
60
+ io.puts paint_line(testrun, width)
61
+ end
62
+
63
+ #puts("\n%i tests, %i assertions, %i failures, %i errors\n\n" % tally)
64
+
65
+ tally_line = "-----\n"
66
+ tally_line << "%-#{width}s " % "TOTAL"
67
+ tally_line << "%10s %10s %10s %10s" % tally
68
+
69
+ io.puts(tally_line + "\n")
70
+
71
+ fails = suite.select do |testrun|
72
+ testrun.fail? || testrun.error?
73
+ end
74
+
75
+ #if tally[2] != 0 or tally[3] != 0
76
+ unless fails.empty? # or verbose?
77
+ io.puts "\n\n-- Failures and Errors --\n\n"
78
+ fails.uniq.each do |testrun|
79
+ message = testrun.message.tabto(0).strip
80
+ message = ::ANSICode.red(message) if COLORIZE
81
+ io.puts(message+"\n\n")
82
+ end
83
+ io.puts
84
+ end
85
+ #end
86
+ end
87
+
88
+ private
89
+
90
+ def paint_line(testrun, width)
91
+ line = ''
92
+ line << "%-#{width}s " % [testrun.name]
93
+ line << "%10s %10s %10s %10s" % testrun.counts
94
+ line << " " * 8
95
+ if testrun.fail?
96
+ line << "[#{FAIL}]"
97
+ elsif testrun.error?
98
+ line << "[#{FAIL}]"
99
+ else
100
+ line << "[#{PASS}]"
101
+ end
102
+ line
103
+ end
104
+
105
+ def test_tally(suite)
106
+ counts = suite.collect{ |tr| tr.counts }
107
+ tally = [0,0,0,0]
108
+ counts.each do |count|
109
+ 4.times{ |i| tally[i] += count[i] }
110
+ end
111
+ return tally
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+
@@ -0,0 +1,40 @@
1
+ module Turn
2
+ require 'turn/runners/isorunner'
3
+
4
+ # = Cross Runner
5
+ #
6
+ # Cross Runner runs test in pairs.
7
+ #
8
+ # TODO: This needs work in the test_loop_runner.
9
+ # It needs to show the files being cross tested.
10
+ #
11
+ # TODO: Cross runner output needs to be fixed
12
+ class CrossRunner < IsoRunner
13
+
14
+ #
15
+ def start
16
+ suite = TestSuite.new
17
+
18
+ files = @controller.files
19
+ viles = @controller.files # TODO: viles this selectable
20
+
21
+ #files = files.select{ |f| File.extname(f) == '.rb' and File.file?(f) }
22
+ #viles = viles.select{ |f| File.extname(f) == '.rb' and File.file?(f) }
23
+
24
+ max = (files+viles).collect{ |f| f.size }.max
25
+
26
+ pairs = files.inject([]){ |m, f| viles.collect{ |v| m << [f,v] }; m }
27
+ pairs = pairs.reject{ |f,v| f == v }
28
+
29
+ testruns = pairs.collect do |file, versus|
30
+ name = "%-#{max}s %-#{max}s" % [file, versus]
31
+ suite.new_case(name, file, versus)
32
+ end
33
+
34
+ test_loop_runner(suite)
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
@@ -0,0 +1,129 @@
1
+ module Turn
2
+ require 'turn/colorize'
3
+
4
+ # = IsoRunner
5
+ #
6
+ # Iso Runner provides means from running unit test
7
+ # in isolated processes. It can do this either by running
8
+ # each test in isolation (solo testing) or in pairs (cross testing).
9
+ #
10
+ # The IsoRunner proiveds some variery in ouput formats and can also
11
+ # log results to a file.
12
+ #
13
+ class IsoRunner
14
+ include Turn::Colorize
15
+
16
+ attr :reporter
17
+
18
+ private
19
+
20
+ def initialize(controller)
21
+ @controller = controller
22
+ @reporter = controller.reporter
23
+ #yield(self) if block_given?
24
+ @loadpath = controller.loadpath
25
+ @requires = controller.requires
26
+ @live = controller.live?
27
+ end
28
+
29
+ public
30
+
31
+ # Runs the list of test calls passed to it.
32
+ # This is used by #test_solo and #test_cross.
33
+ #
34
+ def start
35
+ suite = TestSuite.new
36
+ testruns = @controller.files.collect do |file|
37
+ suite.new_case(file)
38
+ end
39
+ test_loop_runner(suite)
40
+ end
41
+
42
+ private
43
+
44
+ # The IsoRunner actually shells out to turn in
45
+ # manifest mode, to gather results from isolated
46
+ # runs.
47
+ def test_loop_runner(suite)
48
+ reporter.start_suite(suite)
49
+
50
+ recase = []
51
+
52
+ suite.each_with_index do |kase, index|
53
+ reporter.start_case(kase)
54
+
55
+ # FRACKING GENIUS RIGHT HERE !!!!!!!!!!!!
56
+ cmd = []
57
+ cmd << %[turn]
58
+ cmd << %[--marshal]
59
+ cmd << %[--loadpath="#{@loadpath.join(';')}"] unless @loadpath.empty?
60
+ cmd << %[--requires="#{@requires.join(';')}"] unless @requires.empty?
61
+ cmd << %[--live] if @live
62
+ cmd << %[#{kase.files.join(' ')}]
63
+ cmd = cmd.join(' ')
64
+ result = `#{cmd}`
65
+
66
+ files = kase.files
67
+
68
+ head, yaml = *result.split('---')
69
+ sub_suite = YAML.load(yaml)
70
+
71
+ # TODO: How to handle pairs?
72
+ #name = kase.name
73
+ kases = sub_suite.cases
74
+ suite.cases[index] = kases
75
+
76
+ kases.each do |kase|
77
+ kase.files = files
78
+ #reporter.start_case(kase)
79
+ kase.tests.each do |test|
80
+ reporter.start_test(test)
81
+ if test.error?
82
+ reporter.error(test.message)
83
+ elsif test.fail?
84
+ reporter.fail(test.message)
85
+ else
86
+ reporter.pass
87
+ end
88
+ reporter.finish_test(test)
89
+ end
90
+ reporter.finish_case(kase)
91
+ end
92
+ end
93
+
94
+ suite.cases.flatten!
95
+
96
+ reporter.finish_suite(suite)
97
+
98
+ # shutdown test/unit auto runner if test/unit is loaded.
99
+ ::Test::Unit.run=true rescue nil
100
+ end
101
+
102
+ #
103
+ #def test_parse_result(result)
104
+ # if md = /(\d+) tests, (\d+) assertions, (\d+) failures, (\d+) errors/.match(result)
105
+ # count = md[1..4].collect{|q| q.to_i}
106
+ # else
107
+ # count = [1, 0, 0, 1] # SHOULD NEVER HAPPEN
108
+ # end
109
+ # return count
110
+ #end
111
+
112
+ # NOT USED YET.
113
+ def log_report(report)
114
+ if log #&& !dryrun?
115
+ #logfile = File.join('log', apply_naming_policy('testlog', 'txt'))
116
+ FileUtils.mkdir_p('log')
117
+ logfile = File.join('log', 'testlog.txt')
118
+ File.open(logfile, 'a') do |f|
119
+ f << "= #{self.class} Test @ #{Time.now}\n"
120
+ f << report
121
+ f << "\n"
122
+ end
123
+ end
124
+ end
125
+
126
+ end#class IsoRunner
127
+
128
+ end#module Turn
129
+
@@ -0,0 +1,48 @@
1
+ # TODO
2
+
3
+ # Load each test independently to ensure there are no
4
+ # require dependency issues. This is actually a bit redundant
5
+ # as test-solo will also cover these results. So we may deprecate
6
+ # this in the future. This does not generate a test log entry.
7
+
8
+ def test_load(options={})
9
+ options = test_configuration(options)
10
+
11
+ tests = options['tests']
12
+ loadpath = options['loadpath']
13
+ requires = options['requires']
14
+ live = options['live']
15
+ exclude = options['exclude']
16
+
17
+ files = Dir.multiglob_r(*tests) - Dir.multiglob_r(*exclude)
18
+
19
+ return puts("No tests.") if files.empty?
20
+
21
+ max = files.collect{ |f| f.size }.max
22
+ list = []
23
+
24
+ files.each do |f|
25
+ next unless File.file?(f)
26
+ if r = system("ruby -I#{loadpath.join(':')} #{f} > /dev/null 2>&1")
27
+ puts "%-#{max}s [PASS]" % [f] #if verbose?
28
+ else
29
+ puts "%-#{max}s [FAIL]" % [f] #if verbose?
30
+ list << f
31
+ end
32
+ end
33
+
34
+ puts " #{list.size} Load Failures"
35
+
36
+ if verbose?
37
+ unless list.empty?
38
+ puts "\n-- Load Failures --\n"
39
+ list.each do |f|
40
+ print "* "
41
+ system "ruby -I#{loadpath} #{f} 2>&1"
42
+ #puts
43
+ end
44
+ puts
45
+ end
46
+ end
47
+ end
48
+