pretty_test 0.2.3 → 1.0.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.
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