json 2.5.1-java → 2.6.0-java
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/lib/json/ext/generator.jar +0 -0
- data/lib/json/ext/parser.jar +0 -0
- data/lib/json/pure/parser.rb +1 -1
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +1 -1
- metadata +6 -85
- data/tests/fixtures/fail10.json +0 -1
- data/tests/fixtures/fail11.json +0 -1
- data/tests/fixtures/fail12.json +0 -1
- data/tests/fixtures/fail13.json +0 -1
- data/tests/fixtures/fail14.json +0 -1
- data/tests/fixtures/fail18.json +0 -1
- data/tests/fixtures/fail19.json +0 -1
- data/tests/fixtures/fail2.json +0 -1
- data/tests/fixtures/fail20.json +0 -1
- data/tests/fixtures/fail21.json +0 -1
- data/tests/fixtures/fail22.json +0 -1
- data/tests/fixtures/fail23.json +0 -1
- data/tests/fixtures/fail24.json +0 -1
- data/tests/fixtures/fail25.json +0 -1
- data/tests/fixtures/fail27.json +0 -2
- data/tests/fixtures/fail28.json +0 -2
- data/tests/fixtures/fail29.json +0 -1
- data/tests/fixtures/fail3.json +0 -1
- data/tests/fixtures/fail30.json +0 -1
- data/tests/fixtures/fail31.json +0 -1
- data/tests/fixtures/fail32.json +0 -1
- data/tests/fixtures/fail4.json +0 -1
- data/tests/fixtures/fail5.json +0 -1
- data/tests/fixtures/fail6.json +0 -1
- data/tests/fixtures/fail7.json +0 -1
- data/tests/fixtures/fail8.json +0 -1
- data/tests/fixtures/fail9.json +0 -1
- data/tests/fixtures/obsolete_fail1.json +0 -1
- data/tests/fixtures/pass1.json +0 -56
- data/tests/fixtures/pass15.json +0 -1
- data/tests/fixtures/pass16.json +0 -1
- data/tests/fixtures/pass17.json +0 -1
- data/tests/fixtures/pass2.json +0 -1
- data/tests/fixtures/pass26.json +0 -1
- data/tests/fixtures/pass3.json +0 -6
- data/tests/json_addition_test.rb +0 -199
- data/tests/json_common_interface_test.rb +0 -169
- data/tests/json_encoding_test.rb +0 -107
- data/tests/json_ext_parser_test.rb +0 -15
- data/tests/json_fixtures_test.rb +0 -40
- data/tests/json_generator_test.rb +0 -399
- data/tests/json_generic_object_test.rb +0 -82
- data/tests/json_parser_test.rb +0 -497
- data/tests/json_string_matching_test.rb +0 -38
- data/tests/lib/core_assertions.rb +0 -763
- data/tests/lib/envutil.rb +0 -365
- data/tests/lib/find_executable.rb +0 -22
- data/tests/lib/helper.rb +0 -4
- data/tests/ractor_test.rb +0 -30
- data/tests/test_helper.rb +0 -17
@@ -1,763 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Test
|
4
|
-
module Unit
|
5
|
-
module Assertions
|
6
|
-
def _assertions= n # :nodoc:
|
7
|
-
@_assertions = n
|
8
|
-
end
|
9
|
-
|
10
|
-
def _assertions # :nodoc:
|
11
|
-
@_assertions ||= 0
|
12
|
-
end
|
13
|
-
|
14
|
-
##
|
15
|
-
# Returns a proc that will output +msg+ along with the default message.
|
16
|
-
|
17
|
-
def message msg = nil, ending = nil, &default
|
18
|
-
proc {
|
19
|
-
msg = msg.call.chomp(".") if Proc === msg
|
20
|
-
custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty?
|
21
|
-
"#{custom_message}#{default.call}#{ending || "."}"
|
22
|
-
}
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
module CoreAssertions
|
27
|
-
if defined?(MiniTest)
|
28
|
-
require_relative '../../envutil'
|
29
|
-
# for ruby core testing
|
30
|
-
include MiniTest::Assertions
|
31
|
-
|
32
|
-
# Compatibility hack for assert_raise
|
33
|
-
Test::Unit::AssertionFailedError = MiniTest::Assertion
|
34
|
-
else
|
35
|
-
module MiniTest
|
36
|
-
class Assertion < Exception; end
|
37
|
-
class Skip < Assertion; end
|
38
|
-
end
|
39
|
-
|
40
|
-
require 'pp'
|
41
|
-
require_relative 'envutil'
|
42
|
-
include Test::Unit::Assertions
|
43
|
-
end
|
44
|
-
|
45
|
-
def mu_pp(obj) #:nodoc:
|
46
|
-
obj.pretty_inspect.chomp
|
47
|
-
end
|
48
|
-
|
49
|
-
def assert_file
|
50
|
-
AssertFile
|
51
|
-
end
|
52
|
-
|
53
|
-
FailDesc = proc do |status, message = "", out = ""|
|
54
|
-
now = Time.now
|
55
|
-
proc do
|
56
|
-
EnvUtil.failure_description(status, now, message, out)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def assert_in_out_err(args, test_stdin = "", test_stdout = [], test_stderr = [], message = nil,
|
61
|
-
success: nil, **opt)
|
62
|
-
args = Array(args).dup
|
63
|
-
args.insert((Hash === args[0] ? 1 : 0), '--disable=gems')
|
64
|
-
stdout, stderr, status = EnvUtil.invoke_ruby(args, test_stdin, true, true, **opt)
|
65
|
-
desc = FailDesc[status, message, stderr]
|
66
|
-
if block_given?
|
67
|
-
raise "test_stdout ignored, use block only or without block" if test_stdout != []
|
68
|
-
raise "test_stderr ignored, use block only or without block" if test_stderr != []
|
69
|
-
yield(stdout.lines.map {|l| l.chomp }, stderr.lines.map {|l| l.chomp }, status)
|
70
|
-
else
|
71
|
-
all_assertions(desc) do |a|
|
72
|
-
[["stdout", test_stdout, stdout], ["stderr", test_stderr, stderr]].each do |key, exp, act|
|
73
|
-
a.for(key) do
|
74
|
-
if exp.is_a?(Regexp)
|
75
|
-
assert_match(exp, act)
|
76
|
-
elsif exp.all? {|e| String === e}
|
77
|
-
assert_equal(exp, act.lines.map {|l| l.chomp })
|
78
|
-
else
|
79
|
-
assert_pattern_list(exp, act)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
unless success.nil?
|
84
|
-
a.for("success?") do
|
85
|
-
if success
|
86
|
-
assert_predicate(status, :success?)
|
87
|
-
else
|
88
|
-
assert_not_predicate(status, :success?)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
status
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
if defined?(RubyVM::InstructionSequence)
|
98
|
-
def syntax_check(code, fname, line)
|
99
|
-
code = code.dup.force_encoding(Encoding::UTF_8)
|
100
|
-
RubyVM::InstructionSequence.compile(code, fname, fname, line)
|
101
|
-
:ok
|
102
|
-
ensure
|
103
|
-
raise if SyntaxError === $!
|
104
|
-
end
|
105
|
-
else
|
106
|
-
def syntax_check(code, fname, line)
|
107
|
-
code = code.b
|
108
|
-
code.sub!(/\A(?:\xef\xbb\xbf)?(\s*\#.*$)*(\n)?/n) {
|
109
|
-
"#$&#{"\n" if $1 && !$2}BEGIN{throw tag, :ok}\n"
|
110
|
-
}
|
111
|
-
code = code.force_encoding(Encoding::UTF_8)
|
112
|
-
catch {|tag| eval(code, binding, fname, line - 1)}
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def assert_no_memory_leak(args, prepare, code, message=nil, limit: 2.0, rss: false, **opt)
|
117
|
-
# TODO: consider choosing some appropriate limit for MJIT and stop skipping this once it does not randomly fail
|
118
|
-
pend 'assert_no_memory_leak may consider MJIT memory usage as leak' if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
|
119
|
-
|
120
|
-
require_relative '../../memory_status'
|
121
|
-
raise MiniTest::Skip, "unsupported platform" unless defined?(Memory::Status)
|
122
|
-
|
123
|
-
token = "\e[7;1m#{$$.to_s}:#{Time.now.strftime('%s.%L')}:#{rand(0x10000).to_s(16)}:\e[m"
|
124
|
-
token_dump = token.dump
|
125
|
-
token_re = Regexp.quote(token)
|
126
|
-
envs = args.shift if Array === args and Hash === args.first
|
127
|
-
args = [
|
128
|
-
"--disable=gems",
|
129
|
-
"-r", File.expand_path("../../../memory_status", __FILE__),
|
130
|
-
*args,
|
131
|
-
"-v", "-",
|
132
|
-
]
|
133
|
-
if defined? Memory::NO_MEMORY_LEAK_ENVS then
|
134
|
-
envs ||= {}
|
135
|
-
newenvs = envs.merge(Memory::NO_MEMORY_LEAK_ENVS) { |_, _, _| break }
|
136
|
-
envs = newenvs if newenvs
|
137
|
-
end
|
138
|
-
args.unshift(envs) if envs
|
139
|
-
cmd = [
|
140
|
-
'END {STDERR.puts '"#{token_dump}"'"FINAL=#{Memory::Status.new}"}',
|
141
|
-
prepare,
|
142
|
-
'STDERR.puts('"#{token_dump}"'"START=#{$initial_status = Memory::Status.new}")',
|
143
|
-
'$initial_size = $initial_status.size',
|
144
|
-
code,
|
145
|
-
'GC.start',
|
146
|
-
].join("\n")
|
147
|
-
_, err, status = EnvUtil.invoke_ruby(args, cmd, true, true, **opt)
|
148
|
-
before = err.sub!(/^#{token_re}START=(\{.*\})\n/, '') && Memory::Status.parse($1)
|
149
|
-
after = err.sub!(/^#{token_re}FINAL=(\{.*\})\n/, '') && Memory::Status.parse($1)
|
150
|
-
assert(status.success?, FailDesc[status, message, err])
|
151
|
-
([:size, (rss && :rss)] & after.members).each do |n|
|
152
|
-
b = before[n]
|
153
|
-
a = after[n]
|
154
|
-
next unless a > 0 and b > 0
|
155
|
-
assert_operator(a.fdiv(b), :<, limit, message(message) {"#{n}: #{b} => #{a}"})
|
156
|
-
end
|
157
|
-
rescue LoadError
|
158
|
-
pend
|
159
|
-
end
|
160
|
-
|
161
|
-
# :call-seq:
|
162
|
-
# assert_nothing_raised( *args, &block )
|
163
|
-
#
|
164
|
-
#If any exceptions are given as arguments, the assertion will
|
165
|
-
#fail if one of those exceptions are raised. Otherwise, the test fails
|
166
|
-
#if any exceptions are raised.
|
167
|
-
#
|
168
|
-
#The final argument may be a failure message.
|
169
|
-
#
|
170
|
-
# assert_nothing_raised RuntimeError do
|
171
|
-
# raise Exception #Assertion passes, Exception is not a RuntimeError
|
172
|
-
# end
|
173
|
-
#
|
174
|
-
# assert_nothing_raised do
|
175
|
-
# raise Exception #Assertion fails
|
176
|
-
# end
|
177
|
-
def assert_nothing_raised(*args)
|
178
|
-
self._assertions += 1
|
179
|
-
if Module === args.last
|
180
|
-
msg = nil
|
181
|
-
else
|
182
|
-
msg = args.pop
|
183
|
-
end
|
184
|
-
begin
|
185
|
-
line = __LINE__; yield
|
186
|
-
rescue MiniTest::Skip
|
187
|
-
raise
|
188
|
-
rescue Exception => e
|
189
|
-
bt = e.backtrace
|
190
|
-
as = e.instance_of?(MiniTest::Assertion)
|
191
|
-
if as
|
192
|
-
ans = /\A#{Regexp.quote(__FILE__)}:#{line}:in /o
|
193
|
-
bt.reject! {|ln| ans =~ ln}
|
194
|
-
end
|
195
|
-
if ((args.empty? && !as) ||
|
196
|
-
args.any? {|a| a.instance_of?(Module) ? e.is_a?(a) : e.class == a })
|
197
|
-
msg = message(msg) {
|
198
|
-
"Exception raised:\n<#{mu_pp(e)}>\n" +
|
199
|
-
"Backtrace:\n" +
|
200
|
-
e.backtrace.map{|frame| " #{frame}"}.join("\n")
|
201
|
-
}
|
202
|
-
raise MiniTest::Assertion, msg.call, bt
|
203
|
-
else
|
204
|
-
raise
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
def prepare_syntax_check(code, fname = nil, mesg = nil, verbose: nil)
|
210
|
-
fname ||= caller_locations(2, 1)[0]
|
211
|
-
mesg ||= fname.to_s
|
212
|
-
verbose, $VERBOSE = $VERBOSE, verbose
|
213
|
-
case
|
214
|
-
when Array === fname
|
215
|
-
fname, line = *fname
|
216
|
-
when defined?(fname.path) && defined?(fname.lineno)
|
217
|
-
fname, line = fname.path, fname.lineno
|
218
|
-
else
|
219
|
-
line = 1
|
220
|
-
end
|
221
|
-
yield(code, fname, line, message(mesg) {
|
222
|
-
if code.end_with?("\n")
|
223
|
-
"```\n#{code}```\n"
|
224
|
-
else
|
225
|
-
"```\n#{code}\n```\n""no-newline"
|
226
|
-
end
|
227
|
-
})
|
228
|
-
ensure
|
229
|
-
$VERBOSE = verbose
|
230
|
-
end
|
231
|
-
|
232
|
-
def assert_valid_syntax(code, *args, **opt)
|
233
|
-
prepare_syntax_check(code, *args, **opt) do |src, fname, line, mesg|
|
234
|
-
yield if defined?(yield)
|
235
|
-
assert_nothing_raised(SyntaxError, mesg) do
|
236
|
-
assert_equal(:ok, syntax_check(src, fname, line), mesg)
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
def assert_normal_exit(testsrc, message = '', child_env: nil, **opt)
|
242
|
-
assert_valid_syntax(testsrc, caller_locations(1, 1)[0])
|
243
|
-
if child_env
|
244
|
-
child_env = [child_env]
|
245
|
-
else
|
246
|
-
child_env = []
|
247
|
-
end
|
248
|
-
out, _, status = EnvUtil.invoke_ruby(child_env + %W'-W0', testsrc, true, :merge_to_stdout, **opt)
|
249
|
-
assert !status.signaled?, FailDesc[status, message, out]
|
250
|
-
end
|
251
|
-
|
252
|
-
def assert_ruby_status(args, test_stdin="", message=nil, **opt)
|
253
|
-
out, _, status = EnvUtil.invoke_ruby(args, test_stdin, true, :merge_to_stdout, **opt)
|
254
|
-
desc = FailDesc[status, message, out]
|
255
|
-
assert(!status.signaled?, desc)
|
256
|
-
message ||= "ruby exit status is not success:"
|
257
|
-
assert(status.success?, desc)
|
258
|
-
end
|
259
|
-
|
260
|
-
ABORT_SIGNALS = Signal.list.values_at(*%w"ILL ABRT BUS SEGV TERM")
|
261
|
-
|
262
|
-
def separated_runner(out = nil)
|
263
|
-
out = out ? IO.new(out, 'w') : STDOUT
|
264
|
-
at_exit {
|
265
|
-
out.puts [Marshal.dump($!)].pack('m'), "assertions=\#{self._assertions}"
|
266
|
-
}
|
267
|
-
Test::Unit::Runner.class_variable_set(:@@stop_auto_run, true) if defined?(Test::Unit::Runner)
|
268
|
-
end
|
269
|
-
|
270
|
-
def assert_separately(args, file = nil, line = nil, src, ignore_stderr: nil, **opt)
|
271
|
-
unless file and line
|
272
|
-
loc, = caller_locations(1,1)
|
273
|
-
file ||= loc.path
|
274
|
-
line ||= loc.lineno
|
275
|
-
end
|
276
|
-
capture_stdout = true
|
277
|
-
unless /mswin|mingw/ =~ RUBY_PLATFORM
|
278
|
-
capture_stdout = false
|
279
|
-
opt[:out] = MiniTest::Unit.output if defined?(MiniTest::Unit)
|
280
|
-
res_p, res_c = IO.pipe
|
281
|
-
opt[res_c.fileno] = res_c.fileno
|
282
|
-
end
|
283
|
-
src = <<eom
|
284
|
-
# -*- coding: #{line += __LINE__; src.encoding}; -*-
|
285
|
-
BEGIN {
|
286
|
-
require "test/unit";include Test::Unit::Assertions;require #{(__dir__ + "/core_assertions").dump};include Test::Unit::CoreAssertions
|
287
|
-
separated_runner #{res_c&.fileno}
|
288
|
-
}
|
289
|
-
#{line -= __LINE__; src}
|
290
|
-
eom
|
291
|
-
args = args.dup
|
292
|
-
args.insert((Hash === args.first ? 1 : 0), "-w", "--disable=gems", *$:.map {|l| "-I#{l}"})
|
293
|
-
stdout, stderr, status = EnvUtil.invoke_ruby(args, src, capture_stdout, true, **opt)
|
294
|
-
ensure
|
295
|
-
if res_c
|
296
|
-
res_c.close
|
297
|
-
res = res_p.read
|
298
|
-
res_p.close
|
299
|
-
else
|
300
|
-
res = stdout
|
301
|
-
end
|
302
|
-
raise if $!
|
303
|
-
abort = status.coredump? || (status.signaled? && ABORT_SIGNALS.include?(status.termsig))
|
304
|
-
assert(!abort, FailDesc[status, nil, stderr])
|
305
|
-
self._assertions += res[/^assertions=(\d+)/, 1].to_i
|
306
|
-
begin
|
307
|
-
res = Marshal.load(res.unpack1("m"))
|
308
|
-
rescue => marshal_error
|
309
|
-
ignore_stderr = nil
|
310
|
-
res = nil
|
311
|
-
end
|
312
|
-
if res and !(SystemExit === res)
|
313
|
-
if bt = res.backtrace
|
314
|
-
bt.each do |l|
|
315
|
-
l.sub!(/\A-:(\d+)/){"#{file}:#{line + $1.to_i}"}
|
316
|
-
end
|
317
|
-
bt.concat(caller)
|
318
|
-
else
|
319
|
-
res.set_backtrace(caller)
|
320
|
-
end
|
321
|
-
raise res
|
322
|
-
end
|
323
|
-
|
324
|
-
# really is it succeed?
|
325
|
-
unless ignore_stderr
|
326
|
-
# the body of assert_separately must not output anything to detect error
|
327
|
-
assert(stderr.empty?, FailDesc[status, "assert_separately failed with error message", stderr])
|
328
|
-
end
|
329
|
-
assert(status.success?, FailDesc[status, "assert_separately failed", stderr])
|
330
|
-
raise marshal_error if marshal_error
|
331
|
-
end
|
332
|
-
|
333
|
-
# Run Ractor-related test without influencing the main test suite
|
334
|
-
def assert_ractor(src, args: [], require: nil, require_relative: nil, file: nil, line: nil, ignore_stderr: nil, **opt)
|
335
|
-
return unless defined?(Ractor)
|
336
|
-
|
337
|
-
require = "require #{require.inspect}" if require
|
338
|
-
if require_relative
|
339
|
-
dir = File.dirname(caller_locations[0,1][0].absolute_path)
|
340
|
-
full_path = File.expand_path(require_relative, dir)
|
341
|
-
require = "#{require}; require #{full_path.inspect}"
|
342
|
-
end
|
343
|
-
|
344
|
-
assert_separately(args, file, line, <<~RUBY, ignore_stderr: ignore_stderr, **opt)
|
345
|
-
#{require}
|
346
|
-
previous_verbose = $VERBOSE
|
347
|
-
$VERBOSE = nil
|
348
|
-
Ractor.new {} # trigger initial warning
|
349
|
-
$VERBOSE = previous_verbose
|
350
|
-
#{src}
|
351
|
-
RUBY
|
352
|
-
end
|
353
|
-
|
354
|
-
# :call-seq:
|
355
|
-
# assert_throw( tag, failure_message = nil, &block )
|
356
|
-
#
|
357
|
-
#Fails unless the given block throws +tag+, returns the caught
|
358
|
-
#value otherwise.
|
359
|
-
#
|
360
|
-
#An optional failure message may be provided as the final argument.
|
361
|
-
#
|
362
|
-
# tag = Object.new
|
363
|
-
# assert_throw(tag, "#{tag} was not thrown!") do
|
364
|
-
# throw tag
|
365
|
-
# end
|
366
|
-
def assert_throw(tag, msg = nil)
|
367
|
-
ret = catch(tag) do
|
368
|
-
begin
|
369
|
-
yield(tag)
|
370
|
-
rescue UncaughtThrowError => e
|
371
|
-
thrown = e.tag
|
372
|
-
end
|
373
|
-
msg = message(msg) {
|
374
|
-
"Expected #{mu_pp(tag)} to have been thrown"\
|
375
|
-
"#{%Q[, not #{thrown}] if thrown}"
|
376
|
-
}
|
377
|
-
assert(false, msg)
|
378
|
-
end
|
379
|
-
assert(true)
|
380
|
-
ret
|
381
|
-
end
|
382
|
-
|
383
|
-
# :call-seq:
|
384
|
-
# assert_raise( *args, &block )
|
385
|
-
#
|
386
|
-
#Tests if the given block raises an exception. Acceptable exception
|
387
|
-
#types may be given as optional arguments. If the last argument is a
|
388
|
-
#String, it will be used as the error message.
|
389
|
-
#
|
390
|
-
# assert_raise do #Fails, no Exceptions are raised
|
391
|
-
# end
|
392
|
-
#
|
393
|
-
# assert_raise NameError do
|
394
|
-
# puts x #Raises NameError, so assertion succeeds
|
395
|
-
# end
|
396
|
-
def assert_raise(*exp, &b)
|
397
|
-
case exp.last
|
398
|
-
when String, Proc
|
399
|
-
msg = exp.pop
|
400
|
-
end
|
401
|
-
|
402
|
-
begin
|
403
|
-
yield
|
404
|
-
rescue MiniTest::Skip => e
|
405
|
-
return e if exp.include? MiniTest::Skip
|
406
|
-
raise e
|
407
|
-
rescue Exception => e
|
408
|
-
expected = exp.any? { |ex|
|
409
|
-
if ex.instance_of? Module then
|
410
|
-
e.kind_of? ex
|
411
|
-
else
|
412
|
-
e.instance_of? ex
|
413
|
-
end
|
414
|
-
}
|
415
|
-
|
416
|
-
assert expected, proc {
|
417
|
-
flunk(message(msg) {"#{mu_pp(exp)} exception expected, not #{mu_pp(e)}"})
|
418
|
-
}
|
419
|
-
|
420
|
-
return e
|
421
|
-
ensure
|
422
|
-
unless e
|
423
|
-
exp = exp.first if exp.size == 1
|
424
|
-
|
425
|
-
flunk(message(msg) {"#{mu_pp(exp)} expected but nothing was raised"})
|
426
|
-
end
|
427
|
-
end
|
428
|
-
end
|
429
|
-
|
430
|
-
# :call-seq:
|
431
|
-
# assert_raise_with_message(exception, expected, msg = nil, &block)
|
432
|
-
#
|
433
|
-
#Tests if the given block raises an exception with the expected
|
434
|
-
#message.
|
435
|
-
#
|
436
|
-
# assert_raise_with_message(RuntimeError, "foo") do
|
437
|
-
# nil #Fails, no Exceptions are raised
|
438
|
-
# end
|
439
|
-
#
|
440
|
-
# assert_raise_with_message(RuntimeError, "foo") do
|
441
|
-
# raise ArgumentError, "foo" #Fails, different Exception is raised
|
442
|
-
# end
|
443
|
-
#
|
444
|
-
# assert_raise_with_message(RuntimeError, "foo") do
|
445
|
-
# raise "bar" #Fails, RuntimeError is raised but the message differs
|
446
|
-
# end
|
447
|
-
#
|
448
|
-
# assert_raise_with_message(RuntimeError, "foo") do
|
449
|
-
# raise "foo" #Raises RuntimeError with the message, so assertion succeeds
|
450
|
-
# end
|
451
|
-
def assert_raise_with_message(exception, expected, msg = nil, &block)
|
452
|
-
case expected
|
453
|
-
when String
|
454
|
-
assert = :assert_equal
|
455
|
-
when Regexp
|
456
|
-
assert = :assert_match
|
457
|
-
else
|
458
|
-
raise TypeError, "Expected #{expected.inspect} to be a kind of String or Regexp, not #{expected.class}"
|
459
|
-
end
|
460
|
-
|
461
|
-
ex = m = nil
|
462
|
-
EnvUtil.with_default_internal(expected.encoding) do
|
463
|
-
ex = assert_raise(exception, msg || proc {"Exception(#{exception}) with message matches to #{expected.inspect}"}) do
|
464
|
-
yield
|
465
|
-
end
|
466
|
-
m = ex.message
|
467
|
-
end
|
468
|
-
msg = message(msg, "") {"Expected Exception(#{exception}) was raised, but the message doesn't match"}
|
469
|
-
|
470
|
-
if assert == :assert_equal
|
471
|
-
assert_equal(expected, m, msg)
|
472
|
-
else
|
473
|
-
msg = message(msg) { "Expected #{mu_pp expected} to match #{mu_pp m}" }
|
474
|
-
assert expected =~ m, msg
|
475
|
-
block.binding.eval("proc{|_|$~=_}").call($~)
|
476
|
-
end
|
477
|
-
ex
|
478
|
-
end
|
479
|
-
|
480
|
-
MINI_DIR = File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), "minitest") #:nodoc:
|
481
|
-
|
482
|
-
# :call-seq:
|
483
|
-
# assert(test, [failure_message])
|
484
|
-
#
|
485
|
-
#Tests if +test+ is true.
|
486
|
-
#
|
487
|
-
#+msg+ may be a String or a Proc. If +msg+ is a String, it will be used
|
488
|
-
#as the failure message. Otherwise, the result of calling +msg+ will be
|
489
|
-
#used as the message if the assertion fails.
|
490
|
-
#
|
491
|
-
#If no +msg+ is given, a default message will be used.
|
492
|
-
#
|
493
|
-
# assert(false, "This was expected to be true")
|
494
|
-
def assert(test, *msgs)
|
495
|
-
case msg = msgs.first
|
496
|
-
when String, Proc
|
497
|
-
when nil
|
498
|
-
msgs.shift
|
499
|
-
else
|
500
|
-
bt = caller.reject { |s| s.start_with?(MINI_DIR) }
|
501
|
-
raise ArgumentError, "assertion message must be String or Proc, but #{msg.class} was given.", bt
|
502
|
-
end unless msgs.empty?
|
503
|
-
super
|
504
|
-
end
|
505
|
-
|
506
|
-
# :call-seq:
|
507
|
-
# assert_respond_to( object, method, failure_message = nil )
|
508
|
-
#
|
509
|
-
#Tests if the given Object responds to +method+.
|
510
|
-
#
|
511
|
-
#An optional failure message may be provided as the final argument.
|
512
|
-
#
|
513
|
-
# assert_respond_to("hello", :reverse) #Succeeds
|
514
|
-
# assert_respond_to("hello", :does_not_exist) #Fails
|
515
|
-
def assert_respond_to(obj, (meth, *priv), msg = nil)
|
516
|
-
unless priv.empty?
|
517
|
-
msg = message(msg) {
|
518
|
-
"Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}#{" privately" if priv[0]}"
|
519
|
-
}
|
520
|
-
return assert obj.respond_to?(meth, *priv), msg
|
521
|
-
end
|
522
|
-
#get rid of overcounting
|
523
|
-
if caller_locations(1, 1)[0].path.start_with?(MINI_DIR)
|
524
|
-
return if obj.respond_to?(meth)
|
525
|
-
end
|
526
|
-
super(obj, meth, msg)
|
527
|
-
end
|
528
|
-
|
529
|
-
# :call-seq:
|
530
|
-
# assert_not_respond_to( object, method, failure_message = nil )
|
531
|
-
#
|
532
|
-
#Tests if the given Object does not respond to +method+.
|
533
|
-
#
|
534
|
-
#An optional failure message may be provided as the final argument.
|
535
|
-
#
|
536
|
-
# assert_not_respond_to("hello", :reverse) #Fails
|
537
|
-
# assert_not_respond_to("hello", :does_not_exist) #Succeeds
|
538
|
-
def assert_not_respond_to(obj, (meth, *priv), msg = nil)
|
539
|
-
unless priv.empty?
|
540
|
-
msg = message(msg) {
|
541
|
-
"Expected #{mu_pp(obj)} (#{obj.class}) to not respond to ##{meth}#{" privately" if priv[0]}"
|
542
|
-
}
|
543
|
-
return assert !obj.respond_to?(meth, *priv), msg
|
544
|
-
end
|
545
|
-
#get rid of overcounting
|
546
|
-
if caller_locations(1, 1)[0].path.start_with?(MINI_DIR)
|
547
|
-
return unless obj.respond_to?(meth)
|
548
|
-
end
|
549
|
-
refute_respond_to(obj, meth, msg)
|
550
|
-
end
|
551
|
-
|
552
|
-
# pattern_list is an array which contains regexp and :*.
|
553
|
-
# :* means any sequence.
|
554
|
-
#
|
555
|
-
# pattern_list is anchored.
|
556
|
-
# Use [:*, regexp, :*] for non-anchored match.
|
557
|
-
def assert_pattern_list(pattern_list, actual, message=nil)
|
558
|
-
rest = actual
|
559
|
-
anchored = true
|
560
|
-
pattern_list.each_with_index {|pattern, i|
|
561
|
-
if pattern == :*
|
562
|
-
anchored = false
|
563
|
-
else
|
564
|
-
if anchored
|
565
|
-
match = /\A#{pattern}/.match(rest)
|
566
|
-
else
|
567
|
-
match = pattern.match(rest)
|
568
|
-
end
|
569
|
-
unless match
|
570
|
-
msg = message(msg) {
|
571
|
-
expect_msg = "Expected #{mu_pp pattern}\n"
|
572
|
-
if /\n[^\n]/ =~ rest
|
573
|
-
actual_mesg = +"to match\n"
|
574
|
-
rest.scan(/.*\n+/) {
|
575
|
-
actual_mesg << ' ' << $&.inspect << "+\n"
|
576
|
-
}
|
577
|
-
actual_mesg.sub!(/\+\n\z/, '')
|
578
|
-
else
|
579
|
-
actual_mesg = "to match " + mu_pp(rest)
|
580
|
-
end
|
581
|
-
actual_mesg << "\nafter #{i} patterns with #{actual.length - rest.length} characters"
|
582
|
-
expect_msg + actual_mesg
|
583
|
-
}
|
584
|
-
assert false, msg
|
585
|
-
end
|
586
|
-
rest = match.post_match
|
587
|
-
anchored = true
|
588
|
-
end
|
589
|
-
}
|
590
|
-
if anchored
|
591
|
-
assert_equal("", rest)
|
592
|
-
end
|
593
|
-
end
|
594
|
-
|
595
|
-
def assert_warning(pat, msg = nil)
|
596
|
-
result = nil
|
597
|
-
stderr = EnvUtil.with_default_internal(pat.encoding) {
|
598
|
-
EnvUtil.verbose_warning {
|
599
|
-
result = yield
|
600
|
-
}
|
601
|
-
}
|
602
|
-
msg = message(msg) {diff pat, stderr}
|
603
|
-
assert(pat === stderr, msg)
|
604
|
-
result
|
605
|
-
end
|
606
|
-
|
607
|
-
def assert_warn(*args)
|
608
|
-
assert_warning(*args) {$VERBOSE = false; yield}
|
609
|
-
end
|
610
|
-
|
611
|
-
def assert_deprecated_warning(mesg = /deprecated/)
|
612
|
-
assert_warning(mesg) do
|
613
|
-
Warning[:deprecated] = true
|
614
|
-
yield
|
615
|
-
end
|
616
|
-
end
|
617
|
-
|
618
|
-
def assert_deprecated_warn(mesg = /deprecated/)
|
619
|
-
assert_warn(mesg) do
|
620
|
-
Warning[:deprecated] = true
|
621
|
-
yield
|
622
|
-
end
|
623
|
-
end
|
624
|
-
|
625
|
-
class << (AssertFile = Struct.new(:failure_message).new)
|
626
|
-
include CoreAssertions
|
627
|
-
def assert_file_predicate(predicate, *args)
|
628
|
-
if /\Anot_/ =~ predicate
|
629
|
-
predicate = $'
|
630
|
-
neg = " not"
|
631
|
-
end
|
632
|
-
result = File.__send__(predicate, *args)
|
633
|
-
result = !result if neg
|
634
|
-
mesg = "Expected file ".dup << args.shift.inspect
|
635
|
-
mesg << "#{neg} to be #{predicate}"
|
636
|
-
mesg << mu_pp(args).sub(/\A\[(.*)\]\z/m, '(\1)') unless args.empty?
|
637
|
-
mesg << " #{failure_message}" if failure_message
|
638
|
-
assert(result, mesg)
|
639
|
-
end
|
640
|
-
alias method_missing assert_file_predicate
|
641
|
-
|
642
|
-
def for(message)
|
643
|
-
clone.tap {|a| a.failure_message = message}
|
644
|
-
end
|
645
|
-
end
|
646
|
-
|
647
|
-
class AllFailures
|
648
|
-
attr_reader :failures
|
649
|
-
|
650
|
-
def initialize
|
651
|
-
@count = 0
|
652
|
-
@failures = {}
|
653
|
-
end
|
654
|
-
|
655
|
-
def for(key)
|
656
|
-
@count += 1
|
657
|
-
yield
|
658
|
-
rescue Exception => e
|
659
|
-
@failures[key] = [@count, e]
|
660
|
-
end
|
661
|
-
|
662
|
-
def foreach(*keys)
|
663
|
-
keys.each do |key|
|
664
|
-
@count += 1
|
665
|
-
begin
|
666
|
-
yield key
|
667
|
-
rescue Exception => e
|
668
|
-
@failures[key] = [@count, e]
|
669
|
-
end
|
670
|
-
end
|
671
|
-
end
|
672
|
-
|
673
|
-
def message
|
674
|
-
i = 0
|
675
|
-
total = @count.to_s
|
676
|
-
fmt = "%#{total.size}d"
|
677
|
-
@failures.map {|k, (n, v)|
|
678
|
-
v = v.message
|
679
|
-
"\n#{i+=1}. [#{fmt%n}/#{total}] Assertion for #{k.inspect}\n#{v.b.gsub(/^/, ' | ').force_encoding(v.encoding)}"
|
680
|
-
}.join("\n")
|
681
|
-
end
|
682
|
-
|
683
|
-
def pass?
|
684
|
-
@failures.empty?
|
685
|
-
end
|
686
|
-
end
|
687
|
-
|
688
|
-
# threads should respond to shift method.
|
689
|
-
# Array can be used.
|
690
|
-
def assert_join_threads(threads, message = nil)
|
691
|
-
errs = []
|
692
|
-
values = []
|
693
|
-
while th = threads.shift
|
694
|
-
begin
|
695
|
-
values << th.value
|
696
|
-
rescue Exception
|
697
|
-
errs << [th, $!]
|
698
|
-
th = nil
|
699
|
-
end
|
700
|
-
end
|
701
|
-
values
|
702
|
-
ensure
|
703
|
-
if th&.alive?
|
704
|
-
th.raise(Timeout::Error.new)
|
705
|
-
th.join rescue errs << [th, $!]
|
706
|
-
end
|
707
|
-
if !errs.empty?
|
708
|
-
msg = "exceptions on #{errs.length} threads:\n" +
|
709
|
-
errs.map {|t, err|
|
710
|
-
"#{t.inspect}:\n" +
|
711
|
-
RUBY_VERSION >= "2.5.0" ? err.full_message(highlight: false, order: :top) : err.message
|
712
|
-
}.join("\n---\n")
|
713
|
-
if message
|
714
|
-
msg = "#{message}\n#{msg}"
|
715
|
-
end
|
716
|
-
raise MiniTest::Assertion, msg
|
717
|
-
end
|
718
|
-
end
|
719
|
-
|
720
|
-
def assert_all_assertions(msg = nil)
|
721
|
-
all = AllFailures.new
|
722
|
-
yield all
|
723
|
-
ensure
|
724
|
-
assert(all.pass?, message(msg) {all.message.chomp(".")})
|
725
|
-
end
|
726
|
-
alias all_assertions assert_all_assertions
|
727
|
-
|
728
|
-
def message(msg = nil, *args, &default) # :nodoc:
|
729
|
-
if Proc === msg
|
730
|
-
super(nil, *args) do
|
731
|
-
ary = [msg.call, (default.call if default)].compact.reject(&:empty?)
|
732
|
-
if 1 < ary.length
|
733
|
-
ary[0...-1] = ary[0...-1].map {|str| str.sub(/(?<!\.)\z/, '.') }
|
734
|
-
end
|
735
|
-
begin
|
736
|
-
ary.join("\n")
|
737
|
-
rescue Encoding::CompatibilityError
|
738
|
-
ary.map(&:b).join("\n")
|
739
|
-
end
|
740
|
-
end
|
741
|
-
else
|
742
|
-
super
|
743
|
-
end
|
744
|
-
end
|
745
|
-
|
746
|
-
def diff(exp, act)
|
747
|
-
require 'pp'
|
748
|
-
q = PP.new(+"")
|
749
|
-
q.guard_inspect_key do
|
750
|
-
q.group(2, "expected: ") do
|
751
|
-
q.pp exp
|
752
|
-
end
|
753
|
-
q.text q.newline
|
754
|
-
q.group(2, "actual: ") do
|
755
|
-
q.pp act
|
756
|
-
end
|
757
|
-
q.flush
|
758
|
-
end
|
759
|
-
q.output
|
760
|
-
end
|
761
|
-
end
|
762
|
-
end
|
763
|
-
end
|