minitest 5.16.0 → 5.16.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +24 -0
- data/README.rdoc +2 -1
- data/lib/minitest/mock.rb +45 -13
- data/lib/minitest/test.rb +11 -4
- data/lib/minitest/test_task.rb +1 -1
- data/lib/minitest.rb +1 -1
- data/test/minitest/test_minitest_mock.rb +98 -1
- data/test/minitest/test_minitest_test.rb +90 -0
- data.tar.gz.sig +2 -1
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c5a4db9f495b34c86f2c39eef6b6d424b22d8d9e6a86038bf0ff84c1c20c975
|
4
|
+
data.tar.gz: b8a1b6cb226d14c6972460bec05ec610d05acdfa0edcffe19bf51e8220486206
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6505a8f386da89263a005ba8eef3f81053e7e666a54ec03abd8f71e06c290ebf318df4f7728e420e3f40fab55ffe1a57824ec435286c89864ea830d330d6b028
|
7
|
+
data.tar.gz: 5b8bbba7d8565026e64da1d3af31a5aa342c3d063acd75de9661bc09fb142f4a469e9febf44daf2764d4fb33021d993a27bd936200efded501158b23c299989e
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
=== 5.16.3 / 2022-08-17
|
2
|
+
|
3
|
+
* 2 bug fixes:
|
4
|
+
|
5
|
+
* Fixed exception sanitization by removing TypeError restriction on rescue.
|
6
|
+
* Use A instead of deprecated TESTOPTS in rake test:slow. (davidstosik)
|
7
|
+
|
8
|
+
=== 5.16.2 / 2022-07-03
|
9
|
+
|
10
|
+
* 4 bug fixes:
|
11
|
+
|
12
|
+
* Added MT_KWARGS_HACK kludge for stub to deal with ruby 2.7 kwargs nastiness. (tsugimoto)
|
13
|
+
* In #expect, pop Hash class from args if $MT_KWARGS_HACK. (casperisfine)
|
14
|
+
* In above scenario, set expected kwargs (as Objects) based on actual kwargs.
|
15
|
+
* Nuke ivars if exception fails to marshal twice (eg better_errors). (irphilli)
|
16
|
+
|
17
|
+
=== 5.16.1 / 2022-06-20
|
18
|
+
|
19
|
+
* 2 bug fixes:
|
20
|
+
|
21
|
+
* Apparently adding real kwarg support to mocks/stubs broke some code. Fixed.
|
22
|
+
* Use `MT_KWARGS_HACK=1` to activate the kludgy kwargs support w/ caveats.
|
23
|
+
* Clarified some doco wrt the block on #stub.
|
24
|
+
|
1
25
|
=== 5.16.0 / 2022-06-14
|
2
26
|
|
3
27
|
* 2 major enhancements:
|
data/README.rdoc
CHANGED
@@ -641,6 +641,7 @@ minitest-capistrano :: Assertions and expectations for testing
|
|
641
641
|
Capistrano recipes.
|
642
642
|
minitest-capybara :: Capybara matchers support for minitest unit and
|
643
643
|
spec.
|
644
|
+
minitest-cc :: It provides minimal information about code coverage.
|
644
645
|
minitest-chef-handler :: Run Minitest suites as Chef report handlers
|
645
646
|
minitest-ci :: CI reporter plugin for Minitest.
|
646
647
|
minitest-context :: Defines contexts for code reuse in Minitest
|
@@ -739,7 +740,7 @@ minitest-stub-const :: Stub constants for the duration of a block.
|
|
739
740
|
minitest-tags :: Add tags for minitest.
|
740
741
|
minitest-unordered :: Adds a new assertion to minitest for checking the
|
741
742
|
contents of a collection, ignoring element order.
|
742
|
-
minitest-vcr :: Automatic cassette
|
743
|
+
minitest-vcr :: Automatic cassette management with Minitest::Spec
|
743
744
|
and VCR.
|
744
745
|
minitest_log :: Adds structured logging, data explication, and verdicts.
|
745
746
|
minitest_owrapper :: Get tests results as a TestResult object.
|
data/lib/minitest/mock.rb
CHANGED
@@ -51,6 +51,8 @@ module Minitest # :nodoc:
|
|
51
51
|
@actual_calls = Hash.new { |calls, name| calls[name] = [] }
|
52
52
|
end
|
53
53
|
|
54
|
+
@@KW_WARNED = false # :nodoc:
|
55
|
+
|
54
56
|
##
|
55
57
|
# Expect that method +name+ is called, optionally with +args+ (and
|
56
58
|
# +kwargs+ or a +blk+, and returns +retval+.
|
@@ -91,10 +93,26 @@ module Minitest # :nodoc:
|
|
91
93
|
|
92
94
|
if block_given?
|
93
95
|
raise ArgumentError, "args ignored when block given" unless args.empty?
|
96
|
+
raise ArgumentError, "kwargs ignored when block given" unless kwargs.empty?
|
94
97
|
@expected_calls[name] << { :retval => retval, :block => blk }
|
95
98
|
else
|
96
99
|
raise ArgumentError, "args must be an array" unless Array === args
|
97
|
-
|
100
|
+
|
101
|
+
if ENV["MT_KWARGS_HAC\K"] && (Hash === args.last ||
|
102
|
+
Hash == args.last) then
|
103
|
+
if kwargs.empty? then
|
104
|
+
kwargs = args.pop
|
105
|
+
else
|
106
|
+
unless @@KW_WARNED then
|
107
|
+
from = caller.first
|
108
|
+
warn "Using MT_KWARGS_HAC\K yet passing kwargs. From #{from}"
|
109
|
+
@@KW_WARNED = true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
@expected_calls[name] <<
|
115
|
+
{ :retval => retval, :args => args, :kwargs => kwargs }
|
98
116
|
end
|
99
117
|
self
|
100
118
|
end
|
@@ -150,6 +168,9 @@ module Minitest # :nodoc:
|
|
150
168
|
expected_args, expected_kwargs, retval, val_block =
|
151
169
|
expected_call.values_at(:args, :kwargs, :retval, :block)
|
152
170
|
|
171
|
+
expected_kwargs = kwargs.map { |ak, av| [ak, Object] }.to_h if
|
172
|
+
Hash == expected_kwargs
|
173
|
+
|
153
174
|
if val_block then
|
154
175
|
# keep "verify" happy
|
155
176
|
@actual_calls[sym] << expected_call
|
@@ -250,7 +271,7 @@ class Object
|
|
250
271
|
# NOTE: keyword args in callables are NOT checked for correctness
|
251
272
|
# against the existing method. Too many edge cases to be worth it.
|
252
273
|
|
253
|
-
def stub name, val_or_callable, *block_args, **block_kwargs
|
274
|
+
def stub name, val_or_callable, *block_args, **block_kwargs, &block
|
254
275
|
new_name = "__minitest_stub__#{name}"
|
255
276
|
|
256
277
|
metaclass = class << self; self; end
|
@@ -263,26 +284,37 @@ class Object
|
|
263
284
|
|
264
285
|
metaclass.send :alias_method, new_name, name
|
265
286
|
|
266
|
-
|
267
|
-
|
268
|
-
if
|
287
|
+
if ENV["MT_KWARGS_HAC\K"] then
|
288
|
+
metaclass.send :define_method, name do |*args, &blk|
|
289
|
+
if val_or_callable.respond_to? :call then
|
269
290
|
val_or_callable.call(*args, &blk)
|
270
291
|
else
|
271
|
-
|
292
|
+
blk.call(*block_args, **block_kwargs) if blk
|
293
|
+
val_or_callable
|
272
294
|
end
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
295
|
+
end
|
296
|
+
else
|
297
|
+
metaclass.send :define_method, name do |*args, **kwargs, &blk|
|
298
|
+
if val_or_callable.respond_to? :call then
|
299
|
+
if kwargs.empty? then # FIX: drop this after 2.7 dead
|
300
|
+
val_or_callable.call(*args, &blk)
|
277
301
|
else
|
278
|
-
|
302
|
+
val_or_callable.call(*args, **kwargs, &blk)
|
303
|
+
end
|
304
|
+
else
|
305
|
+
if blk then
|
306
|
+
if block_kwargs.empty? then # FIX: drop this after 2.7 dead
|
307
|
+
blk.call(*block_args)
|
308
|
+
else
|
309
|
+
blk.call(*block_args, **block_kwargs)
|
310
|
+
end
|
279
311
|
end
|
312
|
+
val_or_callable
|
280
313
|
end
|
281
|
-
val_or_callable
|
282
314
|
end
|
283
315
|
end
|
284
316
|
|
285
|
-
|
317
|
+
block[self]
|
286
318
|
ensure
|
287
319
|
metaclass.send :undef_method, name
|
288
320
|
metaclass.send :alias_method, name, new_name
|
data/lib/minitest/test.rb
CHANGED
@@ -204,7 +204,7 @@ module Minitest
|
|
204
204
|
def sanitize_exception e # :nodoc:
|
205
205
|
Marshal.dump e
|
206
206
|
e # good: use as-is
|
207
|
-
rescue
|
207
|
+
rescue
|
208
208
|
neuter_exception e
|
209
209
|
end
|
210
210
|
|
@@ -213,15 +213,22 @@ module Minitest
|
|
213
213
|
msg = e.message.dup
|
214
214
|
|
215
215
|
new_exception e.class, msg, bt # e.class can be a problem...
|
216
|
-
rescue
|
216
|
+
rescue
|
217
217
|
msg.prepend "Neutered Exception #{e.class}: "
|
218
218
|
|
219
|
-
new_exception RuntimeError, msg, bt
|
219
|
+
new_exception RuntimeError, msg, bt, true # but if this raises, we die
|
220
220
|
end
|
221
221
|
|
222
|
-
def new_exception klass, msg, bt
|
222
|
+
def new_exception klass, msg, bt, kill = false
|
223
223
|
ne = klass.new msg
|
224
224
|
ne.set_backtrace bt
|
225
|
+
|
226
|
+
if kill then
|
227
|
+
ne.instance_variables.each do |v|
|
228
|
+
ne.remove_instance_variable v
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
225
232
|
Marshal.dump ne # can raise TypeError
|
226
233
|
ne
|
227
234
|
end
|
data/lib/minitest/test_task.rb
CHANGED
data/lib/minitest.rb
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
require "minitest/autorun"
|
2
2
|
|
3
|
+
def with_kwargs_env
|
4
|
+
ENV["MT_KWARGS_HAC\K"] = "1"
|
5
|
+
|
6
|
+
yield
|
7
|
+
ensure
|
8
|
+
ENV.delete "MT_KWARGS_HAC\K"
|
9
|
+
end
|
10
|
+
|
3
11
|
class TestMinitestMock < Minitest::Test
|
4
12
|
parallelize_me!
|
5
13
|
|
@@ -363,6 +371,61 @@ class TestMinitestMock < Minitest::Test
|
|
363
371
|
assert_mock mock
|
364
372
|
end
|
365
373
|
|
374
|
+
def test_mock_allow_all_kwargs__old_style_env
|
375
|
+
with_kwargs_env do
|
376
|
+
mock = Minitest::Mock.new
|
377
|
+
mock.expect :foo, true, [Hash]
|
378
|
+
assert_equal true, mock.foo(bar: 42)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
def test_mock_allow_all_kwargs__old_style_env__rewrite
|
383
|
+
with_kwargs_env do
|
384
|
+
mock = Minitest::Mock.new
|
385
|
+
mock.expect :foo, true, [], bar: Integer
|
386
|
+
assert_equal true, mock.foo(bar: 42)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
def test_mock_block_is_passed_keyword_args__args__old_style_bad
|
391
|
+
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
|
392
|
+
mock = Minitest::Mock.new
|
393
|
+
mock.expect :foo, nil, [{k1: arg1, k2: arg2, k3: arg3}]
|
394
|
+
|
395
|
+
e = assert_raises ArgumentError do
|
396
|
+
mock.foo(k1: arg1, k2: arg2, k3: arg3)
|
397
|
+
end
|
398
|
+
|
399
|
+
assert_equal "mocked method :foo expects 1 arguments, got []", e.message
|
400
|
+
end
|
401
|
+
|
402
|
+
def test_mock_block_is_passed_keyword_args__args__old_style_env
|
403
|
+
with_kwargs_env do
|
404
|
+
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
|
405
|
+
mock = Minitest::Mock.new
|
406
|
+
mock.expect :foo, nil, [{k1: arg1, k2: arg2, k3: arg3}]
|
407
|
+
|
408
|
+
mock.foo(k1: arg1, k2: arg2, k3: arg3)
|
409
|
+
|
410
|
+
assert_mock mock
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
def test_mock_block_is_passed_keyword_args__args__old_style_both
|
415
|
+
with_kwargs_env do
|
416
|
+
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
|
417
|
+
mock = Minitest::Mock.new
|
418
|
+
|
419
|
+
assert_output nil, /Using MT_KWARGS_HAC. yet passing kwargs/ do
|
420
|
+
mock.expect :foo, nil, [{}], k1: arg1, k2: arg2, k3: arg3
|
421
|
+
end
|
422
|
+
|
423
|
+
mock.foo({}, k1: arg1, k2: arg2, k3: arg3)
|
424
|
+
|
425
|
+
assert_mock mock
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
366
429
|
def test_mock_block_is_passed_keyword_args__args_bad_missing
|
367
430
|
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
|
368
431
|
mock = Minitest::Mock.new
|
@@ -442,7 +505,7 @@ class TestMinitestMock < Minitest::Test
|
|
442
505
|
assert_equal exp, e.message
|
443
506
|
end
|
444
507
|
|
445
|
-
def
|
508
|
+
def test_mock_block_raises_if_args_passed
|
446
509
|
mock = Minitest::Mock.new
|
447
510
|
|
448
511
|
e = assert_raises(ArgumentError) do
|
@@ -456,6 +519,20 @@ class TestMinitestMock < Minitest::Test
|
|
456
519
|
assert_match exp, e.message
|
457
520
|
end
|
458
521
|
|
522
|
+
def test_mock_block_raises_if_kwargs_passed
|
523
|
+
mock = Minitest::Mock.new
|
524
|
+
|
525
|
+
e = assert_raises(ArgumentError) do
|
526
|
+
mock.expect :foo, nil, kwargs:1 do
|
527
|
+
true
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
exp = "kwargs ignored when block given"
|
532
|
+
|
533
|
+
assert_match exp, e.message
|
534
|
+
end
|
535
|
+
|
459
536
|
def test_mock_returns_retval_when_called_with_block
|
460
537
|
mock = Minitest::Mock.new
|
461
538
|
mock.expect(:foo, 32) do
|
@@ -761,6 +838,26 @@ class TestMinitestStub < Minitest::Test
|
|
761
838
|
end
|
762
839
|
end
|
763
840
|
|
841
|
+
def test_stub__hash_as_last_real_arg
|
842
|
+
with_kwargs_env do
|
843
|
+
token = Object.new
|
844
|
+
def token.create_with_retry u, p; raise "shouldn't see this"; end
|
845
|
+
|
846
|
+
controller = Object.new
|
847
|
+
controller.define_singleton_method :create do |u, p|
|
848
|
+
token.create_with_retry u, p
|
849
|
+
end
|
850
|
+
|
851
|
+
params = Object.new
|
852
|
+
def params.to_hash; raise "nah"; end
|
853
|
+
|
854
|
+
token.stub(:create_with_retry, ->(u, p) { 42 }) do
|
855
|
+
act = controller.create :u, params
|
856
|
+
@tc.assert_equal 42, act
|
857
|
+
end
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
764
861
|
def test_stub_callable_block_5 # from tenderlove
|
765
862
|
@assertion_count += 1
|
766
863
|
Foo.stub5 :blocking, Bar.new do
|
@@ -786,6 +786,13 @@ class TestMinitestUnitOrder < MetaMetaMetaTestCase
|
|
786
786
|
end
|
787
787
|
end
|
788
788
|
|
789
|
+
class BetterError < RuntimeError # like better_error w/o infecting RuntimeError
|
790
|
+
def set_backtrace bt
|
791
|
+
super
|
792
|
+
@bad_ivar = binding
|
793
|
+
end
|
794
|
+
end
|
795
|
+
|
789
796
|
class TestMinitestRunnable < Minitest::Test
|
790
797
|
def setup_marshal klass
|
791
798
|
tc = klass.new "whatever"
|
@@ -895,6 +902,89 @@ class TestMinitestRunnable < Minitest::Test
|
|
895
902
|
assert_equal @tc.failures, over_the_wire.failures
|
896
903
|
assert_equal @tc.klass, over_the_wire.klass
|
897
904
|
end
|
905
|
+
|
906
|
+
def with_runtime_error klass
|
907
|
+
old_runtime = RuntimeError
|
908
|
+
Object.send :remove_const, :RuntimeError
|
909
|
+
Object.const_set :RuntimeError, klass
|
910
|
+
yield
|
911
|
+
ensure
|
912
|
+
Object.send :remove_const, :RuntimeError
|
913
|
+
Object.const_set :RuntimeError, old_runtime
|
914
|
+
end
|
915
|
+
|
916
|
+
def test_spec_marshal_with_exception__better_error_typeerror
|
917
|
+
klass = describe("whatever") {
|
918
|
+
it("raises with binding") {
|
919
|
+
raise BetterError, "boom"
|
920
|
+
}
|
921
|
+
}
|
922
|
+
|
923
|
+
rm = klass.runnable_methods.first
|
924
|
+
|
925
|
+
# Run the test
|
926
|
+
@tc = with_runtime_error BetterError do
|
927
|
+
klass.new(rm).run
|
928
|
+
end
|
929
|
+
|
930
|
+
assert_kind_of Minitest::Result, @tc
|
931
|
+
assert_instance_of Minitest::UnexpectedError, @tc.failure
|
932
|
+
|
933
|
+
msg = @tc.failure.error.message
|
934
|
+
assert_equal "Neutered Exception BetterError: boom", msg
|
935
|
+
|
936
|
+
# Pass it over the wire
|
937
|
+
over_the_wire = Marshal.load Marshal.dump @tc
|
938
|
+
|
939
|
+
assert_equal @tc.time, over_the_wire.time
|
940
|
+
assert_equal @tc.name, over_the_wire.name
|
941
|
+
assert_equal @tc.assertions, over_the_wire.assertions
|
942
|
+
assert_equal @tc.failures, over_the_wire.failures
|
943
|
+
assert_equal @tc.klass, over_the_wire.klass
|
944
|
+
end
|
945
|
+
|
946
|
+
def test_spec_marshal_with_exception__worse_error_typeerror
|
947
|
+
worse_error_klass = Class.new(StandardError) do
|
948
|
+
# problem #1: anonymous subclass can'tmarshal, fails sanitize_exception
|
949
|
+
def initialize(record = nil)
|
950
|
+
|
951
|
+
super(record.first)
|
952
|
+
end
|
953
|
+
end
|
954
|
+
|
955
|
+
klass = describe("whatever") {
|
956
|
+
it("raises with NoMethodError") {
|
957
|
+
# problem #2: instantiated with a NON-string argument
|
958
|
+
#
|
959
|
+
# problem #3: arg responds to #first, but it becomes message
|
960
|
+
# which gets passed back in via new_exception
|
961
|
+
# that passes a string to worse_error_klass#initialize
|
962
|
+
# which calls first on it, which raises NoMethodError
|
963
|
+
raise worse_error_klass.new(["boom"])
|
964
|
+
}
|
965
|
+
}
|
966
|
+
|
967
|
+
rm = klass.runnable_methods.first
|
968
|
+
|
969
|
+
# Run the test
|
970
|
+
@tc = klass.new(rm).run
|
971
|
+
|
972
|
+
assert_kind_of Minitest::Result, @tc
|
973
|
+
assert_instance_of Minitest::UnexpectedError, @tc.failure
|
974
|
+
|
975
|
+
msg = @tc.failure.error.message.gsub(/0x[A-Fa-f0-9]+/, "0xXXX")
|
976
|
+
|
977
|
+
assert_equal "Neutered Exception #<Class:0xXXX>: boom", msg
|
978
|
+
|
979
|
+
# Pass it over the wire
|
980
|
+
over_the_wire = Marshal.load Marshal.dump @tc
|
981
|
+
|
982
|
+
assert_equal @tc.time, over_the_wire.time
|
983
|
+
assert_equal @tc.name, over_the_wire.name
|
984
|
+
assert_equal @tc.assertions, over_the_wire.assertions
|
985
|
+
assert_equal @tc.failures, over_the_wire.failures
|
986
|
+
assert_equal @tc.klass, over_the_wire.klass
|
987
|
+
end
|
898
988
|
end
|
899
989
|
|
900
990
|
class TestMinitestTest < TestMinitestRunnable
|
data.tar.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
��#3)�~<Lp1���=�ܞb���qG���,]�x,_�.f��� ��|Wqn�g�:����ۊ���-5
|
2
|
+
�3WP�fG&�����TU�5���tj�Ͷ�AoRvn�ܿ����h��������V�ڌ�Xh3�Gp��g���|\%d�L�Y#��D�e�=p�={����t�,I���L�����i���2-��$�~�z����]6F�M{t/֦yϭ
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minitest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.16.
|
4
|
+
version: 5.16.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
@@ -29,7 +29,7 @@ cert_chain:
|
|
29
29
|
JFmxn4h9YO/pVdB962BdBNNDia0kgIjI3ENnkLq0dKpYU3+F3KhEuTksLO0L6X/V
|
30
30
|
YsuyUzsMz6GQA4khyaMgKNSD
|
31
31
|
-----END CERTIFICATE-----
|
32
|
-
date: 2022-
|
32
|
+
date: 2022-08-17 00:00:00.000000000 Z
|
33
33
|
dependencies:
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: rdoc
|
@@ -57,14 +57,14 @@ dependencies:
|
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '3.
|
60
|
+
version: '3.24'
|
61
61
|
type: :development
|
62
62
|
prerelease: false
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '3.
|
67
|
+
version: '3.24'
|
68
68
|
description: |-
|
69
69
|
minitest provides a complete suite of testing facilities supporting
|
70
70
|
TDD, BDD, mocking, and benchmarking.
|
metadata.gz.sig
CHANGED
Binary file
|