uspec 1.3.0 → 1.5.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 +4 -4
- data/README.markdown +1 -1
- data/example_specs/example_spec.rb +5 -6
- data/example_specs/spec_helper.rb +0 -7
- data/lib/uspec/cli.rb +24 -29
- data/lib/uspec/define.rb +1 -1
- data/lib/uspec/errors.rb +177 -0
- data/lib/uspec/harness.rb +27 -17
- data/lib/uspec/result.rb +37 -45
- data/lib/uspec/spec.rb +1 -0
- data/lib/uspec/version.rb +1 -1
- data/lib/uspec.rb +10 -5
- data/uspec/cli_spec.rb +9 -10
- data/uspec/dsl_spec.rb +1 -1
- data/uspec/errors_spec.rb +37 -0
- data/uspec/result_spec.rb +53 -8
- data/uspec/stats_spec.rb +8 -1
- data/uspec/test_specs/error_value_spec +8 -0
- data/uspec/test_specs/internal_error_spec +3 -0
- data/uspec/test_specs/source_error_spec +8 -0
- data/uspec/uspec_helper.rb +10 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5ebd02acebff5a7d7ffa72dfe23a30b6ef1789acffb41b540758d1cf4d1f083
|
4
|
+
data.tar.gz: ffbc0c4e20c8a4c4376e0ba059ecedc9e8f1589ada86a31998a6b628b1d30df9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aecd905b5420be09dca096a188180e98b6af4514e82d58d3e510500d33899e21034ba143bb77de0536e2f00b126e4635478ecc48f7f6b2b2fa7a6c614d3f3e42
|
7
|
+
data.tar.gz: 98990be1d95c445bb8791b3fc11acefc4fc90013ae533b884db4829ad4e965695d58c1788bdc250fe9181a5eb30956b6f17f7c4afa75732e9a71e565f3f90fb7
|
data/README.markdown
CHANGED
@@ -69,7 +69,7 @@ Output
|
|
69
69
|
|
70
70
|
Uspec's output is in beautiful ANSI technicolor, with red for failures, green for successes, and yellow for pending specs.
|
71
71
|
|
72
|
-

|
73
73
|
|
74
74
|
A brief explanation of `uspec`'s output to show you what it can do!
|
75
75
|
|
@@ -1,21 +1,20 @@
|
|
1
1
|
require_relative 'spec_helper'
|
2
2
|
|
3
|
-
spec 'I love passing tests' do
|
3
|
+
spec 'I love passing tests! Passing tests return `true`' do
|
4
4
|
true
|
5
5
|
end
|
6
6
|
|
7
7
|
spec "This is an idea, but I haven't written the test yet"
|
8
8
|
|
9
|
-
spec 'Failing tests
|
9
|
+
spec 'This is a failing test. Failing tests return `false`' do
|
10
10
|
false
|
11
11
|
end
|
12
12
|
|
13
|
-
spec '
|
13
|
+
spec 'Non-boolean values are shown in detail' do
|
14
14
|
'non-boolean value'
|
15
15
|
end
|
16
16
|
|
17
|
-
spec '
|
17
|
+
spec 'Exceptions are handled and displayed' do
|
18
18
|
class ExampleError < RuntimeError; end
|
19
|
-
raise ExampleError
|
19
|
+
raise ExampleError, "an example error for demonstration"
|
20
20
|
end
|
21
|
-
|
data/lib/uspec/cli.rb
CHANGED
@@ -3,8 +3,6 @@ require_relative '../uspec'
|
|
3
3
|
|
4
4
|
class Uspec::CLI
|
5
5
|
def initialize args
|
6
|
-
usage unless (args & %w[-h --help -? /? -v --version]).empty?
|
7
|
-
|
8
6
|
@paths = args
|
9
7
|
@pwd = Pathname.pwd.freeze
|
10
8
|
@stats = Uspec::Stats.new
|
@@ -15,6 +13,9 @@ class Uspec::CLI
|
|
15
13
|
def usage
|
16
14
|
warn "uspec v#{::Uspec::VERSION} - minimalistic ruby testing framework"
|
17
15
|
warn "usage: #{File.basename $0} [<file_or_path>...]"
|
16
|
+
warn ""
|
17
|
+
warn "\t\t--full_backtrace\tshow full backtrace"
|
18
|
+
warn "\t\t--\t\t\tstop checking paths for options (good if a path begins with a dash)"
|
18
19
|
exit 1
|
19
20
|
end
|
20
21
|
|
@@ -23,6 +24,7 @@ class Uspec::CLI
|
|
23
24
|
end
|
24
25
|
|
25
26
|
def invoke
|
27
|
+
parse_options @paths
|
26
28
|
run_specs
|
27
29
|
die!
|
28
30
|
end
|
@@ -61,49 +63,42 @@ class Uspec::CLI
|
|
61
63
|
end
|
62
64
|
|
63
65
|
def run_paths
|
66
|
+
check_options = true
|
67
|
+
|
64
68
|
paths.each do |path|
|
65
69
|
run @pwd.join path
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
69
73
|
def run path
|
70
|
-
|
74
|
+
p, line = path.to_s.split(?:)
|
75
|
+
path = Pathname.new p
|
76
|
+
|
71
77
|
if path.directory? then
|
72
78
|
Pathname.glob(path.join('**', '**_spec.rb')).each do |spec|
|
73
79
|
run spec
|
74
80
|
end
|
75
81
|
elsif path.exist? then
|
76
82
|
puts "#{path.basename path.extname}:"
|
77
|
-
harness.
|
83
|
+
harness.file_eval path, line
|
78
84
|
else
|
79
85
|
warn "path not found: #{path}"
|
80
86
|
end
|
81
|
-
|
87
|
+
end
|
82
88
|
|
83
|
-
|
84
|
-
|
89
|
+
def parse_options args
|
90
|
+
args.each_with_index do |arg, i|
|
91
|
+
if arg == '--' then
|
92
|
+
return args
|
93
|
+
elsif arg == '--full_backtrace' then
|
94
|
+
Uspec::Errors.full_backtrace!
|
95
|
+
args.delete_at i
|
96
|
+
elsif !(args & %w[-h --help -? /? -v --version]).empty?
|
97
|
+
usage
|
98
|
+
elsif arg[0] == ?- then
|
99
|
+
warn "unknown option: #{arg}"
|
100
|
+
args.delete_at i
|
101
|
+
end
|
85
102
|
end
|
86
|
-
|
87
|
-
error_file, error_line, _ = error.backtrace.first.split ?:
|
88
|
-
|
89
|
-
message = <<-MSG
|
90
|
-
#{error.class} : #{error.message}
|
91
|
-
|
92
|
-
Uspec encountered an error when loading a test file.
|
93
|
-
This is probably a typo in the test file or the file it is testing.
|
94
|
-
|
95
|
-
If you think this is a bug in Uspec please report it: https://github.com/acook/uspec/issues/new
|
96
|
-
|
97
|
-
Error occured when loading test file `#{spec || path}`.
|
98
|
-
The origin of the error may be in file `#{error_file}` on line ##{error_line}.
|
99
|
-
|
100
|
-
\t#{error.backtrace[0,3].join "\n\t"}
|
101
|
-
MSG
|
102
|
-
puts
|
103
|
-
warn message
|
104
|
-
stats << Uspec::Result.new(message, error, caller)
|
105
|
-
|
106
|
-
handle_interrupt! error
|
107
103
|
end
|
108
|
-
|
109
104
|
end
|
data/lib/uspec/define.rb
CHANGED
data/lib/uspec/errors.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
require_relative "terminal"
|
2
|
+
|
3
|
+
module Uspec
|
4
|
+
module Errors
|
5
|
+
module_function
|
6
|
+
|
7
|
+
extend Uspec::Terminal
|
8
|
+
|
9
|
+
MSG_USPEC_BUG_URL = "https://github.com/acook/uspec/issues/new"
|
10
|
+
MSG_IF_USPEC_BUG = "If you think this is a bug in Uspec please report it: #{MSG_USPEC_BUG_URL}"
|
11
|
+
TRACE_EXCLUDE_PATTERN = /#{Uspec.libpath.join 'lib'}|#{Uspec.libpath.join 'bin'}/
|
12
|
+
|
13
|
+
def handle_file_error error, path, cli = nil
|
14
|
+
error_info = error_context error
|
15
|
+
|
16
|
+
message = <<~MSG
|
17
|
+
Uspec encountered an error when loading a test file.
|
18
|
+
This is probably a typo in the test file or the file it is testing.
|
19
|
+
|
20
|
+
Error occured when loading test file `#{path}`.
|
21
|
+
#{error_info}
|
22
|
+
MSG
|
23
|
+
|
24
|
+
handle_error message, error, cli
|
25
|
+
end
|
26
|
+
|
27
|
+
def handle_internal_error error, cli = nil
|
28
|
+
error_info = error_context error, skip_internal: false
|
29
|
+
|
30
|
+
message = <<~MSG
|
31
|
+
Uspec encountered an internal error!
|
32
|
+
|
33
|
+
#{error_info}
|
34
|
+
MSG
|
35
|
+
|
36
|
+
handle_error message, error, cli
|
37
|
+
end
|
38
|
+
|
39
|
+
def handle_error message, error, cli
|
40
|
+
result = Uspec::Result.new(message, error, true)
|
41
|
+
|
42
|
+
puts
|
43
|
+
warn error_format error, message, leading_newline: false
|
44
|
+
|
45
|
+
cli.handle_interrupt! result.raw if cli
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
def msg_spec_error error, desc
|
50
|
+
error_info = error_context error
|
51
|
+
|
52
|
+
info = <<~MSG
|
53
|
+
Error occured when evaluating spec `#{desc}`.
|
54
|
+
#{error_info}
|
55
|
+
MSG
|
56
|
+
body = error_format error, info, first_line_indent: false
|
57
|
+
|
58
|
+
message = <<~MSG
|
59
|
+
#{red 'Exception'}
|
60
|
+
#{body}
|
61
|
+
MSG
|
62
|
+
|
63
|
+
message
|
64
|
+
end
|
65
|
+
|
66
|
+
def msg_spec_value error
|
67
|
+
error_info = white bt_format(bt_get error).chomp
|
68
|
+
|
69
|
+
message = <<~MSG
|
70
|
+
#{error.message}
|
71
|
+
#{error_info}
|
72
|
+
MSG
|
73
|
+
|
74
|
+
error_format error, message, header: false
|
75
|
+
end
|
76
|
+
|
77
|
+
def msg_source_error error, desc, cli = nil
|
78
|
+
error_info = error_context error
|
79
|
+
|
80
|
+
message = <<~MSG
|
81
|
+
Uspec detected a bug in your source code!
|
82
|
+
|
83
|
+
Calling #inspect on an object will recusively call #inspect on its instance variables and contents.
|
84
|
+
If one of those contained objects does not have an #inspect method you will see this message.
|
85
|
+
You will also get this message if your #inspect method or one of its callees raises an exception.
|
86
|
+
This is most likely to happen with BasicObject and its subclasses.
|
87
|
+
|
88
|
+
Error occured when evaluating spec `#{desc}`.
|
89
|
+
#{error_info}
|
90
|
+
MSG
|
91
|
+
|
92
|
+
error_format error, message, first_line_indent: false
|
93
|
+
end
|
94
|
+
|
95
|
+
def error_context error, skip_internal: true
|
96
|
+
bt = bt_get error
|
97
|
+
error_line = bt.first.split(?:)
|
98
|
+
[
|
99
|
+
error_origin(*error_line),
|
100
|
+
white(bt_format(bt, skip_internal)),
|
101
|
+
MSG_IF_USPEC_BUG
|
102
|
+
].join ?\n
|
103
|
+
end
|
104
|
+
|
105
|
+
def bt_get error
|
106
|
+
error.backtrace || caller[3..-1]
|
107
|
+
end
|
108
|
+
|
109
|
+
def error_origin error_file, error_line, *_
|
110
|
+
"The origin of the error may be in file `#{error_file}` on line ##{error_line}."
|
111
|
+
end
|
112
|
+
|
113
|
+
def error_format error, message, first_line_indent: true, leading_newline: true, header: true
|
114
|
+
h = ""
|
115
|
+
|
116
|
+
if header then
|
117
|
+
h << newline if leading_newline
|
118
|
+
h << hspace if first_line_indent
|
119
|
+
h << error_header(error)
|
120
|
+
h << vspace
|
121
|
+
end
|
122
|
+
|
123
|
+
error_indent(error, h + message)
|
124
|
+
end
|
125
|
+
|
126
|
+
def error_indent error, message
|
127
|
+
a = message.split(newline)
|
128
|
+
a << ""
|
129
|
+
a.join("#{newline}#{hspace}")
|
130
|
+
end
|
131
|
+
|
132
|
+
def error_header error
|
133
|
+
"#{red subklassinfo error}#{error.message}"
|
134
|
+
end
|
135
|
+
|
136
|
+
def subklassinfo obj
|
137
|
+
"#{::TOISB.wrap(obj).subklassinfo}: "
|
138
|
+
end
|
139
|
+
|
140
|
+
def bt_format bt, skip_internal = true
|
141
|
+
skip_internal = skip_internal && !full_backtrace?
|
142
|
+
bt_indent bt_clean(bt, skip_internal)
|
143
|
+
end
|
144
|
+
|
145
|
+
def bt_indent bt
|
146
|
+
"#{newline}#{hspace}" + bt.join("#{newline}#{hspace}") + newline if bt
|
147
|
+
end
|
148
|
+
|
149
|
+
def bt_clean bt, skip_internal = true
|
150
|
+
bt.inject(Array.new) do |t, line|
|
151
|
+
next t if skip_internal && line.match(TRACE_EXCLUDE_PATTERN)
|
152
|
+
t << bt_rewrite_caller(line)
|
153
|
+
end if bt
|
154
|
+
end
|
155
|
+
|
156
|
+
def bt_rewrite_caller line
|
157
|
+
return line if full_backtrace?
|
158
|
+
if line.match TRACE_EXCLUDE_PATTERN then
|
159
|
+
line
|
160
|
+
else
|
161
|
+
line.sub /file_eval/, 'spec_block'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def full_backtrace?
|
166
|
+
@full_backtrace
|
167
|
+
end
|
168
|
+
|
169
|
+
def full_backtrace!
|
170
|
+
@full_backtrace = true
|
171
|
+
end
|
172
|
+
|
173
|
+
def clean_backtrace!
|
174
|
+
@full_backtrace = false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
data/lib/uspec/harness.rb
CHANGED
@@ -14,45 +14,55 @@ module Uspec
|
|
14
14
|
cli.stats
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def file_eval path, line
|
18
|
+
@path = path
|
19
|
+
@line = line
|
20
|
+
define.instance_eval(path.read, path.to_s)
|
21
|
+
rescue Exception => error
|
22
|
+
raise error if SystemExit === error
|
23
|
+
result = Uspec::Errors.handle_file_error error, path, cli
|
24
|
+
stats << result if result
|
25
|
+
end
|
26
|
+
|
27
|
+
def spec_eval description, source, &block
|
28
|
+
return if @line && !source.first.include?("#{@path}:#{@line}")
|
29
|
+
|
30
|
+
ex = nil
|
18
31
|
state = 0
|
19
32
|
print ' -- ', description
|
20
33
|
|
21
34
|
if block then
|
22
35
|
begin
|
23
36
|
state = 1
|
24
|
-
|
37
|
+
spec = Uspec::Spec.new(self, description, &block)
|
38
|
+
raw_result = spec.__uspec_block
|
25
39
|
state = 2
|
26
40
|
rescue Exception => raw_result
|
27
41
|
state = 3
|
42
|
+
ex = true
|
28
43
|
end
|
29
44
|
end
|
30
45
|
|
31
|
-
result = Uspec::Result.new
|
46
|
+
result = Uspec::Result.new spec, raw_result, ex
|
32
47
|
|
33
48
|
unless block then
|
34
49
|
state = 4
|
35
50
|
result.pending!
|
36
51
|
end
|
37
52
|
|
38
|
-
stats << result
|
39
|
-
|
40
53
|
print ': ', result.pretty, "\n"
|
41
54
|
rescue => error
|
42
|
-
|
43
|
-
message = <<-MSG
|
44
|
-
#{error.class} : #{error.message}
|
45
|
-
|
46
|
-
Uspec encountered an internal error, please report this bug: https://github.com/acook/uspec/issues/new
|
47
|
-
|
48
|
-
\t#{error.backtrace.join "\n\t"}
|
49
|
-
MSG
|
50
|
-
puts
|
51
|
-
warn message
|
52
|
-
stats << Uspec::Result.new(message, error, caller)
|
55
|
+
result = Uspec::Errors.handle_internal_error error, cli
|
53
56
|
ensure
|
54
|
-
|
57
|
+
stats << result if result
|
58
|
+
cli.handle_interrupt! result ? result.raw : raw_result
|
55
59
|
return [state, error, result, raw_result]
|
56
60
|
end
|
61
|
+
|
62
|
+
def inspect
|
63
|
+
<<~MSG.chomp
|
64
|
+
<#{self.class}##{self.object_id} @cli=#{@cli ? '<...>' : @cli} @define=#{@define ? '<...>' : @define}>
|
65
|
+
MSG
|
66
|
+
end
|
57
67
|
end
|
58
68
|
end
|
data/lib/uspec/result.rb
CHANGED
@@ -7,13 +7,15 @@ module Uspec
|
|
7
7
|
|
8
8
|
PREFIX = "#{Uspec::Terminal.newline}#{Uspec::Terminal.yellow}>\t#{Uspec::Terminal.normal}"
|
9
9
|
|
10
|
-
def initialize spec, raw,
|
10
|
+
def initialize spec, raw, ex
|
11
11
|
@spec = spec
|
12
12
|
@raw = raw
|
13
|
-
@
|
13
|
+
@ex = ex
|
14
14
|
@handler = ::TOISB.wrap raw
|
15
|
+
@full_backtrace = false
|
16
|
+
@caller = caller
|
15
17
|
end
|
16
|
-
attr_reader :spec, :raw, :
|
18
|
+
attr_reader :spec, :raw, :ex, :handler, :full_backtrace
|
17
19
|
|
18
20
|
def pretty
|
19
21
|
if raw == true then
|
@@ -22,70 +24,60 @@ module Uspec
|
|
22
24
|
red raw
|
23
25
|
elsif pending? then
|
24
26
|
yellow 'pending'
|
25
|
-
elsif
|
26
|
-
|
27
|
-
red('Exception'), vspace,
|
28
|
-
hspace, 'Spec encountered an Exception ', newline,
|
29
|
-
hspace, 'in spec at ', source.first, vspace,
|
30
|
-
hspace, message, vspace,
|
31
|
-
white(trace)
|
32
|
-
].join
|
27
|
+
elsif ex == true then
|
28
|
+
Uspec::Errors.msg_spec_error raw, desc
|
33
29
|
else
|
34
|
-
|
35
|
-
red('Failed'), vspace,
|
36
|
-
hspace, 'Spec did not return a boolean value ', newline,
|
37
|
-
hspace, 'in spec at ', source.first, vspace,
|
38
|
-
hspace, red(subklassinfo), inspector, (Class === raw ? ' Class' : ''), newline
|
39
|
-
].join
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def trace
|
44
|
-
raw.backtrace.inject(String.new) do |text, line|
|
45
|
-
text << "#{hspace}#{line}#{newline}"
|
30
|
+
nonboolean
|
46
31
|
end
|
47
32
|
end
|
48
33
|
|
49
|
-
def
|
50
|
-
|
34
|
+
def source
|
35
|
+
@source ||= Uspec::Errors.bt_clean @caller
|
51
36
|
end
|
52
37
|
|
53
38
|
def subklassinfo
|
54
39
|
"#{handler.subklassinfo}: "
|
55
40
|
end
|
56
41
|
|
42
|
+
def desc
|
43
|
+
if String === spec then
|
44
|
+
spec
|
45
|
+
elsif Uspec::Spec === spec then
|
46
|
+
spec.instance_variable_get :@__uspec_description
|
47
|
+
else
|
48
|
+
spec.inspect
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def nonboolean
|
53
|
+
[
|
54
|
+
red('Failed'), vspace,
|
55
|
+
hspace, 'Spec did not return a boolean value ', newline,
|
56
|
+
hspace, 'in spec at ', source.first, vspace,
|
57
|
+
hspace, red(subklassinfo), inspector, (Class === raw ? ' Class' : ''), newline
|
58
|
+
].join
|
59
|
+
|
60
|
+
end
|
61
|
+
|
57
62
|
# Attempts to inspect an object
|
58
63
|
def inspector
|
59
64
|
if String === raw && raw.include?(?\n) then
|
60
65
|
# if object is a multiline string, display it unescaped
|
61
|
-
|
62
66
|
[
|
63
67
|
raw.split(newline).unshift(newline).join(PREFIX), normal, newline,
|
64
68
|
].join
|
69
|
+
elsif Exception === raw then
|
70
|
+
Uspec::Errors.msg_spec_value raw
|
65
71
|
else
|
66
72
|
handler.inspector!
|
67
73
|
end
|
68
74
|
rescue Exception => error
|
69
75
|
return handler.simple_inspector if error.message.include? handler.get_id
|
70
76
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
#{error.class} : #{error.message}
|
76
|
-
|
77
|
-
Uspec detected a bug in your source code!
|
78
|
-
Calling #inspect on an object will recusively call #inspect on its instance variables and contents.
|
79
|
-
If one of those contained objects does not have an #inspect method you will see this message.
|
80
|
-
You will also get this message if your #inspect method or one of its callees raises an exception.
|
81
|
-
This is most likely to happen with BasicObject and its subclasses.
|
82
|
-
|
83
|
-
If you think this is a bug in Uspec please report it: https://github.com/acook/uspec/issues/new
|
84
|
-
|
85
|
-
Error may have occured in test `#{spec}` in file `#{error_file}` on line ##{error_line}.
|
86
|
-
|
87
|
-
\t#{error.backtrace.join "\n\t"}
|
88
|
-
MSG
|
77
|
+
[
|
78
|
+
red('Unable to Inspect Object'), newline,
|
79
|
+
Uspec::Errors.msg_source_error(error, desc),
|
80
|
+
].join
|
89
81
|
end
|
90
82
|
|
91
83
|
def success?
|
@@ -105,7 +97,7 @@ module Uspec
|
|
105
97
|
end
|
106
98
|
|
107
99
|
def inspect
|
108
|
-
"#{self.class} for `#{
|
100
|
+
"#{self.class} for `#{desc}` -> #{pretty}"
|
109
101
|
end
|
110
102
|
end
|
111
103
|
end
|
data/lib/uspec/spec.rb
CHANGED
data/lib/uspec/version.rb
CHANGED
data/lib/uspec.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
require_relative 'uspec/version'
|
2
|
-
require_relative 'uspec/harness'
|
3
|
-
require_relative 'uspec/define'
|
4
|
-
require_relative 'uspec/stats'
|
5
|
-
|
6
1
|
module Uspec
|
7
2
|
def self.included object
|
8
3
|
warn 'Use extend instead of include.'
|
@@ -15,4 +10,14 @@ module Uspec
|
|
15
10
|
# object.extend Uspec::DSL
|
16
11
|
#end
|
17
12
|
end
|
13
|
+
|
14
|
+
def self.libpath
|
15
|
+
Pathname.new(__FILE__).dirname.dirname
|
16
|
+
end
|
18
17
|
end
|
18
|
+
|
19
|
+
require_relative 'uspec/version'
|
20
|
+
require_relative 'uspec/errors'
|
21
|
+
require_relative 'uspec/harness'
|
22
|
+
require_relative 'uspec/define'
|
23
|
+
require_relative 'uspec/stats'
|
data/uspec/cli_spec.rb
CHANGED
@@ -1,14 +1,5 @@
|
|
1
1
|
require_relative 'uspec_helper'
|
2
2
|
|
3
|
-
def new_cli path = '.'
|
4
|
-
Uspec::CLI.new(Array(path))
|
5
|
-
end
|
6
|
-
|
7
|
-
def run_specs path
|
8
|
-
new_cli(path).run_specs
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
3
|
spec 'shows usage' do
|
13
4
|
output = capture do
|
14
5
|
exec 'bin/uspec -h'
|
@@ -25,7 +16,7 @@ spec 'runs a path of specs' do
|
|
25
16
|
output.include?('I love passing tests') || output
|
26
17
|
end
|
27
18
|
|
28
|
-
spec 'runs an individual
|
19
|
+
spec 'runs an individual file' do
|
29
20
|
output = outstr do
|
30
21
|
run_specs exdir.join('example_spec.rb').to_s
|
31
22
|
end
|
@@ -33,6 +24,14 @@ spec 'runs an individual spec' do
|
|
33
24
|
output.include?('I love passing tests') || output
|
34
25
|
end
|
35
26
|
|
27
|
+
spec 'runs an individual spec' do
|
28
|
+
output = outstr do
|
29
|
+
run_specs exdir.join('example_spec.rb:13').to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
!output.include?('I love passing tests') && output.include?('non-boolean') || output
|
33
|
+
end
|
34
|
+
|
36
35
|
spec 'broken requires in test files count as test failures' do
|
37
36
|
output, status = Open3.capture2e "#{root}/bin/uspec #{testdir.join('broken_require_spec')}"
|
38
37
|
|
data/uspec/dsl_spec.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative "uspec_helper"
|
2
|
+
|
3
|
+
spec 'file errors are captured' do
|
4
|
+
cli = new_cli
|
5
|
+
|
6
|
+
output = outstr do
|
7
|
+
cli.harness.file_eval testdir.join('broken_require_spec'), nil
|
8
|
+
end
|
9
|
+
|
10
|
+
output.include?('Uspec encountered an error when loading') || output
|
11
|
+
end
|
12
|
+
|
13
|
+
spec 'internal errors are captured' do
|
14
|
+
cli = new_cli
|
15
|
+
|
16
|
+
output = outstr do
|
17
|
+
cli.harness.spec_eval BasicObject.new, BasicObject.new do
|
18
|
+
raise 'block error'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
output.include?('Uspec encountered an internal error') || output
|
23
|
+
end
|
24
|
+
|
25
|
+
spec 'source errors are captured' do
|
26
|
+
bo = BasicObject.new
|
27
|
+
def bo.inspect
|
28
|
+
invalid_for_source_error
|
29
|
+
end
|
30
|
+
|
31
|
+
a = [ bo ]
|
32
|
+
|
33
|
+
result = Uspec::Result.new "source error result", a, true
|
34
|
+
output = result.inspector
|
35
|
+
|
36
|
+
output.include?('Uspec detected a bug in your source') || output
|
37
|
+
end
|
data/uspec/result_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require_relative "uspec_helper"
|
|
3
3
|
bo = BasicObject.new
|
4
4
|
|
5
5
|
spec "#pretty doesn't die when given a BasicObject" do
|
6
|
-
result = Uspec::Result.new "BasicObject Result", bo,
|
6
|
+
result = Uspec::Result.new "BasicObject Result", bo, nil
|
7
7
|
expected = "#<BasicObject:"
|
8
8
|
actual = result.pretty
|
9
9
|
actual.include?(expected) || actual
|
@@ -14,28 +14,28 @@ class ::TestObject < BasicObject; end
|
|
14
14
|
obj = TestObject.new
|
15
15
|
|
16
16
|
spec "ensure BasicObject subclass instances work" do
|
17
|
-
result = Uspec::Result.new "BasicObject Subclass Result", obj,
|
17
|
+
result = Uspec::Result.new "BasicObject Subclass Result", obj, nil
|
18
18
|
expected = "#<BasicObject/TestObject:"
|
19
19
|
actual = result.pretty
|
20
20
|
actual.include?(expected) || result.pretty
|
21
21
|
end
|
22
22
|
|
23
23
|
spec "display basic info about Object" do
|
24
|
-
result = Uspec::Result.new "Object Result", Object.new,
|
24
|
+
result = Uspec::Result.new "Object Result", Object.new, nil
|
25
25
|
expected = "Object < BasicObject: \e[0m#<Object:"
|
26
26
|
actual = result.pretty
|
27
27
|
actual.include?(expected) || result.pretty
|
28
28
|
end
|
29
29
|
|
30
30
|
spec "display basic info about Array" do
|
31
|
-
result = Uspec::Result.new "Array Result", [],
|
31
|
+
result = Uspec::Result.new "Array Result", [], nil
|
32
32
|
expected = "Array < Object"
|
33
33
|
actual = result.pretty
|
34
34
|
actual.include?(expected) || result.pretty
|
35
35
|
end
|
36
36
|
|
37
37
|
spec "display basic info about Array class" do
|
38
|
-
result = Uspec::Result.new "Array Class Result", Array,
|
38
|
+
result = Uspec::Result.new "Array Class Result", Array, nil
|
39
39
|
expected = "Class < Module: \e[0mArray Class"
|
40
40
|
actual = result.pretty
|
41
41
|
actual.include?(expected) || result.pretty
|
@@ -44,7 +44,7 @@ end
|
|
44
44
|
parent = [obj]
|
45
45
|
|
46
46
|
spec "ensure parent object of BasicObject subclasses get a useful error message" do
|
47
|
-
result = Uspec::Result.new "BasicObject Parent Result", parent,
|
47
|
+
result = Uspec::Result.new "BasicObject Parent Result", parent, nil
|
48
48
|
expected = "BasicObject and its subclasses"
|
49
49
|
actual = result.pretty
|
50
50
|
actual.include?(expected) || result.inspector
|
@@ -54,7 +54,7 @@ class ::InspectFail; def inspect; raise RuntimeError, "This error is intentional
|
|
54
54
|
inspect_fail = InspectFail.new
|
55
55
|
|
56
56
|
spec "display a useful error message when a user-defined inspect method fails" do
|
57
|
-
result = Uspec::Result.new "Inspect Fail Result", inspect_fail,
|
57
|
+
result = Uspec::Result.new "Inspect Fail Result", inspect_fail, nil
|
58
58
|
expected = "raises an exception"
|
59
59
|
actual = result.pretty
|
60
60
|
actual.include?(expected) || result.inspector
|
@@ -63,7 +63,52 @@ end
|
|
63
63
|
spec "display strings more like their actual contents" do
|
64
64
|
string = "this string:\nshould display \e\[42;2mproperly"
|
65
65
|
expected = /this string:\n.*should display \e\[42;2mproperly/
|
66
|
-
result = Uspec::Result.new "Inspect Fail Result", string,
|
66
|
+
result = Uspec::Result.new "Inspect Fail Result", string, nil
|
67
67
|
actual = result.pretty
|
68
68
|
actual.match?(expected) || result.inspector
|
69
69
|
end
|
70
|
+
|
71
|
+
def exception_value
|
72
|
+
raise "A test exception!"
|
73
|
+
rescue => err
|
74
|
+
return err
|
75
|
+
end
|
76
|
+
|
77
|
+
spec "handles exception values" do
|
78
|
+
result = Uspec::Result.new "Exception Value Result", exception_value, nil
|
79
|
+
expected = "RuntimeError < StandardError: \e[0mA test exception!"
|
80
|
+
actual = result.pretty
|
81
|
+
actual.include?(expected) || result.pretty
|
82
|
+
end
|
83
|
+
|
84
|
+
spec "handles exception values including backtraces" do
|
85
|
+
result = Uspec::Result.new "Exception Value Result", exception_value, nil
|
86
|
+
expected = "exception_value"
|
87
|
+
actual = result.pretty
|
88
|
+
actual.include?(expected) || result.pretty
|
89
|
+
end
|
90
|
+
|
91
|
+
spec "handles raised exceptions" do
|
92
|
+
result = Uspec::Result.new "Exception Raised Result", exception_value, true
|
93
|
+
expected = "RuntimeError < StandardError: \e[0mA test exception!"
|
94
|
+
actual = result.pretty
|
95
|
+
actual.include?(expected) || result.pretty
|
96
|
+
end
|
97
|
+
|
98
|
+
spec "handles raised exceptions without backtraces" do
|
99
|
+
result = Uspec::Result.new "Exception Raised Result", Exception.new, true
|
100
|
+
expected = "Exception < Object: \e[0mException"
|
101
|
+
actual = result.pretty
|
102
|
+
actual.include?(expected) || result.pretty
|
103
|
+
end
|
104
|
+
|
105
|
+
spec "doesn't show 'run' for spec file in stack trace" do
|
106
|
+
Uspec::Errors.clean_backtrace!
|
107
|
+
|
108
|
+
result = Uspec::Result.new "No Run Exception Trace Result", exception_value, true
|
109
|
+
expected = /uspec.*run/
|
110
|
+
actual = result.pretty
|
111
|
+
|
112
|
+
Uspec::Errors.full_backtrace!
|
113
|
+
!actual.match?(expected) || result.pretty
|
114
|
+
end
|
data/uspec/stats_spec.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
require_relative 'uspec_helper'
|
2
2
|
|
3
|
+
def stats_object
|
4
|
+
Uspec::Stats.new
|
5
|
+
end
|
6
|
+
|
3
7
|
spec 'stats can be inspected' do
|
8
|
+
# this is a regression test
|
9
|
+
# the issue it covers occured because of a refactor where stats had a custom inspect method
|
10
|
+
# stats no longer has a custom inspect method, but this makes sure that nothing breaks
|
4
11
|
actual = @__uspec_harness.stats.inspect
|
5
12
|
actual.include?("failure") || actual
|
6
13
|
end
|
7
14
|
|
8
15
|
spec 'stats inspect does not have any stray whitespace' do
|
9
|
-
output =
|
16
|
+
output = stats_object.inspect
|
10
17
|
match = output.match /(.*(?: |\n))/m
|
11
18
|
match == nil || match
|
12
19
|
end
|
data/uspec/uspec_helper.rb
CHANGED
@@ -9,6 +9,8 @@ require 'stringio'
|
|
9
9
|
require_relative '../lib/uspec'
|
10
10
|
extend Uspec
|
11
11
|
|
12
|
+
Uspec::Errors.full_backtrace!
|
13
|
+
|
12
14
|
def capture
|
13
15
|
readme, writeme = IO.pipe
|
14
16
|
pid = fork do
|
@@ -59,3 +61,11 @@ end
|
|
59
61
|
def testdir
|
60
62
|
specdir.join('test_specs')
|
61
63
|
end
|
64
|
+
|
65
|
+
def new_cli path = '.'
|
66
|
+
Uspec::CLI.new(Array(path))
|
67
|
+
end
|
68
|
+
|
69
|
+
def run_specs path
|
70
|
+
new_cli(path).run_specs
|
71
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony M. Cook
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: that_object_is_so_basic
|
@@ -50,6 +50,7 @@ files:
|
|
50
50
|
- lib/uspec.rb
|
51
51
|
- lib/uspec/cli.rb
|
52
52
|
- lib/uspec/define.rb
|
53
|
+
- lib/uspec/errors.rb
|
53
54
|
- lib/uspec/harness.rb
|
54
55
|
- lib/uspec/result.rb
|
55
56
|
- lib/uspec/spec.rb
|
@@ -59,16 +60,20 @@ files:
|
|
59
60
|
- uspec.gemspec
|
60
61
|
- uspec/cli_spec.rb
|
61
62
|
- uspec/dsl_spec.rb
|
63
|
+
- uspec/errors_spec.rb
|
62
64
|
- uspec/result_spec.rb
|
63
65
|
- uspec/stats_spec.rb
|
64
66
|
- uspec/test_specs/break_spec
|
65
67
|
- uspec/test_specs/broken_require_spec
|
68
|
+
- uspec/test_specs/error_value_spec
|
69
|
+
- uspec/test_specs/internal_error_spec
|
66
70
|
- uspec/test_specs/ivar_spec
|
67
71
|
- uspec/test_specs/kill_this_script.sh
|
68
72
|
- uspec/test_specs/kill_this_spec
|
69
73
|
- uspec/test_specs/method_spec
|
70
74
|
- uspec/test_specs/pending_spec
|
71
75
|
- uspec/test_specs/return_spec
|
76
|
+
- uspec/test_specs/source_error_spec
|
72
77
|
- uspec/test_specs/value_spec
|
73
78
|
- uspec/uspec_helper.rb
|
74
79
|
- uspec/uspec_spec.rb
|