duck_typer 0.6.0 → 0.6.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/CHANGELOG.md +10 -0
- data/README.md +25 -0
- data/lib/duck_typer/minitest.rb +3 -0
- data/lib/duck_typer/rspec.rb +30 -13
- data/lib/duck_typer/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d83b2db8bd9f4f9286edacaeecaf978aed251b15c0295d697a529c542f4e5c8
|
|
4
|
+
data.tar.gz: 176b5e8a8b555749b3e6f56f7ef36225e32db086ca54f9085b0a0db2ef5f09c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aef37fad60ebeb09be165d46ff2fb0cdcb2e0ec330d4a773c71b412d265fe0e6ed3de2a2ec2daec5f0a19fbae8b32fb66541c29f6c1705e9e4528199fe12063a
|
|
7
|
+
data.tar.gz: d9f172fd026f220574582025803bdd887eead27d97d8b37a71f11cb6ee046508b1dc7e1efda88a1727ba60161a80fa47d0199f046a055263ee6fcd1cadc2cd7e
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.1] - 2026-05-20
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `assert_canonical_duck_type_match` Minitest alias for
|
|
7
|
+
`assert_canonical_interface_match`
|
|
8
|
+
- `implement_canonical_duck_type` RSpec alias for
|
|
9
|
+
`implement_canonical_interface`
|
|
10
|
+
- `canonical:` keyword support in the shared example
|
|
11
|
+
(`it_behaves_like "an interface"`)
|
|
12
|
+
|
|
3
13
|
## [0.6.0] - 2026-05-15
|
|
4
14
|
|
|
5
15
|
### Added
|
data/README.md
CHANGED
|
@@ -240,6 +240,9 @@ assert_canonical_interface_match PaymentGateway, [StripeProcessor, PaypalProcess
|
|
|
240
240
|
name: "PaymentProcessor"
|
|
241
241
|
```
|
|
242
242
|
|
|
243
|
+
> If you prefer duck typing terminology,
|
|
244
|
+
> `assert_canonical_duck_type_match` is available as an alias.
|
|
245
|
+
|
|
243
246
|
### RSpec
|
|
244
247
|
|
|
245
248
|
Require the RSpec integration in your `spec_helper.rb`:
|
|
@@ -354,6 +357,9 @@ expect([StripeProcessor, PaypalProcessor])
|
|
|
354
357
|
When multiple classes fail, the failure message reports all of them
|
|
355
358
|
at once.
|
|
356
359
|
|
|
360
|
+
> If you prefer duck typing terminology,
|
|
361
|
+
> `implement_canonical_duck_type` is available as an alias.
|
|
362
|
+
|
|
357
363
|
#### Shared example
|
|
358
364
|
|
|
359
365
|
If you prefer shared examples, register one in `spec_helper.rb`
|
|
@@ -398,6 +404,25 @@ To check all classes in a module, pass it with `namespace:`:
|
|
|
398
404
|
it_behaves_like "an interface", namespace: Payments
|
|
399
405
|
```
|
|
400
406
|
|
|
407
|
+
To check against a canonical reference class, pass
|
|
408
|
+
`canonical:`:
|
|
409
|
+
|
|
410
|
+
```ruby
|
|
411
|
+
it_behaves_like "an interface", [
|
|
412
|
+
StripeProcessor,
|
|
413
|
+
PaypalProcessor,
|
|
414
|
+
BraintreeProcessor
|
|
415
|
+
], canonical: PaymentGateway
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
To combine `canonical:` with `namespace:`:
|
|
419
|
+
|
|
420
|
+
```ruby
|
|
421
|
+
it_behaves_like "an interface",
|
|
422
|
+
canonical: PaymentGateway,
|
|
423
|
+
namespace: Payments
|
|
424
|
+
```
|
|
425
|
+
|
|
401
426
|
## Limitations
|
|
402
427
|
|
|
403
428
|
By default, Duck Typer checks the **structure** of public method
|
data/lib/duck_typer/minitest.rb
CHANGED
data/lib/duck_typer/rspec.rb
CHANGED
|
@@ -19,7 +19,8 @@ RSpec::Matchers.define :have_matching_interfaces do |name: nil, type: :instance_
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
RSpec::Matchers.alias_matcher :have_matching_duck_types,
|
|
22
|
+
RSpec::Matchers.alias_matcher :have_matching_duck_types,
|
|
23
|
+
:have_matching_interfaces
|
|
23
24
|
|
|
24
25
|
RSpec::Matchers.define :implement_canonical_interface do |canonical, name: nil, type: :instance_methods, methods: nil, strict: false|
|
|
25
26
|
match do |actual|
|
|
@@ -38,25 +39,41 @@ RSpec::Matchers.define :implement_canonical_interface do |canonical, name: nil,
|
|
|
38
39
|
end
|
|
39
40
|
end
|
|
40
41
|
|
|
42
|
+
RSpec::Matchers.alias_matcher :implement_canonical_duck_type,
|
|
43
|
+
:implement_canonical_interface
|
|
44
|
+
|
|
41
45
|
module DuckTyper
|
|
42
46
|
module RSpec
|
|
43
47
|
def self.define_shared_example(name = "an interface")
|
|
44
|
-
::RSpec.shared_examples name do |*args, namespace: nil, name: nil, type: :instance_methods, methods: nil, strict: false|
|
|
48
|
+
::RSpec.shared_examples name do |*args, canonical: nil, namespace: nil, name: nil, type: :instance_methods, methods: nil, strict: false|
|
|
45
49
|
objects = namespace ? nil : args.first
|
|
46
50
|
|
|
47
|
-
# We intentionally avoid reusing the
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
# We intentionally avoid reusing the matchers here. Since this shared
|
|
52
|
+
# example is defined in gem code, RSpec filters it from its backtrace,
|
|
53
|
+
# causing the Failure/Error: line to show an internal RSpec constant
|
|
54
|
+
# instead of useful context.
|
|
55
|
+
if canonical
|
|
56
|
+
it "implements the canonical interface" do
|
|
57
|
+
checker = DuckTyper::CanonicalInterfaceChecker
|
|
58
|
+
.new(objects, canonical:, namespace:, type:, methods:, strict:, name:)
|
|
59
|
+
|
|
60
|
+
result = checker.call
|
|
61
|
+
|
|
62
|
+
if !result.match?
|
|
63
|
+
raise ::RSpec::Expectations::ExpectationNotMetError, result.failure_message
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
else
|
|
67
|
+
it "has compatible interfaces" do
|
|
68
|
+
checker = DuckTyper::BulkInterfaceChecker
|
|
69
|
+
.new(objects, namespace:, type:, methods:, strict:, name:)
|
|
54
70
|
|
|
55
|
-
|
|
71
|
+
failures = checker.call.reject(&:match?)
|
|
56
72
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
73
|
+
if failures.any?
|
|
74
|
+
message = failures.map(&:failure_message).join("\n")
|
|
75
|
+
raise ::RSpec::Expectations::ExpectationNotMetError, message
|
|
76
|
+
end
|
|
60
77
|
end
|
|
61
78
|
end
|
|
62
79
|
end
|
data/lib/duck_typer/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: duck_typer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.6.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thiago A. Silva
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description:
|
|
14
14
|
email:
|