lineman 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.
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ `lineman` is a test runner for
2
+ [test-unit](https://github.com/test-unit/test-unit) that prints a line per test,
3
+ with statistics about its performance.
4
+
5
+ Example output:
6
+
7
+ NPCRobotTest
8
+ test: should have a cool nickname 0:1 0.01 N
9
+ test: should have big birthday party 1:1 0.00
10
+ test: should have pizzas for party 0:0 0.00 ON
11
+ test: should not dance 0:0 0.00 P
12
+ NPCRobotTest 1:2 0.01 PON
13
+ test/npc_robot_test 1:2 0.01 PON
14
+
15
+ ========
16
+ Failures
17
+ ========
18
+
19
+ 1) Failure:
20
+ test: should have a cool nickname(NPCRobotTest) [test/npc_robot_test.rb:30]:
21
+ <"claptrap"> expected but was
22
+ <"Claptrap">.
23
+
24
+ diff:
25
+ - claptrap
26
+ ? ^
27
+ + Claptrap
28
+ ? ^
29
+
30
+ 2) Failure:
31
+ test: should have big birthday party(NPCRobotTest) [test/npc_robot_test.rb:14]:
32
+ Pending block should not be passed: acquaintances != friends.
33
+
34
+
35
+ =========
36
+ Omissions
37
+ =========
38
+
39
+ 1) Omission: I am not sure what a pizza is
40
+ test: should have pizzas for party(NPCRobotTest)
41
+ test/npc_robot_test.rb:43:in `block in <class:NPCRobotTest>'
42
+
43
+
44
+ ========
45
+ Pendings
46
+ ========
47
+
48
+ 1) Pending: pended.
49
+ test: should not dance(NPCRobotTest)
50
+ test/npc_robot_test.rb:23:in `block in <class:NPCRobotTest>'
51
+
52
+
53
+ =============
54
+ Notifications
55
+ =============
56
+
57
+ 1) Notification: Claptrap
58
+ test: should have a cool nickname(NPCRobotTest)
59
+ test/npc_robot_test.rb:29:in `block in <class:NPCRobotTest>'
60
+
61
+ 2) Notification: NPCRobotTest#test: should have pizzas for party was redefined
62
+ test: should have pizzas for party(NPCRobotTest)
63
+ test/npc_robot_test.rb:42:in `<class:NPCRobotTest>'
64
+ test/npc_robot_test.rb:10:in `<main>'
65
+
66
+
67
+
68
+ Finished in 0.013893
69
+ 4 tests, 3 assertions, 2 failures, 0 errors, 1 pendings, 1 omissions, 2 notifications
70
+
71
+ The characters P, O, and N that are reported in the last column map to calls to
72
+ `pend`, `omit`, and `notify` inside of the test. (These are part of test-unit).
73
+
74
+ Usage:
75
+
76
+ * put lineman in you bundle or otherwise install the gem
77
+ * `Test::Unit::AutoRunner.default_runner = 'lineman'`
78
+ * You could also specify --runner on the command line or your test-unit.yml
79
+ * Run your tests!
80
+
81
+ Make pull requests and be friendly.
82
+
@@ -0,0 +1,21 @@
1
+ require 'test/unit/ui/statistics/base_runner'
2
+
3
+
4
+ module Test::Unit # :nodoc:
5
+ class << self
6
+ def require_statistics_runners # :nodoc:
7
+ stat_dir = File.expand_path('../ui/statistics/runners',
8
+ File.dirname(__FILE__))
9
+ Dir["#{stat_dir}/*.rb"].each do |f|
10
+ require_relative "../ui/statistics/runners/#{File.basename(f)}"
11
+ end
12
+ end
13
+ end
14
+
15
+ require_statistics_runners
16
+ Test::Unit::UI::Statistics::BaseRunner.each_subclass do |subclass|
17
+ AutoRunner.register_runner(subclass.name) do |_auto_runner|
18
+ subclass
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,146 @@
1
+ require 'test/unit/ui/testrunner'
2
+ require 'test/unit/ui/testrunnermediator'
3
+ require_relative '../statistics'
4
+
5
+ module Test::Unit::UI::Statistics
6
+
7
+ # Inherit from this class to create a runner that has access to statistics.
8
+ #
9
+ # Implement any/all of the following callbacks in your subclass:
10
+ # * reset
11
+ # * started
12
+ # * finished
13
+ # * suite_started
14
+ # * suite_finished
15
+ # * case_started
16
+ # * case_finished
17
+ # * assertion
18
+ # * error
19
+ # * failure
20
+ # * pending
21
+ # * omission
22
+ # * notification
23
+ # * fault
24
+ #
25
+ class BaseRunner < Test::Unit::UI::TestRunner # :nodoc:
26
+
27
+ attr_accessor :result
28
+
29
+ # Case Statistics
30
+ def cstat
31
+ @method_metrics
32
+ end
33
+
34
+ # Suite Statistics
35
+ def sstat
36
+ @suite_stack.last
37
+ end
38
+
39
+ def self.inherited kls #:nodoc:
40
+ (@@subclasses ||= []) << kls
41
+ end
42
+
43
+ def self.each_subclass #:nodoc:
44
+ @@subclasses.each {|kls| yield kls }
45
+ end
46
+
47
+ def initialize suite, options={} #:nodoc:
48
+ super
49
+ @suite_stack = []
50
+ @output = options[:output] || STDOUT
51
+ end
52
+
53
+ # Inherited from TestRunner, sets up callbacks via i-var.
54
+ def attach_to_mediator #:nodoc:
55
+ @mediator.add_listener(Test::Unit::UI::TestRunnerMediator::RESET,
56
+ &callback(:reset))
57
+ @mediator.add_listener(Test::Unit::UI::TestRunnerMediator::STARTED,
58
+ &callback(:stats_started, :started))
59
+ @mediator.add_listener(Test::Unit::UI::TestRunnerMediator::FINISHED,
60
+ &callback(:finished))
61
+ @mediator.add_listener(Test::Unit::TestSuite::STARTED_OBJECT,
62
+ &callback(:stats_suite_started, :suite_started))
63
+ @mediator.add_listener(Test::Unit::TestSuite::FINISHED_OBJECT,
64
+ &callback(:suite_finished, :stats_suite_finished))
65
+ @mediator.add_listener(Test::Unit::TestCase::STARTED,
66
+ &callback(:stats_case_started, :case_started))
67
+ @mediator.add_listener(Test::Unit::TestCase::FINISHED,
68
+ &callback(:stats_case_finished, :case_finished))
69
+ @mediator.add_listener(Test::Unit::TestResult::PASS_ASSERTION,
70
+ &callback(:stats_assertion, :assertion))
71
+ @mediator.add_listener(Test::Unit::TestResult::FAULT,
72
+ &callback(:stats_fault, :fault))
73
+ end
74
+
75
+ # Forward to methods (in-order) that we might respond to.
76
+ def callback *types #:nodoc:
77
+ ->(*args) { types.select{|t| respond_to?(t) }.each{|t| send(t, *args) }}
78
+ end
79
+
80
+ def stats_started result #:nodoc:
81
+ @result = result
82
+ end
83
+
84
+ def stats_suite_started testsuite #:nodoc:
85
+ @suite_stack << SuiteStatistics.new(testsuite)
86
+ end
87
+
88
+ def stats_suite_finished testsuite #:nodoc:
89
+ @suite_stack.pop
90
+ end
91
+
92
+ def stats_case_started name #:nodoc:
93
+ @method_metrics = CaseStatistics.new(@result)
94
+ end
95
+
96
+ def stats_case_finished name #:nodoc:
97
+ @method_metrics.complete
98
+ update_suites_with_case_statistics
99
+ end
100
+
101
+ def stats_assertion testresult #:nodoc:
102
+ @method_metrics.pass += 1
103
+ end
104
+
105
+ def stats_fault fault #:nodoc:
106
+ base_type = fault.class.name.split('::').last.downcase
107
+ stat_method_name = "stats_handle_#{base_type}".to_sym
108
+ method_name = "#{base_type}".to_sym
109
+ send(stat_method_name, fault)
110
+ if respond_to?(method_name)
111
+ send(method_name, fault)
112
+ end
113
+ end
114
+
115
+ def stats_handle_error fault #:nodoc:
116
+ # Don't count errors before setup (i.e. in startup).
117
+ return unless @method_metrics
118
+ @method_metrics.errs += 1
119
+ end
120
+
121
+ def stats_handle_failure fault #:nodoc:
122
+ # The PASS_ASSERTION message just means it was run, we handle failures
123
+ @method_metrics.fail += 1
124
+ @method_metrics.pass -= 1
125
+ end
126
+
127
+ def stats_handle_pending fault #:nodoc:
128
+ @method_metrics.pend += 1
129
+ end
130
+
131
+ def stats_handle_omission fault #:nodoc:
132
+ @method_metrics.omit += 1
133
+ end
134
+
135
+ def stats_handle_notification fault #:nodoc:
136
+ @method_metrics.note += 1
137
+ end
138
+
139
+ def update_suites_with_case_statistics #:nodoc:
140
+ @suite_stack.each do |suite|
141
+ suite.add_test_case_statistics @method_metrics
142
+ end
143
+ end
144
+
145
+ end
146
+ end
@@ -0,0 +1,109 @@
1
+ require_relative '../base_runner'
2
+ #require 'test/unit/color-scheme'
3
+ #require 'test/unit/code-snippet-fetcher'
4
+ #require 'test/unit/diff'
5
+
6
+
7
+ module Test::Unit::UI::Statistics::Lineman
8
+ class TestRunner < Test::Unit::UI::Statistics::BaseRunner
9
+
10
+ def self.name
11
+ 'lineman'
12
+ end
13
+
14
+ # callback
15
+ def reset size
16
+ puts "Preparing to run #{size} tests"
17
+ end
18
+
19
+ # callback
20
+ def finished time
21
+ show_faults
22
+ puts "Finished in #{time.inspect}"
23
+ puts result.to_s
24
+ end
25
+
26
+ # callback
27
+ def suite_started testcase
28
+ puts "%-0.80s" % testcase
29
+ end
30
+
31
+ # callback
32
+ def suite_finished testcase
33
+ two_point_time = ("%.2f" % sstat.elapsed_time)
34
+ extended_actions = ''
35
+ extended_actions += (sstat.errs.nonzero? ? 'E' : ' ')
36
+ extended_actions += (sstat.pend.nonzero? ? 'P' : ' ')
37
+ extended_actions += (sstat.omit.nonzero? ? 'O' : ' ')
38
+ extended_actions += (sstat.note.nonzero? ? 'N' : ' ')
39
+ puts "%-50.50s %4.4s:%-4.4s %6.6s %s" % [testcase,
40
+ sstat.pass,
41
+ sstat.fail,
42
+ two_point_time,
43
+ extended_actions]
44
+ end
45
+
46
+ # callback
47
+ def case_started test_name
48
+ output_name = test_name.gsub(/\(#{sstat.test_suite.to_s}\)$/, '')
49
+ print " %-46.46s " % output_name
50
+ end
51
+
52
+ # callback
53
+ def case_finished test_name
54
+ two_point_time = ("%.2f" % cstat.elapsed_time)
55
+ if cstat.errs.nonzero?
56
+ err_or_pass_fail = 'ERROR'
57
+ else
58
+ err_or_pass_fail = '%4.4s:%-4.4s' % [cstat.pass,
59
+ cstat.fail]
60
+ end
61
+ extended_actions = ''
62
+ extended_actions += (cstat.pend.nonzero? ? 'P' : ' ')
63
+ extended_actions += (cstat.omit.nonzero? ? 'O' : ' ')
64
+ extended_actions += (cstat.note.nonzero? ? 'N' : ' ')
65
+ puts "%9.9s %6.6s %s" % [err_or_pass_fail, two_point_time,
66
+ extended_actions]
67
+ end
68
+
69
+ def show_faults
70
+ puts "\n"
71
+ order = [Test::Unit::Error, Test::Unit::Failure, Test::Unit::Omission,
72
+ Test::Unit::Pending, Test::Unit::Notification]
73
+ order.each do |type|
74
+ faults = result.faults.select {|f| f.is_a?(type) }
75
+ if faults.length.nonzero?
76
+ type_str = "#{type.to_s.split('::').last}s"
77
+ puts "=" * type_str.length
78
+ puts type_str
79
+ puts "=" * type_str.length
80
+ puts ''
81
+ max_width = faults.length.to_s.length
82
+ faults.each_with_index do |f,i|
83
+ puts " %#{max_width}i) %s\n" % [i+1, f.long_display]
84
+ puts ''
85
+ end
86
+ puts ''
87
+ end
88
+ end
89
+ puts "\n"
90
+ end
91
+
92
+ def fault_header_line num, fault
93
+ " %#{@exception_max_width}i) %s:" % [num, fault.label]
94
+ end
95
+
96
+ def fault_location_line fault
97
+ "#{fault.test_name} #{fault.location}:"
98
+ end
99
+
100
+ def fault_message fault
101
+ fault.message
102
+ end
103
+
104
+ def exception_backtrace fault
105
+ " " + fault.backtrace.join("\n ")
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,65 @@
1
+ module Test::Unit::UI::Statistics
2
+ class CaseStatistics
3
+ attr_accessor :pass
4
+ attr_accessor :fail
5
+ attr_accessor :errs
6
+ attr_accessor :pend
7
+ attr_accessor :omit
8
+ attr_accessor :note
9
+
10
+ def initialize results
11
+ self.pass = 0
12
+ self.fail = 0
13
+ self.errs = 0
14
+ self.pend = 0
15
+ self.omit = 0
16
+ self.note = 0
17
+ @start_time = Time.now
18
+ @end_time = nil
19
+ end
20
+
21
+ def elapsed_time
22
+ end_time - @start_time
23
+ end
24
+
25
+ def end_time
26
+ @end_time ? @end_time : Time.now
27
+ end
28
+
29
+ def complete
30
+ @end_time = Time.now
31
+ end
32
+ end
33
+
34
+
35
+ class SuiteStatistics
36
+ attr_reader :test_suite
37
+ attr_accessor :forward_class
38
+
39
+ def initialize test_suite
40
+ @test_suite = test_suite
41
+ @aggregate_statistics = []
42
+ end
43
+
44
+ def add_test_case_statistics stats
45
+ @aggregate_statistics << stats
46
+ end
47
+
48
+ def aggregate sym
49
+ @aggregate_statistics.inject(0) {|a,v| a + v.send(sym) }
50
+ end
51
+
52
+ def method_missing sym, *args
53
+ if respond_to?(sym)
54
+ aggregate(sym)
55
+ else
56
+ super
57
+ end
58
+ end
59
+
60
+ def respond_to? sym
61
+ Test::Unit::TestResult.instance_methods.include?(sym) or
62
+ CaseStatistics.instance_methods.include?(sym)
63
+ end
64
+ end
65
+ end
data/lineman.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'lineman'
3
+ s.version = '0.9.0'
4
+ s.date = '2012-10-07'
5
+
6
+ s.summary = 'A test runner (UI) for test-unit'
7
+ s.description = 'Lineman provides clean output for your tests, giving you one line for each test that shows the name along with some statistics.'
8
+
9
+ s.authors = ['Todd Willey (xtoddx)']
10
+ s.email = 'xtoddx@gmail.com'
11
+ s.homepage = 'http://github.com/xtoddx/lineman'
12
+
13
+ s.require_paths = %w[lib]
14
+
15
+ s.rdoc_options = ["--charset=UTF-8"]
16
+ s.extra_rdoc_files = %w[README.md]
17
+
18
+ s.add_dependency('test-unit', '~> 2.4')
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {spec,tests}/*`.split("\n")
22
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lineman
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Todd Willey (xtoddx)
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: test-unit
16
+ requirement: &70263140719340 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.4'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70263140719340
25
+ description: Lineman provides clean output for your tests, giving you one line for
26
+ each test that shows the name along with some statistics.
27
+ email: xtoddx@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files:
31
+ - README.md
32
+ files:
33
+ - README.md
34
+ - lib/test/unit/runner/statistics.rb
35
+ - lib/test/unit/ui/statistics.rb
36
+ - lib/test/unit/ui/statistics/base_runner.rb
37
+ - lib/test/unit/ui/statistics/runners/lineman.rb
38
+ - lineman.gemspec
39
+ homepage: http://github.com/xtoddx/lineman
40
+ licenses: []
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --charset=UTF-8
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 1.8.17
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: A test runner (UI) for test-unit
64
+ test_files: []
65
+ has_rdoc: