minitest-verify 0.1.0 → 0.1.1
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.md +10 -10
- data/Rakefile +5 -2
- data/lib/minitest/verify/version.rb +1 -1
- data/lib/minitest/verify.rb +27 -36
- data/lib/minitest/verify_plugin.rb +3 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2464bb648cf544989dd202a1306d3fc0e90739249eb5bc9e34887fe0ed47d0c7
|
4
|
+
data.tar.gz: 99d318563f2241dc9d3da3a7cb0a882096a2742198c51eeca2c9d819d14fc310
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5fe05ddf58dfd01f4aa7889420f34df579b7583bc692990faa896004508e2ae0bbc8e022af3c485cfc52cb5aeb02b32d9d1eaaf67f53db689542206c1382ef1
|
7
|
+
data.tar.gz: 2e80275d96ebf402943f33387a6caf99a99d400155c1d72d604d719355cd54427668e87a2f835d44a0e204477358bae9f734a4de9f682366c5e9082439e14342
|
data/README.md
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
# Minitest::Verify
|
2
2
|
|
3
|
-
Avoid false
|
3
|
+
Avoid false negative tests by verifying they fail when key setup is removed.
|
4
4
|
|
5
|
-
|
5
|
+
This is a quick proof-of-concept minitest plugin, but it mostly works fine!
|
6
6
|
|
7
|
-
|
7
|
+
## Installation
|
8
8
|
|
9
9
|
Install the gem and add to the application's Gemfile by executing:
|
10
10
|
|
11
|
-
$ bundle add
|
11
|
+
$ bundle add minitest-verify
|
12
12
|
|
13
13
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
14
14
|
|
15
|
-
$ gem install
|
15
|
+
$ gem install minitest-verify
|
16
16
|
|
17
17
|
## Usage
|
18
18
|
|
19
|
-
This is a false
|
19
|
+
This is a false negative test. It always passes because `post` and `comment` are completely unrelated: there's no reason `post.comments` would ever include `comment`.
|
20
20
|
|
21
21
|
```rb
|
22
22
|
require "minitest/autorun"
|
@@ -57,18 +57,18 @@ Now run the test with the `--verify` argument:
|
|
57
57
|
$ ruby post_test.rb --verify
|
58
58
|
```
|
59
59
|
|
60
|
-
This will cause the test to run twice. First it runs _with_ the contents of the `verify_fails_without` block evaluated (normal run). Then it runs _without_ the contents of the `verify_fails_without` block evaluated (verification run). If the test still passes without having evaluated the code inside the block, it's a false
|
60
|
+
This will cause the test to run twice. First it runs _with_ the contents of the `verify_fails_without` block evaluated (normal run). Then it runs _without_ the contents of the `verify_fails_without` block evaluated (verification run). If the test still passes without having evaluated the code inside the block, it's a false negative and you'll see a verification failure in your test output:
|
61
61
|
|
62
62
|
```
|
63
63
|
# Running:
|
64
64
|
|
65
|
-
|
65
|
+
F
|
66
66
|
|
67
67
|
Finished in 0.000380s, 2631.5783 runs/s, 5263.1565 assertions/s.
|
68
68
|
|
69
|
-
1)
|
69
|
+
1) Failure:
|
70
70
|
PostTest#test_comments_excludes_hidden_comments [post_test.rb:11]:
|
71
71
|
Expected at least one assertion to fail.
|
72
72
|
|
73
|
-
1 runs, 2 assertions,
|
73
|
+
1 runs, 2 assertions, 1 failures, 0 errors, 0 skips
|
74
74
|
```
|
data/Rakefile
CHANGED
data/lib/minitest/verify.rb
CHANGED
@@ -6,45 +6,39 @@ module Minitest
|
|
6
6
|
module Verify
|
7
7
|
class VerificationFailedError < StandardError; end
|
8
8
|
|
9
|
-
class VerificationFailure < Minitest::Assertion
|
10
|
-
def result_label
|
11
|
-
"Verification Failure"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class VerificationError < Minitest::UnexpectedError
|
16
|
-
def result_label
|
17
|
-
"Verification Error"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
9
|
class << self
|
22
10
|
attr_accessor :enabled
|
23
11
|
end
|
24
12
|
|
25
13
|
def verify_fails_without(&block)
|
26
14
|
if @current_caller
|
27
|
-
|
15
|
+
# If @current_caller is set, we are in the verification phase.
|
16
|
+
# Evaluate the block unless it is the one currently being verified.
|
17
|
+
block.call unless caller(1..1).first == @current_caller[0]
|
28
18
|
else
|
19
|
+
# If @current_caller is not set, we're in the normal test phase.
|
20
|
+
# Collect the caller (there might be multiple per test) and evaluate the block.
|
29
21
|
callers << caller
|
30
22
|
block.call
|
31
23
|
end
|
32
24
|
end
|
33
25
|
|
34
26
|
def run
|
35
|
-
|
27
|
+
# If verification is disabled, run the test normally.
|
28
|
+
return super unless Verify.enabled
|
36
29
|
|
37
|
-
|
30
|
+
super
|
38
31
|
|
39
|
-
|
40
|
-
failures.
|
32
|
+
# If there are normal failures, don't run verification.
|
33
|
+
return Result.from(self) if failures.any?
|
41
34
|
|
42
35
|
begin
|
43
|
-
|
36
|
+
# For each caller, run the test again and verify that it fails.
|
37
|
+
while (@current_caller = callers.shift)
|
44
38
|
with_verification { super }
|
45
39
|
end
|
46
40
|
rescue VerificationFailedError
|
47
|
-
|
41
|
+
# If verification fails, break out of the loop.
|
48
42
|
end
|
49
43
|
|
50
44
|
Result.from(self)
|
@@ -59,27 +53,24 @@ module Minitest
|
|
59
53
|
def with_verification
|
60
54
|
yield
|
61
55
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
failures.clear
|
66
|
-
failures.concat(@normal_failures)
|
67
|
-
|
68
|
-
if unexpected_errors.any?
|
69
|
-
unexpected_errors.each do |unexpected_error|
|
70
|
-
failures << VerificationError.new(unexpected_error.error)
|
71
|
-
end
|
72
|
-
|
56
|
+
# Fail verification if there is an unexpected error.
|
57
|
+
# Encountering an unexpected error doesn't imply the test is not a false negative, it might just be broken.
|
58
|
+
if failures.any? { |f| f.is_a?(Minitest::UnexpectedError) }
|
73
59
|
raise VerificationFailedError
|
74
60
|
end
|
75
61
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
raise VerificationFailedError
|
62
|
+
# Remove all assertion failures so the failing test passes.
|
63
|
+
# If at least one was removed, the test is not a false negative.
|
64
|
+
if failures.reject! { |f| f.is_a?(Minitest::Assertion) }
|
65
|
+
return
|
82
66
|
end
|
67
|
+
|
68
|
+
# If there were no assertion failures, we probably have a false negative.
|
69
|
+
exception = Minitest::Assertion.new("Expected at least one assertion to fail.")
|
70
|
+
exception.set_backtrace(@current_caller)
|
71
|
+
failures << exception
|
72
|
+
|
73
|
+
raise VerificationFailedError
|
83
74
|
end
|
84
75
|
end
|
85
76
|
end
|
@@ -2,12 +2,12 @@ require "minitest/verify"
|
|
2
2
|
|
3
3
|
module Minitest
|
4
4
|
def self.plugin_verify_options(opts, options)
|
5
|
-
opts.on "--verify", "Verify tests
|
6
|
-
options[:
|
5
|
+
opts.on "--verify", "Verify tests are not false negatives after running them." do
|
6
|
+
options[:verify] = true
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.plugin_verify_init(options)
|
11
|
-
Verify.enabled = options.fetch(:
|
11
|
+
Verify.enabled = options.fetch(:verify, false)
|
12
12
|
end
|
13
13
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minitest-verify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Marshall
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -57,8 +57,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
57
|
- !ruby/object:Gem::Version
|
58
58
|
version: '0'
|
59
59
|
requirements: []
|
60
|
-
rubygems_version: 3.5.
|
60
|
+
rubygems_version: 3.5.18
|
61
61
|
signing_key:
|
62
62
|
specification_version: 4
|
63
|
-
summary: A minitest plugin to prevent false
|
63
|
+
summary: A minitest plugin to prevent false negative tests.
|
64
64
|
test_files: []
|