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,98 @@
1
+ module Turn
2
+
3
+ #
4
+ class TestCase
5
+
6
+ # Name of test case.
7
+ attr_accessor :name
8
+
9
+ # Test methods.
10
+ attr_accessor :tests
11
+
12
+ # Some runners marshal tests per file.
13
+ attr_accessor :files
14
+
15
+ #attr_accessor :count_passes
16
+ #attr_accessor :count_failures
17
+ #attr_accessor :count_errors
18
+ #attr_accessor :count_tests
19
+
20
+ # This can;t be calculated, so it must be
21
+ # assigned by the runner.
22
+ attr_accessor :count_assertions
23
+
24
+ # Holds dump of test output (optional depending on runner).
25
+ attr_accessor :message
26
+
27
+ # Command used to run test (optional depending on runner).
28
+ #attr_accessor :command
29
+
30
+ #
31
+ def initialize(name, *files)
32
+ @name = name
33
+ @files = (files.empty? ? [name] : files)
34
+ @tests = []
35
+
36
+ @message = nil
37
+ @count_assertions = 0
38
+
39
+ #@count_tests = 0
40
+ #@count_failures = 0
41
+ #@count_errors = 0
42
+
43
+ #@command = command
44
+ end
45
+
46
+ def new_test(name)
47
+ c = TestMethod.new(name)
48
+ @tests << c
49
+ c
50
+ end
51
+
52
+ # Whne used by a per-file runner.
53
+ #alias_method :file, :name
54
+
55
+ # Were there any errors?
56
+ def error?
57
+ count_errors != 0
58
+ end
59
+
60
+ # Were there any failures?
61
+ def fail?
62
+ count_failures != 0
63
+ end
64
+
65
+ # Did all tests/assertion pass?
66
+ def pass?
67
+ not(fail? or error?)
68
+ end
69
+
70
+ def count_tests
71
+ tests.size
72
+ end
73
+
74
+ def count_failures
75
+ sum = 0; tests.each{ |t| sum += 1 if t.fail? }; sum
76
+ end
77
+
78
+ def count_errors
79
+ sum = 0; tests.each{ |t| sum += 1 if t.error? }; sum
80
+ end
81
+
82
+ def count_passes
83
+ sum = 0; tests.each{ |t| sum += 1 if t.pass? }; sum
84
+ end
85
+
86
+ #
87
+ def counts
88
+ return count_tests, count_assertions, count_failures, count_errors
89
+ end
90
+
91
+ def message
92
+ tests.collect{ |t| t.message }.join("\n")
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+
@@ -0,0 +1,32 @@
1
+ module Turn
2
+
3
+ #
4
+ class TestMethod
5
+ attr_accessor :name
6
+ attr_accessor :file
7
+ attr_accessor :message
8
+
9
+ def initialize(name)
10
+ @name = name
11
+ @fail = false
12
+ @error = false
13
+ @message = nil
14
+ end
15
+
16
+ def fail!(message=nil)
17
+ @fail, @error = true, false
18
+ @message = message if message
19
+ end
20
+
21
+ def error!(message=nil)
22
+ @fail, @error = false, true
23
+ @message = message if message
24
+ end
25
+
26
+ def fail? ; @fail ; end
27
+ def error? ; @error ; end
28
+ def pass? ; !(@fail or @error) ; end
29
+ end
30
+
31
+ end
32
+
@@ -0,0 +1,82 @@
1
+ module Turn
2
+
3
+ #
4
+ class TestSuite
5
+
6
+ include Enumerable
7
+
8
+ attr_accessor :name
9
+ attr_accessor :size
10
+ attr_accessor :cases
11
+
12
+ # This one can be set manually since it
13
+ # is not calculatable (beyond the case level).
14
+ attr_accessor :count_assertions
15
+
16
+ #
17
+ def initialize(name=nil)
18
+ @name = name
19
+ @size = nil
20
+ @cases = []
21
+
22
+ #@count_tests = nil
23
+ #@count_assertions = nil
24
+ #@count_failures = nil
25
+ #@count_errors = nil
26
+ #@count_passes = nil
27
+ end
28
+
29
+ #
30
+ def new_case(name, *files)
31
+ c = TestCase.new(name, *files)
32
+ @cases << c
33
+ c
34
+ end
35
+
36
+ def count_failures
37
+ #@count_failures ||= (
38
+ sum = 0; each{ |c| sum += c.count_failures }; sum
39
+ #)
40
+ end
41
+
42
+ def count_errors
43
+ #@count_errors ||= (
44
+ sum = 0; each{ |c| sum += c.count_errors }; sum
45
+ #)
46
+ end
47
+
48
+ def count_passes
49
+ #@count_passes ||= (
50
+ sum = 0; each{ |c| sum += c.count_passes }; sum
51
+ #)
52
+ end
53
+
54
+ def count_tests
55
+ #@count_tests ||= (
56
+ sum = 0; each{ |c| sum += c.count_tests }; sum
57
+ #)
58
+ end
59
+
60
+ def count_assertions
61
+ #@count_assertions ||= (
62
+ sum = 0; each{ |c| sum += c.count_assertions }; sum
63
+ #)
64
+ end
65
+
66
+ # Convenience methods --this is what is typcially wanted.
67
+ def counts
68
+ return count_tests, count_assertions, count_failures, count_errors
69
+ end
70
+
71
+ def each(&block)
72
+ @cases.each(&block)
73
+ end
74
+
75
+ def size
76
+ @size ||= @cases.size
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+
@@ -0,0 +1,146 @@
1
+ require 'fileutils'
2
+
3
+ module Turn
4
+ require 'turn/components/suite.rb'
5
+ require 'turn/components/case.rb'
6
+ require 'turn/components/method.rb'
7
+
8
+ require 'turn/reporters/outline_reporter'
9
+ require 'turn/reporters/marshal_reporter'
10
+ require 'turn/reporters/progress_reporter'
11
+ require 'turn/reporters/dot_reporter'
12
+
13
+ require 'turn/runners/testrunner'
14
+ require 'turn/runners/solorunner'
15
+ require 'turn/runners/crossrunner'
16
+
17
+ # = Controller
18
+ #
19
+ #--
20
+ # TODO: Add support to test run loggging.
21
+ #++
22
+ class Controller
23
+
24
+ # File glob pattern of tests to run.
25
+ # Can be an array of files/globs.
26
+ attr_accessor :tests
27
+
28
+ # Files globs to specially exclude.
29
+ attr_accessor :exclude
30
+
31
+ # Add these folders to the $LOAD_PATH.
32
+ attr_accessor :loadpath
33
+
34
+ # Libs to require when running tests.
35
+ attr_accessor :requires
36
+
37
+ # Instance of Reporter.
38
+ attr_accessor :reporter
39
+
40
+ # Insatance of Runner.
41
+ attr_accessor :runner
42
+
43
+ # Test against live install (i.e. Don't use loadpath option)
44
+ attr_accessor :live
45
+
46
+ # Log results? May be true/false or log file name. (TODO)
47
+ attr_accessor :log
48
+
49
+ # Verbose output?
50
+ attr_accessor :verbose
51
+
52
+ def verbose? ; @verbose ; end
53
+ def live? ; @live ; end
54
+
55
+ private
56
+
57
+ def initialize
58
+ yield(self) if block_given?
59
+ initialize_defaults
60
+ end
61
+
62
+ #
63
+ def initialize_defaults
64
+ @loadpath ||= ['lib']
65
+ @tests ||= "test/**/{test,}*{,test}"
66
+ @exclude ||= []
67
+ @reqiures ||= []
68
+ @live ||= false
69
+ @log ||= true
70
+ @reporter ||= OutlineReporter.new($stdout)
71
+ @runner ||= TestRunner.new
72
+ end
73
+
74
+ # Collect test configuation.
75
+ #def test_configuration(options={})
76
+ # #options = configure_options(options, 'test')
77
+ # #options['loadpath'] ||= metadata.loadpath
78
+ # options['tests'] ||= self.tests
79
+ # options['loadpath'] ||= self.loadpath
80
+ # options['requires'] ||= self.requires
81
+ # options['live'] ||= self.live
82
+ # options['exclude'] ||= self.exclude
83
+ # #options['tests'] = list_option(options['tests'])
84
+ # options['loadpath'] = list_option(options['loadpath'])
85
+ # options['exclude'] = list_option(options['exclude'])
86
+ # options['require'] = list_option(options['require'])
87
+ # return options
88
+ #end
89
+
90
+ #
91
+ def list_option(list)
92
+ case list
93
+ when nil
94
+ []
95
+ when Array
96
+ list
97
+ else
98
+ list.split(/[:;]/)
99
+ end
100
+ end
101
+
102
+ public
103
+
104
+ def loadpath=(paths)
105
+ @loadpath = list_option(paths)
106
+ end
107
+
108
+ def exclude=(paths)
109
+ @exclude = list_option(paths)
110
+ end
111
+
112
+ def requries=(paths)
113
+ @requries = list_option(paths)
114
+ end
115
+
116
+ def files
117
+ @files ||= (
118
+ fs = tests.map do |t|
119
+ File.directory?(t) ? Dir[File.join(t, '**', '*')] : Dir[t]
120
+ end
121
+ fs = fs.flatten.reject{ |f| File.directory?(f) }
122
+ ex = exclude.map do |x|
123
+ File.directory?(x) ? Dir[File.join(x, '**', '*')] : Dir[x]
124
+ end
125
+ ex = ex.flatten.reject{ |f| File.directory?(f) }
126
+ (fs - ex).uniq
127
+ )
128
+ end
129
+
130
+ def start
131
+ @files = nil # reset files just in case
132
+
133
+ if files.empty?
134
+ $stderr.puts "No tests."
135
+ return
136
+ end
137
+
138
+ testrun = runner.new(self)
139
+
140
+ testrun.start
141
+ end
142
+
143
+ end
144
+
145
+ end
146
+
@@ -0,0 +1,56 @@
1
+ module Turn
2
+ require 'turn/colorize'
3
+
4
+ # = Reporter
5
+ #
6
+ # There are two distinct way in which a report may be utilized
7
+ # by a Runner: per-call or per-file. The method #pass, #fail
8
+ # and #error are generic, and will be used in either case.
9
+ # A per-call runner will use all the methods of a Reporter,
10
+ # while a per-file runner will use start_case per file,
11
+ # and will not use the start_test and finish_test methods,
12
+ # since those are beyond it's grainularity.
13
+ #
14
+ class Reporter
15
+
16
+ include Colorize
17
+
18
+ attr :io
19
+
20
+ def initialize(io)
21
+ @io = io || $stdout
22
+ end
23
+
24
+ # These methods are called in the process of running the tests.
25
+
26
+ def start_suite(suite)
27
+ end
28
+
29
+ def start_case(kase)
30
+ end
31
+
32
+ def start_test(test)
33
+ end
34
+
35
+ def pass(message=nil)
36
+ end
37
+
38
+ def fail(message=nil)
39
+ end
40
+
41
+ def error(message=nil)
42
+ end
43
+
44
+ def finish_test(test)
45
+ end
46
+
47
+ def finish_case(kase)
48
+ end
49
+
50
+ def finish_suite(suite)
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
@@ -0,0 +1,78 @@
1
+ require 'turn/reporter'
2
+
3
+ module Turn
4
+
5
+ # = Traditional Dot Reporter
6
+ #
7
+ class DotReporter < Reporter
8
+
9
+ def start_suite(suite)
10
+ @time = Time.now
11
+ io.puts "Loaded suite #{suite.name}"
12
+ io.puts "Started"
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
+ io.print '.'; io.flush
23
+ end
24
+
25
+ def fail(message=nil)
26
+ io.print 'F'; io.flush
27
+ end
28
+
29
+ def error(message=nil)
30
+ io.print 'E'; io.flush
31
+ end
32
+
33
+ def finish_test(test)
34
+ end
35
+
36
+ def finish_case(kase)
37
+ end
38
+
39
+ def finish_suite(suite)
40
+ io.puts("\nFinished in %.5f seconds." % [Time.now - @time])
41
+ io.puts
42
+
43
+ report = ''
44
+
45
+ fails = suite.select do |testrun|
46
+ testrun.fail? || testrun.error?
47
+ end
48
+
49
+ unless fails.empty? # or verbose?
50
+ #report << "\n\n-- Failures and Errors --\n\n"
51
+ fails.uniq.each do |testrun|
52
+ message = testrun.message.tabto(0)
53
+ message = ::ANSICode.magenta(message) if COLORIZE
54
+ report << message << "\n"
55
+ end
56
+ report << "\n"
57
+ end
58
+
59
+ io.puts report
60
+
61
+ io.puts "%s tests, %s assetions, %s failures, %s errors" % test_tally(suite)
62
+ end
63
+
64
+ private
65
+
66
+ def test_tally(suite)
67
+ counts = suite.collect{ |tr| tr.counts }
68
+ tally = [0,0,0,0]
69
+ counts.each do |count|
70
+ 4.times{ |i| tally[i] += count[i] }
71
+ end
72
+ return tally
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+