pretty_test 0.2.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1058954e3aebf342c2c9480ae7306396166d7c78
4
- data.tar.gz: e7863d4ffb02afa46f23b60a863babb2527bb35f
3
+ metadata.gz: 99fcfccadd470fa6e50f1fe9947fd4ceaa42a646
4
+ data.tar.gz: 6f8cc428dde9fdea68dd75fea69262074f263b4c
5
5
  SHA512:
6
- metadata.gz: 7fb1e1e7a078a7097f29e764c06f1d40aa4a983cdc03c2849ac0208fe0520f1feaf8c5d562292db409fa4d0008382667114ed65ffac958de66e16a3feddad576
7
- data.tar.gz: a3dcd9c4f545e06645c29eae15604bff1a258edac7ee60e96395886531567aa72574c7e6f408a3869c22cd466417dafcf6c62fe2b5c6bc0aa5516e9e4a1dd0f6
6
+ metadata.gz: 26cf7172794a146c034e151639db6f193518d735ef329e432527966a38244aef64f401fff3cc60191436c5d6e398df1b717bfd108b2de25c78122d3854ae816c
7
+ data.tar.gz: 6e45fa16eafc958c076a3059eb29fca0678dc9329ce14798d8fdac03bae15ad44dfd9d02650c8c9088392ffcc735822d0da589f71d63db6c8d9e638fa89c057e
data/lib/pretty_test.rb CHANGED
@@ -1,3 +1,3 @@
1
- require "pretty_test/runner"
2
-
3
- MiniTest::Unit.runner = PrettyTest::Runner.new if STDOUT.tty?
1
+ if STDOUT.tty?
2
+ require "pretty_test/reporter"
3
+ end
@@ -0,0 +1,145 @@
1
+ require "minitest"
2
+
3
+ module Minitest
4
+
5
+ class ProgressReporter
6
+
7
+ SKIP_FORMAT = "\e[33m[SKIPPED] %s\e[0m\n%s\n%s"
8
+ FAILURE_FORMAT = "\e[31m[FAILURE] %s\e[0m\n\e[31m%s: %s\e[0m\n%s"
9
+ ERROR_FORMAT = "\e[31m[ERROR] %s\e[0m\n\e[31m%s: %s\e[0m\n%s"
10
+ STATUS_FORMAT = "\e[2K\r\e[?7l\e[37m(%.1fs) \e[32m%d/%d tests (%d%%)\e[37m, \e[36m%d assertions\e[37m, \e[31m%d errors\e[37m, \e[31m%d failures\e[37m, \e[33m%d skips\e[?7h\e[0m"
11
+
12
+ attr_accessor :started_at, :tests, :assertions, :completed, :failures, :errors, :skips
13
+
14
+ def initialize(io = $stdout, options = {})
15
+ super
16
+
17
+ self.started_at = nil
18
+ self.completed = 0
19
+ self.assertions = 0
20
+ self.failures = 0
21
+ self.errors = 0
22
+ self.skips = 0
23
+ end
24
+
25
+ def start
26
+ self.started_at = Time.now
27
+ suites = ::Minitest::Runnable.runnables
28
+ self.tests = 0
29
+ suites.each do |suite|
30
+ self.tests += suite.runnable_methods.count
31
+ end
32
+ end
33
+
34
+ def record(result)
35
+ super
36
+ test_name = "#{result.class.name}##{result.name}"
37
+ @completed += 1
38
+ @assertions += result.assertions
39
+ case exception = result.failure
40
+ when nil then pass
41
+ when ::MiniTest::Skip then skip(test_name, exception)
42
+ when ::MiniTest::Assertion then failure(test_name, exception)
43
+ else error(test_name, exception)
44
+ end
45
+ update_status
46
+ end
47
+
48
+ def report
49
+ if tests > 0
50
+ update_status
51
+ end
52
+ if errors + failures == 0
53
+ io.puts " \e[32m----- PASSED! -----\e[0m"
54
+ else
55
+ io.puts " \e[31m----- FAILED! -----\e[0m"
56
+ end
57
+ end
58
+
59
+ def passed?
60
+ true
61
+ end
62
+
63
+ def pass
64
+ end
65
+
66
+ def skip(test_name, exception)
67
+ self.skips += 1
68
+ location = pretty_location(exception)
69
+ message = exception.message.strip
70
+ print_error SKIP_FORMAT, test_name, message, location
71
+ end
72
+
73
+ def failure(test_name, exception)
74
+ self.failures += 1
75
+ index = find_assertion_index(exception)
76
+ trace = pretty_trace(exception, index)
77
+ print_error FAILURE_FORMAT, test_name, exception.class, exception.message, trace
78
+ end
79
+
80
+ def error(test_name, exception)
81
+ self.errors += 1
82
+ index = find_exception_index(exception)
83
+ trace = pretty_trace(exception, index)
84
+ print_error ERROR_FORMAT, test_name, exception.class, exception.message, trace
85
+ end
86
+
87
+ def pretty_location(e)
88
+ path, line = location(e)
89
+ clean_trace_line("\e[1m-> ", path, line)
90
+ end
91
+
92
+ def find_assertion_index(error)
93
+ index = error.backtrace.rindex { |trace| trace =~ /:in .(assert|refute|flunk|pass|fail|raise|must|wont)/ }
94
+ index ? index + 1 : find_exception_index(error)
95
+ end
96
+
97
+ def find_exception_index(error)
98
+ error.backtrace.index { |trace| trace.index(Dir.pwd) }
99
+ end
100
+
101
+ def pretty_trace(error, location_index)
102
+ lines = []
103
+ backtrace = error.backtrace
104
+ entry_point = backtrace.reverse.detect { |trace| trace.starts_with?(Dir.pwd) }
105
+ backtrace.each_with_index do |trace, index|
106
+ prefix = index == location_index ? "\e[1m-> " : " "
107
+ trace_file, trace_line, trace_method = trace.split(":", 3)
108
+ lines << clean_trace_line(prefix, trace_file, trace_line, trace_method)
109
+ break if trace == entry_point
110
+ end
111
+ lines.compact.join("\n")
112
+ end
113
+
114
+ def clean_trace_line(prefix, path, line, method = nil)
115
+ case path
116
+ when %r{^#{Dir.pwd}/([^/]+)/(.+)$} then "\e[37m#{prefix}[#{$1}] #{$2}:#{line} #{method}\e[0m"
117
+ when %r{^.*/(ruby-[^/]+)/(bin/.+)$} then "\e[35m#{prefix}[#{$1}] #{$2}:#{line} #{method}\e[0m"
118
+ when %r{^.*/gems/(minitap|minitest)-.+/(.+)$} then nil
119
+ when %r{^.*/gems/([^/]+)/(.+)$} then "\e[36m#{prefix}[#{$1}] #{$2}:#{line} #{method}\e[0m"
120
+ else "#{prefix}#{path}:#{line}\e[0m"
121
+ end
122
+ end
123
+
124
+ def print_error(format, *args)
125
+ remove_status
126
+ io.puts format % args
127
+ io.puts
128
+ end
129
+
130
+ def update_status
131
+ running_time = Time.now - started_at
132
+ progress = 100.0 * completed / tests
133
+ io.print STATUS_FORMAT % [running_time, completed, tests, progress, assertions, errors, failures, skips]
134
+ end
135
+
136
+ def remove_status
137
+ io.print "\e[2K\r"
138
+ end
139
+ end
140
+
141
+ class SummaryReporter
142
+ def report
143
+ end
144
+ end
145
+ end
data/pretty_test.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
11
11
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
12
12
  gem.name = "pretty_test"
13
13
  gem.require_paths = ["lib"]
14
- gem.version = "0.2.3"
14
+ gem.version = "1.0.0"
15
15
 
16
- gem.add_dependency "minitest", "~> 4"
16
+ gem.add_dependency "minitest", "~> 5"
17
17
  end
@@ -0,0 +1,40 @@
1
+ require "stringio"
2
+ require "pretty_test/reporter"
3
+
4
+ class TestReporter
5
+
6
+ def self.run
7
+ new.run
8
+ end
9
+
10
+ def run
11
+ output = StringIO.new("")
12
+ reporter = PrettyTest::Reporter.new(output)
13
+
14
+ klass = Class.new(::Minitest::Test) do
15
+
16
+ def self.name
17
+ "SomeTest"
18
+ end
19
+
20
+ def test_pass
21
+ assert true
22
+ end
23
+
24
+ def test_fail
25
+ assert false
26
+ end
27
+
28
+ def test_error
29
+ raise "qwe"
30
+ end
31
+ end
32
+
33
+ reporter.start
34
+ klass.run reporter, {}
35
+ reporter.report
36
+ puts output.string
37
+ end
38
+ end
39
+
40
+ TestReporter.run
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pretty_test
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Bobes Tuzinsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-28 00:00:00.000000000 Z
11
+ date: 2014-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '4'
19
+ version: '5'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '4'
26
+ version: '5'
27
27
  description: Minitest patch for pretty (and useful) output.
28
28
  email:
29
29
  - vladimir@tuzinsky.com
@@ -35,8 +35,9 @@ files:
35
35
  - Gemfile
36
36
  - README.md
37
37
  - lib/pretty_test.rb
38
- - lib/pretty_test/runner.rb
38
+ - lib/pretty_test/reporter.rb
39
39
  - pretty_test.gemspec
40
+ - test/test_reporter.rb
40
41
  homepage: https://github.com/bobes/pretty_test
41
42
  licenses:
42
43
  - MIT
@@ -61,4 +62,5 @@ rubygems_version: 2.2.2
61
62
  signing_key:
62
63
  specification_version: 4
63
64
  summary: Minitest patch for pretty output
64
- test_files: []
65
+ test_files:
66
+ - test/test_reporter.rb
@@ -1,183 +0,0 @@
1
- require "minitest/unit"
2
-
3
- module PrettyTest
4
-
5
- class Runner < ::MiniTest::Unit
6
-
7
- SKIP_FORMAT = "\e[33m[SKIPPED] %s: %s\e[0m\n%s\n%s"
8
- FAILURE_FORMAT = "\e[31m[FAILURE] %s: %s\e[0m\n\e[31m%s: %s\e[0m\n%s"
9
- ERROR_FORMAT = "\e[31m[ERROR] %s: %s\e[0m\n\e[31m%s: %s\e[0m\n%s"
10
- STATUS_FORMAT = "\e[2K\r\e[?7l\e[37m(%.1fs) \e[32m%d/%d tests (%d%%)\e[37m, \e[36m%d assertions\e[37m, \e[31m%d errors\e[37m, \e[31m%d failures\e[37m, \e[33m%d skips \e[37m%s\e[?7h\e[0m"
11
-
12
- attr_accessor :started_at, :test_count, :assertion_count, :completed, :suite_name, :test_name, :test_record
13
-
14
- def _run_anything(type)
15
- suites = TestCase.send("#{type}_suites")
16
- _run_suites(suites, type)
17
- end
18
-
19
- def _run_suites(suites, type)
20
- before_suites(suites, type)
21
- super
22
- ensure
23
- after_suites(suites, type)
24
- end
25
-
26
- def _run_suite(suite, type)
27
- tests = suite.send("#{type}_methods")
28
- if tests.any?
29
- before_suite(suite)
30
- tests.each do |test|
31
- run_test(suite, test)
32
- end
33
- end
34
- end
35
-
36
- def record(suite, test, assertions, time, exception)
37
- @test_record = TestRecord.new(suite, test, assertions, time, exception)
38
- end
39
-
40
- private
41
-
42
- def before_suites(suites, type)
43
- @started_at = Time.now
44
- @test_count = suites.map { |suite| suite.send("#{type}_methods").count }.sum
45
- @completed = 0
46
- @assertion_count = 0
47
- end
48
-
49
- def before_suite(suite)
50
- @suite_name = pretty_suite_name(suite.name || suite.to_s)
51
- end
52
-
53
- def run_test(suite, test)
54
- before_test(test)
55
- instance = suite.new(test)
56
- instance._assertions = 0
57
- instance.run(self)
58
- @assertion_count += instance._assertions
59
- ensure
60
- after_test
61
- end
62
-
63
- def before_test(test)
64
- @test_name = pretty_test_name(test)
65
- remove_status
66
- update_status("#{suite_name}: #{test_name}")
67
- end
68
-
69
- def after_test
70
- @completed += 1
71
- case exception = test_record && test_record.exception
72
- when nil then pass
73
- when ::MiniTest::Skip then skip(exception)
74
- when ::MiniTest::Assertion then failure(exception)
75
- else error(exception)
76
- end
77
- update_status("")
78
- end
79
-
80
- def pass
81
- end
82
-
83
- def skip(exception)
84
- location = pretty_location(exception)
85
- message = exception.message.strip
86
- print_error SKIP_FORMAT, suite_name, test_name, message, location
87
- end
88
-
89
- def failure(exception)
90
- index = find_assertion_index(exception)
91
- trace = pretty_trace(exception, index)
92
- print_error FAILURE_FORMAT, suite_name, test_name, exception.class, exception.message, trace
93
- end
94
-
95
- def error(exception)
96
- index = find_exception_index(exception)
97
- trace = pretty_trace(exception, index)
98
- print_error ERROR_FORMAT, suite_name, test_name, exception.class, exception.message, trace
99
- end
100
-
101
- def after_suites(suites, type)
102
- if test_count > 0
103
- update_status
104
- end
105
- if errors + failures == 0
106
- puts " \e[32m----- PASSED! -----\e[0m"
107
- else
108
- puts " \e[31m----- FAILED! -----\e[0m"
109
- end
110
- end
111
-
112
- def pretty_suite_name(suite)
113
- suite = suite.dup
114
- suite.gsub!(/(::|_)/, " ")
115
- suite.gsub!(/\btest/i, "")
116
- suite.gsub!(/test\b/i, "")
117
- suite.gsub!(/\b([a-z])/i) { $1.upcase }
118
- suite.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1 \2')
119
- suite.gsub!(/([a-z\d])([A-Z])/, '\1 \2')
120
- suite
121
- end
122
-
123
- def pretty_test_name(test)
124
- test = test.dup
125
- test.gsub!(/^test_/, "")
126
- test.gsub!(/_+/, " ")
127
- test
128
- end
129
-
130
- def pretty_location(e)
131
- path, line = location(e)
132
- clean_trace_line("\e[1m-> ", path, line)
133
- end
134
-
135
- def find_assertion_index(error)
136
- index = error.backtrace.rindex { |trace| trace =~ /:in .(assert|refute|flunk|pass|fail|raise|must|wont)/ }
137
- index ? index + 1 : find_exception_index(error)
138
- end
139
-
140
- def find_exception_index(error)
141
- error.backtrace.index { |trace| trace.index(Dir.pwd) }
142
- end
143
-
144
- def pretty_trace(error, location_index)
145
- lines = []
146
- error.backtrace.each_with_index do |trace, index|
147
- prefix = index == location_index ? "\e[1m-> " : " "
148
- trace_file, trace_line, trace_method = trace.split(":", 3)
149
- lines << clean_trace_line(prefix, trace_file, trace_line, trace_method)
150
- end
151
- lines.compact.join("\n")
152
- end
153
-
154
- def clean_trace_line(prefix, path, line, method = nil)
155
- case path
156
- when %r{^#{Dir.pwd}/([^/]+)/(.+)$} then "\e[37m#{prefix}[#{$1}] #{$2}:#{line} #{method}\e[0m"
157
- when %r{^.*/(ruby-[^/]+)/(bin/.+)$} then "\e[35m#{prefix}[#{$1}] #{$2}:#{line} #{method}\e[0m"
158
- when %r{^.*/gems/(minitap|minitest)-.+/(.+)$} then nil
159
- when %r{^.*/gems/([^/]+)/(.+)$} then "\e[36m#{prefix}[#{$1}] #{$2}:#{line} #{method}\e[0m"
160
- else "#{prefix}#{path}:#{line}\e[0m"
161
- end
162
- end
163
-
164
- def print_error(format, *args)
165
- remove_status
166
- puts format % args
167
- puts
168
- end
169
-
170
- def update_status(message = "")
171
- running_time = Time.now - started_at
172
- progress = 100.0 * completed / test_count
173
- print STATUS_FORMAT % [running_time, completed, test_count, progress, assertion_count, errors, failures, skips, message]
174
- end
175
-
176
- def remove_status
177
- print "\e[2K\r"
178
- end
179
-
180
- class TestRecord < Struct.new(:suite, :test, :assertions, :time, :exception)
181
- end
182
- end
183
- end