minitest-attributes 0.1.0 → 0.2.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/CHANGELOG.md +8 -0
- data/README.md +20 -1
- data/lib/minitest/attributes/version.rb +1 -1
- data/lib/minitest/attributes.rb +40 -11
- data/sig/minitest/attributes.rbs +4 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 40bffe082643608c76743541a2d5407624899216156781110c8dfcfb768c71e4
|
|
4
|
+
data.tar.gz: 0b8d08ab75ba4b13c4f9ccefc3801f1b4fd7fbd5556f1d4ff5cd217144eba55d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 178862be03081097dce0c56b342e6815b4bb42918aafefe2b3ca407fb16d269aff49b79db0147003a6608149097eb030a693bfb3806cde467726676baa6f286a
|
|
7
|
+
data.tar.gz: 1f3cecc0b993ba3e8d017935f03165197ab88414bbf82be4c7601f73ede698df8f7e9f69761b6d412de70f82bd58be7542828ea21d0e26f330f598a90689381e
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.2.0] - 2026-10-13
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `assert_hash_attributes(hash, **expected)` assertion, applying the same comparisons to hash values
|
|
15
|
+
- Keys are looked up as given, then as strings, so symbol keys match parsed JSON
|
|
16
|
+
- A missing key fails, even when the expected value is `nil`
|
|
17
|
+
|
|
10
18
|
## [0.1.0] - 2026-09-24
|
|
11
19
|
|
|
12
20
|
### Added
|
data/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Then run:
|
|
|
27
27
|
bundle install
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
Requiring the gem mixes `assert_attributes` into `Minitest::Assertions`, so it is available in every `Minitest::Test`, `ActiveSupport::TestCase`, and integration test. Bundler requires it for you in a Rails app; otherwise add `require "minitest/attributes"` to your test helper.
|
|
30
|
+
Requiring the gem mixes `assert_attributes` and `assert_hash_attributes` into `Minitest::Assertions`, so it is available in every `Minitest::Test`, `ActiveSupport::TestCase`, and integration test. Bundler requires it for you in a Rails app; otherwise add `require "minitest/attributes"` to your test helper.
|
|
31
31
|
|
|
32
32
|
## Usage
|
|
33
33
|
|
|
@@ -44,6 +44,25 @@ A mismatch fails with a message such as:
|
|
|
44
44
|
Expected Person#last_name to be "Bubblegum", but was "Abadeer"
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
### Hashes
|
|
48
|
+
|
|
49
|
+
`assert_hash_attributes` makes the same comparisons against the values of a hash. Each key is looked up as given and then as a string, so symbol keys also match parsed JSON:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
assert_hash_attributes(
|
|
53
|
+
JSON.parse(response.body),
|
|
54
|
+
"@type": "Person",
|
|
55
|
+
name: "Marceline",
|
|
56
|
+
nickname: nil
|
|
57
|
+
)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
A missing key fails with the hash's keys, even when the expected value is `nil`:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Expected hash to have key :nickname, but its keys were ["@type", "name"]
|
|
64
|
+
```
|
|
65
|
+
|
|
47
66
|
## Development
|
|
48
67
|
|
|
49
68
|
After checking out the repo, run `bin/setup` to install dependencies. Then run `bundle exec rake` to run the tests and RuboCop. You can also run `bin/console` for an interactive prompt.
|
data/lib/minitest/attributes.rb
CHANGED
|
@@ -14,52 +14,81 @@ module Minitest
|
|
|
14
14
|
# compared within +TIME_DELTA+ seconds, and an actual value that responds to
|
|
15
15
|
# +to_plain_text+ (such as an Action Text rich text) is compared as plain
|
|
16
16
|
# text. Everything else falls through to +assert_equal+.
|
|
17
|
+
#
|
|
18
|
+
# +assert_hash_attributes+ applies the same comparisons to the values of a
|
|
19
|
+
# hash.
|
|
17
20
|
module Attributes
|
|
18
21
|
TIME_DELTA = 1
|
|
19
22
|
|
|
20
23
|
def assert_attributes(record, **expected_attributes)
|
|
21
24
|
expected_attributes.each do |attribute, expected_value|
|
|
22
|
-
|
|
25
|
+
assert_value(
|
|
26
|
+
"#{record.class.name}##{attribute}",
|
|
27
|
+
expected_value,
|
|
28
|
+
record.public_send(attribute)
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Like +assert_attributes+, but reads each key from a hash. A key is looked
|
|
34
|
+
# up as given, then as a string, so symbol keys also match the string keys
|
|
35
|
+
# of parsed JSON:
|
|
36
|
+
#
|
|
37
|
+
# assert_hash_attributes(JSON.parse(body), "@type": "Person", age: 12)
|
|
38
|
+
#
|
|
39
|
+
# A missing key fails, even when the expected value is +nil+.
|
|
40
|
+
def assert_hash_attributes(hash, **expected_attributes)
|
|
41
|
+
expected_attributes.each do |key, expected_value|
|
|
42
|
+
assert_hash_attribute(hash, key, expected_value)
|
|
23
43
|
end
|
|
24
44
|
end
|
|
25
45
|
|
|
26
46
|
private
|
|
27
47
|
|
|
28
|
-
def
|
|
29
|
-
|
|
48
|
+
def assert_hash_attribute(hash, key, expected_value)
|
|
49
|
+
found_key = [key, key.to_s].find { |candidate| hash.key?(candidate) }
|
|
50
|
+
assert(
|
|
51
|
+
found_key,
|
|
52
|
+
"Expected hash to have key #{key.inspect}, " \
|
|
53
|
+
"but its keys were #{hash.keys.inspect}"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
assert_value(
|
|
57
|
+
"hash[#{found_key.inspect}]", expected_value, hash[found_key]
|
|
58
|
+
)
|
|
59
|
+
end
|
|
30
60
|
|
|
61
|
+
def assert_value(label, expected_value, actual_value)
|
|
31
62
|
if expected_value.nil?
|
|
32
63
|
assert_nil(
|
|
33
64
|
actual_value,
|
|
34
|
-
|
|
65
|
+
value_message(label, expected_value, actual_value)
|
|
35
66
|
)
|
|
36
67
|
elsif expected_value.is_a?(Time)
|
|
37
68
|
assert_in_delta(
|
|
38
69
|
expected_value.to_f,
|
|
39
70
|
actual_value.to_f,
|
|
40
71
|
TIME_DELTA,
|
|
41
|
-
|
|
72
|
+
value_message(label, expected_value, actual_value)
|
|
42
73
|
)
|
|
43
74
|
elsif actual_value.respond_to?(:to_plain_text)
|
|
44
75
|
plain_actual_value = actual_value.to_plain_text
|
|
45
76
|
assert_equal(
|
|
46
77
|
expected_value,
|
|
47
78
|
plain_actual_value,
|
|
48
|
-
|
|
49
|
-
record, attribute, expected_value, plain_actual_value
|
|
50
|
-
)
|
|
79
|
+
value_message(label, expected_value, plain_actual_value)
|
|
51
80
|
)
|
|
52
81
|
else
|
|
53
82
|
assert_equal(
|
|
54
83
|
expected_value,
|
|
55
84
|
actual_value,
|
|
56
|
-
|
|
85
|
+
value_message(label, expected_value, actual_value)
|
|
57
86
|
)
|
|
58
87
|
end
|
|
59
88
|
end
|
|
60
89
|
|
|
61
|
-
def
|
|
62
|
-
"Expected #{
|
|
90
|
+
def value_message(label, expected_value, actual_value)
|
|
91
|
+
"Expected #{label} to be " \
|
|
63
92
|
"#{expected_value.inspect}, but was #{actual_value.inspect}"
|
|
64
93
|
end
|
|
65
94
|
end
|
data/sig/minitest/attributes.rbs
CHANGED
|
@@ -4,10 +4,12 @@ module Minitest
|
|
|
4
4
|
TIME_DELTA: Integer
|
|
5
5
|
|
|
6
6
|
def assert_attributes: (untyped record, **untyped expected_attributes) -> void
|
|
7
|
+
def assert_hash_attributes: (Hash[untyped, untyped] hash, **untyped expected_attributes) -> void
|
|
7
8
|
|
|
8
9
|
private
|
|
9
10
|
|
|
10
|
-
def
|
|
11
|
-
def
|
|
11
|
+
def assert_hash_attribute: (Hash[untyped, untyped] hash, Symbol key, untyped expected_value) -> void
|
|
12
|
+
def assert_value: (String label, untyped expected_value, untyped actual_value) -> void
|
|
13
|
+
def value_message: (String label, untyped expected_value, untyped actual_value) -> String
|
|
12
14
|
end
|
|
13
15
|
end
|