attr_extras 6.2.1 → 6.2.5
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 +5 -5
- data/.github/workflows/ci.yml +26 -0
- data/CHANGELOG.md +18 -5
- data/README.md +64 -7
- data/attr_extras.gemspec +4 -3
- data/lib/attr_extras/attr_implement.rb +1 -1
- data/lib/attr_extras/explicit.rb +13 -6
- data/lib/attr_extras/version.rb +1 -1
- data/spec/attr_extras/aattr_initialize_spec.rb +6 -6
- data/spec/attr_extras/attr_id_query_spec.rb +1 -1
- data/spec/attr_extras/attr_implement_spec.rb +21 -11
- data/spec/attr_extras/attr_initialize_spec.rb +21 -21
- data/spec/attr_extras/attr_private_spec.rb +3 -3
- data/spec/attr_extras/attr_query_spec.rb +1 -1
- data/spec/attr_extras/attr_value_spec.rb +7 -7
- data/spec/attr_extras/params_builder_spec.rb +20 -20
- data/spec/attr_extras/pattr_initialize_spec.rb +5 -5
- data/spec/attr_extras/rattr_initialize_spec.rb +4 -4
- data/spec/attr_extras/static_facade_spec.rb +30 -0
- data/spec/attr_extras/utils_spec.rb +3 -3
- data/spec/attr_extras/vattr_initialize_spec.rb +9 -9
- data/spec/attr_extras_spec.rb +1 -1
- data/spec/spec_helper_without_loading_attr_extras.rb +17 -0
- metadata +9 -8
- data/.travis.yml +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a01c4bfc2a6ce3f1ae8735fe122b7abbd65c99be5a17330087e09e028e59b3cb
|
4
|
+
data.tar.gz: c83abb5d1467b7c91b2ff0c54220fa72ebdc2d6ee0deba2c7ca8edc3629f744c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48893855229adec5435cd0b709c50cf1e631e321197dd23baeaaa54e11c513f1d4f47ac3e9b3ab2268fc6d86c26c519e57c8e12d9c7aa2a7e819e9c5a53d9cfd
|
7
|
+
data.tar.gz: dc63a635eedac54ce49b25eece473e5264b655d2c87852725bc28baeaf4f9c7d516febad45978ba71816c3dec0afc1e5e114c9587c16ad890999a408efe588cd
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: Ruby CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
strategy:
|
15
|
+
matrix:
|
16
|
+
ruby-version: ["3.0", "2.7", "2.6", "2.5", "jruby-head"]
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v2
|
20
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
21
|
+
uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
24
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
25
|
+
- name: Run tests
|
26
|
+
run: bundle exec rake
|
data/CHANGELOG.md
CHANGED
@@ -1,21 +1,34 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
|
3
|
+
## [6.2.4](https://github.com/barsoom/attr_extras/releases/tag/v6.2.4)
|
4
|
+
|
5
|
+
- Fix keyword argument warnings with Ruby 2.7. Thanks to [Elliot Winkler](https://github.com/barsoom/attr_extras/pull/34)!
|
6
|
+
|
7
|
+
## [6.2.3](https://github.com/barsoom/attr_extras/releases/tag/v6.2.3)
|
8
|
+
|
9
|
+
- `attr_implement` error says "an 'ear()' method" instead of "a 'ear()' method", when the method starts with a likely vowel.
|
10
|
+
|
11
|
+
## [6.2.2](https://github.com/barsoom/attr_extras/releases/tag/v6.2.2)
|
12
|
+
|
13
|
+
- Fix warnings with Ruby 2.7. Thanks to [Juanito Fatas](https://github.com/barsoom/attr_extras/pull/31)!
|
14
|
+
- Fix deprecation warnings for Minitest 6. Thanks again to [Juanito Fatas](https://github.com/barsoom/attr_extras/pull/30)!
|
15
|
+
|
16
|
+
## [6.2.1](https://github.com/barsoom/attr_extras/releases/tag/v6.2.1)
|
4
17
|
|
5
18
|
* Bugfix with keyword argument defaults. Thanks to [Roman Dubrovsky](https://github.com/barsoom/attr_extras/pull/29)!
|
6
19
|
|
7
|
-
|
20
|
+
## [6.2.0](https://github.com/barsoom/attr_extras/releases/tag/v6.2.0)
|
8
21
|
|
9
22
|
* Another bugfix when passing hash values to positional arguments.
|
10
23
|
|
11
|
-
|
24
|
+
## [6.1.0](https://github.com/barsoom/attr_extras/releases/tag/v6.1.0)
|
12
25
|
|
13
26
|
* Bugfix when passing hash values to positional arguments.
|
14
27
|
|
15
|
-
|
28
|
+
## 6.0.0 (yanked)
|
16
29
|
|
17
30
|
* Default arguments! Thanks to [Ola K](https://github.com/lesin). For example: `pattr_initialize [:foo, bar: "default value"]`
|
18
31
|
|
19
|
-
|
32
|
+
## [5.2.0](https://github.com/barsoom/attr_extras/releases/tag/v5.2.0) and earlier
|
20
33
|
|
21
34
|
Please [see Git history](https://github.com/barsoom/attr_extras/releases).
|
data/README.md
CHANGED
@@ -1,21 +1,31 @@
|
|
1
|
-
[](https://badge.fury.io/rb/attr_extras)
|
2
|
+
[](https://github.com/barsoom/attr_extras/actions/workflows/ci.yml)
|
2
3
|
[](https://codeclimate.com/github/barsoom/attr_extras)
|
3
4
|
|
4
5
|
# attr\_extras
|
5
6
|
|
6
7
|
Takes some boilerplate out of Ruby, lowering the barrier to extracting small focused classes, without [the downsides of using `Struct`](http://thepugautomatic.com/2013/08/struct-inheritance-is-overused/).
|
7
8
|
|
9
|
+
Provides lower-level methods like `attr_private` and `attr_value` that nicely complement Ruby's built-in `attr_accessor`, `attr_reader` and `attr_writer`.
|
10
|
+
|
11
|
+
Also higher-level ones like `pattr_initialize` (or `attr_private_initialize`) and `method_object` to really cut down on the boilerplate.
|
12
|
+
|
8
13
|
Instead of
|
9
14
|
|
10
15
|
``` ruby
|
11
|
-
class
|
12
|
-
def initialize(invoice,
|
13
|
-
@invoice
|
16
|
+
class InvoicePolicy
|
17
|
+
def initialize(invoice, company:)
|
18
|
+
@invoice = invoice
|
19
|
+
@company = company
|
20
|
+
end
|
21
|
+
|
22
|
+
def payable?
|
23
|
+
some_logic(invoice, company)
|
14
24
|
end
|
15
25
|
|
16
26
|
private
|
17
27
|
|
18
|
-
attr_reader :invoice, :
|
28
|
+
attr_reader :invoice, :company
|
19
29
|
end
|
20
30
|
```
|
21
31
|
|
@@ -23,11 +33,58 @@ you can just do
|
|
23
33
|
|
24
34
|
``` ruby
|
25
35
|
class InvoiceBuilder
|
26
|
-
pattr_initialize :invoice, :
|
36
|
+
pattr_initialize :invoice, [:company!]
|
37
|
+
|
38
|
+
def payable?
|
39
|
+
some_logic(invoice, company)
|
40
|
+
end
|
27
41
|
end
|
28
42
|
```
|
29
43
|
|
30
|
-
|
44
|
+
And instead of
|
45
|
+
|
46
|
+
``` ruby
|
47
|
+
class PayInvoice
|
48
|
+
def self.call(invoice, amount)
|
49
|
+
new(invoice, amount).call
|
50
|
+
end
|
51
|
+
|
52
|
+
def initialize(invoice, amount)
|
53
|
+
@invoice = invoice
|
54
|
+
@amount = amount
|
55
|
+
end
|
56
|
+
|
57
|
+
def call
|
58
|
+
PaymentGateway.charge(invoice.id, amount_in_cents)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def amount_in_cents
|
64
|
+
amount * 100
|
65
|
+
end
|
66
|
+
|
67
|
+
attr_reader :invoice, :amount
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
you can just do
|
72
|
+
|
73
|
+
``` ruby
|
74
|
+
class PayInvoice
|
75
|
+
method_object :invoice, :amount
|
76
|
+
|
77
|
+
def call
|
78
|
+
PaymentGateway.charge(invoice.id, amount_in_cents)
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def amount_in_cents
|
84
|
+
amount * 100
|
85
|
+
end
|
86
|
+
end
|
87
|
+
```
|
31
88
|
|
32
89
|
Supports positional arguments as well as optional and required keyword arguments.
|
33
90
|
|
data/attr_extras.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path(
|
2
|
+
require File.expand_path("../lib/attr_extras/version", __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = ["Henrik Nyh", "Joakim Kolsjö", "Victor Arias", "Ola K"]
|
5
|
+
gem.authors = ["Henrik Nyh", "Joakim Kolsjö", "Tomas Skogberg", "Victor Arias", "Ola K"]
|
6
6
|
gem.email = ["henrik@nyh.se"]
|
7
7
|
gem.summary = %q{Takes some boilerplate out of Ruby with methods like attr_initialize.}
|
8
8
|
gem.homepage = "https://github.com/barsoom/attr_extras"
|
@@ -14,9 +14,10 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.require_paths = ["lib"]
|
15
15
|
gem.license = "MIT"
|
16
16
|
gem.version = AttrExtras::VERSION
|
17
|
+
gem.metadata = { "rubygems_mfa_required" => "true" }
|
17
18
|
|
18
19
|
gem.add_development_dependency "minitest", ">= 5"
|
19
|
-
gem.add_development_dependency "m", "~> 1.5.
|
20
|
+
gem.add_development_dependency "m", "~> 1.5.1" # Running individual tests.
|
20
21
|
|
21
22
|
# For Travis CI.
|
22
23
|
gem.add_development_dependency "rake"
|
@@ -19,7 +19,7 @@ class AttrExtras::AttrImplement
|
|
19
19
|
raise ArgumentError, "wrong number of arguments (#{provided_arity} for #{expected_arity})"
|
20
20
|
end
|
21
21
|
|
22
|
-
raise AttrExtras::MethodNotImplementedError, "Implement a '#{name}(#{arg_names.join(", ")})' method"
|
22
|
+
raise AttrExtras::MethodNotImplementedError, "Implement a#{"n" if name[0].match?(/\A[aeiou]/i)} '#{name}(#{arg_names.join(", ")})' method"
|
23
23
|
else
|
24
24
|
super(name, *args)
|
25
25
|
end
|
data/lib/attr_extras/explicit.rb
CHANGED
@@ -21,9 +21,8 @@ module AttrExtras
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def attr_private(*names)
|
24
|
-
#
|
25
|
-
|
26
|
-
public
|
24
|
+
# Avoid warnings: https://github.com/barsoom/attr_extras/pull/31
|
25
|
+
return unless names && names.any?
|
27
26
|
|
28
27
|
attr_reader(*names)
|
29
28
|
private(*names)
|
@@ -62,9 +61,17 @@ module AttrExtras
|
|
62
61
|
alias_method :attr_accessor_initialize, :aattr_initialize
|
63
62
|
|
64
63
|
def static_facade(method_name_or_names, *names)
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
if names.any? { |name| name.is_a?(Array) }
|
65
|
+
Array(method_name_or_names).each do |method_name|
|
66
|
+
define_singleton_method(method_name) do |*args, **opts, &block|
|
67
|
+
new(*args, **opts).public_send(method_name, &block)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
else
|
71
|
+
Array(method_name_or_names).each do |method_name|
|
72
|
+
define_singleton_method(method_name) do |*args, &block|
|
73
|
+
new(*args).public_send(method_name, &block)
|
74
|
+
end
|
68
75
|
end
|
69
76
|
end
|
70
77
|
|
data/lib/attr_extras/version.rb
CHANGED
@@ -8,7 +8,7 @@ describe Object, ".aattr_initialize" do
|
|
8
8
|
|
9
9
|
example = klass.new("Foo", "Bar")
|
10
10
|
|
11
|
-
example.foo.must_equal "Foo"
|
11
|
+
_(example.foo).must_equal "Foo"
|
12
12
|
end
|
13
13
|
|
14
14
|
it "creates public writers" do
|
@@ -19,7 +19,7 @@ describe Object, ".aattr_initialize" do
|
|
19
19
|
example = klass.new("Foo", "Bar")
|
20
20
|
example.foo = "Baz"
|
21
21
|
|
22
|
-
example.foo.must_equal "Baz"
|
22
|
+
_(example.foo).must_equal "Baz"
|
23
23
|
end
|
24
24
|
|
25
25
|
it "works with hash ivars" do
|
@@ -29,7 +29,7 @@ describe Object, ".aattr_initialize" do
|
|
29
29
|
|
30
30
|
example = klass.new("Foo", bar: "Bar", baz: "Baz")
|
31
31
|
|
32
|
-
example.baz.must_equal "Baz"
|
32
|
+
_(example.baz).must_equal "Baz"
|
33
33
|
end
|
34
34
|
|
35
35
|
it "works with hash ivars and default values" do
|
@@ -39,7 +39,7 @@ describe Object, ".aattr_initialize" do
|
|
39
39
|
|
40
40
|
example = klass.new("Foo")
|
41
41
|
|
42
|
-
example.baz.must_equal "Baz"
|
42
|
+
_(example.baz).must_equal "Baz"
|
43
43
|
end
|
44
44
|
|
45
45
|
it "accepts a block for initialization" do
|
@@ -53,7 +53,7 @@ describe Object, ".aattr_initialize" do
|
|
53
53
|
|
54
54
|
example = klass.new("expected")
|
55
55
|
|
56
|
-
example.copy.must_equal "expected"
|
56
|
+
_(example.copy).must_equal "expected"
|
57
57
|
end
|
58
58
|
|
59
59
|
it "accepts the alias attr_accessor_initialize" do
|
@@ -63,6 +63,6 @@ describe Object, ".aattr_initialize" do
|
|
63
63
|
|
64
64
|
example = klass.new("Foo", "Bar")
|
65
65
|
|
66
|
-
example.foo.must_equal "Foo"
|
66
|
+
_(example.foo).must_equal "Foo"
|
67
67
|
end
|
68
68
|
end
|
@@ -7,8 +7,8 @@ describe Object, ".attr_implement" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
example = klass.new
|
10
|
-
exception = lambda { example.foo }.must_raise AttrExtras::MethodNotImplementedError
|
11
|
-
exception.message.must_equal "Implement a 'foo()' method"
|
10
|
+
exception = _(lambda { example.foo }).must_raise AttrExtras::MethodNotImplementedError
|
11
|
+
_(exception.message).must_equal "Implement a 'foo()' method"
|
12
12
|
end
|
13
13
|
|
14
14
|
it "allows specifying arity and argument names" do
|
@@ -18,10 +18,10 @@ describe Object, ".attr_implement" do
|
|
18
18
|
|
19
19
|
example = klass.new
|
20
20
|
|
21
|
-
exception = lambda { example.foo(1, 2) }.must_raise AttrExtras::MethodNotImplementedError
|
22
|
-
exception.message.must_equal "Implement a 'foo(name, age)' method"
|
21
|
+
exception = _(lambda { example.foo(1, 2) }).must_raise AttrExtras::MethodNotImplementedError
|
22
|
+
_(exception.message).must_equal "Implement a 'foo(name, age)' method"
|
23
23
|
|
24
|
-
lambda { example.foo }.must_raise ArgumentError
|
24
|
+
_(lambda { example.foo }).must_raise ArgumentError
|
25
25
|
end
|
26
26
|
|
27
27
|
it "does not raise if method is implemented in a subclass" do
|
@@ -35,7 +35,7 @@ describe Object, ".attr_implement" do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
subklass.new.foo.must_equal "bar"
|
38
|
+
_(subklass.new.foo).must_equal "bar"
|
39
39
|
end
|
40
40
|
|
41
41
|
# E.g. when Active Record defines column query methods like "admin?"
|
@@ -55,7 +55,7 @@ describe Object, ".attr_implement" do
|
|
55
55
|
include foo_interface
|
56
56
|
end
|
57
57
|
|
58
|
-
klass.new.foo.must_equal "bar"
|
58
|
+
_(klass.new.foo).must_equal "bar"
|
59
59
|
end
|
60
60
|
|
61
61
|
it "does not mess up missing-method handling" do
|
@@ -63,7 +63,17 @@ describe Object, ".attr_implement" do
|
|
63
63
|
attr_implement :foo
|
64
64
|
end
|
65
65
|
|
66
|
-
lambda { klass.new.some_other_method }.must_raise NoMethodError
|
66
|
+
_(lambda { klass.new.some_other_method }).must_raise NoMethodError
|
67
|
+
end
|
68
|
+
|
69
|
+
it "says 'an' if followed by a vowel" do
|
70
|
+
klass = Class.new do
|
71
|
+
attr_implement :ear
|
72
|
+
end
|
73
|
+
|
74
|
+
example = klass.new
|
75
|
+
exception = _(lambda { example.ear }).must_raise AttrExtras::MethodNotImplementedError
|
76
|
+
_(exception.message).must_equal "Implement an 'ear()' method"
|
67
77
|
end
|
68
78
|
end
|
69
79
|
|
@@ -73,9 +83,9 @@ describe Object, ".cattr_implement" do
|
|
73
83
|
cattr_implement :foo, [:name, :age]
|
74
84
|
end
|
75
85
|
|
76
|
-
exception = lambda { klass.foo(1, 2) }.must_raise AttrExtras::MethodNotImplementedError
|
77
|
-
exception.message.must_equal "Implement a 'foo(name, age)' method"
|
86
|
+
exception = _(lambda { klass.foo(1, 2) }).must_raise AttrExtras::MethodNotImplementedError
|
87
|
+
_(exception.message).must_equal "Implement a 'foo(name, age)' method"
|
78
88
|
|
79
|
-
lambda { klass.foo }.must_raise ArgumentError
|
89
|
+
_(lambda { klass.foo }).must_raise ArgumentError
|
80
90
|
end
|
81
91
|
end
|
@@ -13,13 +13,13 @@ describe Object, ".attr_initialize" do
|
|
13
13
|
|
14
14
|
it "creates an initializer setting those instance variables" do
|
15
15
|
example = klass.new("Foo", "Bar")
|
16
|
-
example.instance_variable_get("@foo").must_equal "Foo"
|
17
|
-
example.instance_variable_get("@bar").must_equal "Bar"
|
16
|
+
_(example.instance_variable_get("@foo")).must_equal "Foo"
|
17
|
+
_(example.instance_variable_get("@bar")).must_equal "Bar"
|
18
18
|
end
|
19
19
|
|
20
20
|
it "requires all arguments" do
|
21
|
-
exception = lambda { klass.new("Foo") }.must_raise ArgumentError
|
22
|
-
exception.message.must_equal "wrong number of arguments (1 for 2) for ExampleClass initializer"
|
21
|
+
exception = _(lambda { klass.new("Foo") }).must_raise ArgumentError
|
22
|
+
_(exception.message).must_equal "wrong number of arguments (1 for 2) for ExampleClass initializer"
|
23
23
|
end
|
24
24
|
|
25
25
|
it "can set ivars from a hash" do
|
@@ -28,9 +28,9 @@ describe Object, ".attr_initialize" do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
example = klass.new("Foo", bar: "Bar", baz: "Baz")
|
31
|
-
example.instance_variable_get("@foo").must_equal "Foo"
|
32
|
-
example.instance_variable_get("@bar").must_equal "Bar"
|
33
|
-
example.instance_variable_get("@baz").must_equal "Baz"
|
31
|
+
_(example.instance_variable_get("@foo")).must_equal "Foo"
|
32
|
+
_(example.instance_variable_get("@bar")).must_equal "Bar"
|
33
|
+
_(example.instance_variable_get("@baz")).must_equal "Baz"
|
34
34
|
end
|
35
35
|
|
36
36
|
it "can set default values for keyword arguments" do
|
@@ -39,12 +39,12 @@ describe Object, ".attr_initialize" do
|
|
39
39
|
end
|
40
40
|
|
41
41
|
example = klass.new("Foo", bar: "Bar")
|
42
|
-
example.instance_variable_get("@foo").must_equal "Foo"
|
43
|
-
example.instance_variable_get("@bar").must_equal "Bar"
|
44
|
-
example.instance_variable_get("@baz").must_equal "default baz"
|
42
|
+
_(example.instance_variable_get("@foo")).must_equal "Foo"
|
43
|
+
_(example.instance_variable_get("@bar")).must_equal "Bar"
|
44
|
+
_(example.instance_variable_get("@baz")).must_equal "default baz"
|
45
45
|
|
46
46
|
example = klass.new("Foo", bar: "Bar", baz: "Baz")
|
47
|
-
example.instance_variable_get("@baz").must_equal "Baz"
|
47
|
+
_(example.instance_variable_get("@baz")).must_equal "Baz"
|
48
48
|
end
|
49
49
|
|
50
50
|
it "treats hash values as optional" do
|
@@ -53,10 +53,10 @@ describe Object, ".attr_initialize" do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
example = klass.new("Foo", bar: "Bar")
|
56
|
-
example.instance_variable_defined?("@baz").must_equal false
|
56
|
+
_(example.instance_variable_defined?("@baz")).must_equal false
|
57
57
|
|
58
58
|
example = klass.new("Foo")
|
59
|
-
example.instance_variable_defined?("@bar").must_equal false
|
59
|
+
_(example.instance_variable_defined?("@bar")).must_equal false
|
60
60
|
end
|
61
61
|
|
62
62
|
it "can require hash values" do
|
@@ -65,9 +65,9 @@ describe Object, ".attr_initialize" do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
example = klass.new(required: "X")
|
68
|
-
example.instance_variable_get("@required").must_equal "X"
|
68
|
+
_(example.instance_variable_get("@required")).must_equal "X"
|
69
69
|
|
70
|
-
lambda { klass.new(optional: "X") }.must_raise KeyError
|
70
|
+
_(lambda { klass.new(optional: "X") }).must_raise KeyError
|
71
71
|
end
|
72
72
|
|
73
73
|
it "complains about unknown hash values" do
|
@@ -78,8 +78,8 @@ describe Object, ".attr_initialize" do
|
|
78
78
|
# Should not raise.
|
79
79
|
klass.new("Foo", bar: "Bar", baz: "Baz")
|
80
80
|
|
81
|
-
exception = lambda { klass.new("Foo", bar: "Bar", baz: "Baz", hello: "Hello") }.must_raise ArgumentError
|
82
|
-
exception.message.must_include "[:hello]"
|
81
|
+
exception = _(lambda { klass.new("Foo", bar: "Bar", baz: "Baz", hello: "Hello") }).must_raise ArgumentError
|
82
|
+
_(exception.message).must_include "[:hello]"
|
83
83
|
end
|
84
84
|
|
85
85
|
# Regression.
|
@@ -99,8 +99,8 @@ describe Object, ".attr_initialize" do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
# Provides a hash to "foo" but does not provide "bar".
|
102
|
-
exception = lambda { klass.new({ bar: 123 }) }.must_raise KeyError
|
103
|
-
exception.message.must_include "[:bar]"
|
102
|
+
exception = _(lambda { klass.new({ bar: 123 }) }).must_raise KeyError
|
103
|
+
_(exception.message).must_include "[:bar]"
|
104
104
|
end
|
105
105
|
|
106
106
|
# Regression.
|
@@ -113,7 +113,7 @@ describe Object, ".attr_initialize" do
|
|
113
113
|
# Should not raise.
|
114
114
|
example = klass.new({ "invalid.ivar.name" => 123 })
|
115
115
|
|
116
|
-
example.foo.must_equal({ "invalid.ivar.name" => 123 })
|
116
|
+
_(example.foo).must_equal({ "invalid.ivar.name" => 123 })
|
117
117
|
end
|
118
118
|
|
119
119
|
it "accepts a block for initialization" do
|
@@ -127,6 +127,6 @@ describe Object, ".attr_initialize" do
|
|
127
127
|
|
128
128
|
example = klass.new("expected")
|
129
129
|
|
130
|
-
example.copy.must_equal "expected"
|
130
|
+
_(example.copy).must_equal "expected"
|
131
131
|
end
|
132
132
|
end
|
@@ -11,8 +11,8 @@ describe Object, ".attr_private" do
|
|
11
11
|
example = klass.new
|
12
12
|
example.instance_variable_set("@foo", "Foo")
|
13
13
|
example.instance_variable_set("@bar", "Bar")
|
14
|
-
example.send(:foo).must_equal "Foo"
|
15
|
-
example.send(:bar).must_equal "Bar"
|
16
|
-
lambda { example.foo }.must_raise NoMethodError
|
14
|
+
_(example.send(:foo)).must_equal "Foo"
|
15
|
+
_(example.send(:bar)).must_equal "Bar"
|
16
|
+
_(lambda { example.foo }).must_raise NoMethodError
|
17
17
|
end
|
18
18
|
end
|
@@ -9,7 +9,7 @@ describe Object, ".attr_value" do
|
|
9
9
|
|
10
10
|
example = klass.new
|
11
11
|
example.instance_variable_set("@foo", "Foo")
|
12
|
-
example.foo.must_equal "Foo"
|
12
|
+
_(example.foo).must_equal "Foo"
|
13
13
|
end
|
14
14
|
|
15
15
|
it "does not create writers" do
|
@@ -17,7 +17,7 @@ describe Object, ".attr_value" do
|
|
17
17
|
attr_value :foo
|
18
18
|
end
|
19
19
|
|
20
|
-
lambda { klass.new.foo = "new value" }.must_raise NoMethodError
|
20
|
+
_(lambda { klass.new.foo = "new value" }).must_raise NoMethodError
|
21
21
|
end
|
22
22
|
|
23
23
|
describe "object equality" do
|
@@ -92,21 +92,21 @@ describe Object, ".attr_value" do
|
|
92
92
|
klass1_bar = klass1.new("Bar")
|
93
93
|
klass2_foo = klass2.new("Foo")
|
94
94
|
|
95
|
-
klass1_foo.hash.must_equal klass1_foo2.hash
|
96
|
-
klass1_foo.hash.wont_equal klass1_bar.hash
|
97
|
-
klass1_foo.hash.wont_equal klass2_foo.hash
|
95
|
+
_(klass1_foo.hash).must_equal klass1_foo2.hash
|
96
|
+
_(klass1_foo.hash).wont_equal klass1_bar.hash
|
97
|
+
_(klass1_foo.hash).wont_equal klass2_foo.hash
|
98
98
|
|
99
99
|
assert klass1_foo.eql?(klass1_foo2), "Examples should be 'eql?'"
|
100
100
|
refute klass1_foo.eql?(klass1_bar), "Examples should not be 'eql?'"
|
101
101
|
refute klass1_foo.eql?(klass2_foo), "Examples should not be 'eql?'"
|
102
102
|
|
103
|
-
Set[klass1_foo, klass1_foo2, klass1_bar, klass2_foo].length.must_equal 3
|
103
|
+
_(Set[klass1_foo, klass1_foo2, klass1_bar, klass2_foo].length).must_equal 3
|
104
104
|
|
105
105
|
hash = {}
|
106
106
|
hash[klass1_foo] = :awyeah
|
107
107
|
hash[klass1_bar] = :wat
|
108
108
|
hash[klass2_foo] = :nooooo
|
109
|
-
hash[klass1_foo2].must_equal :awyeah
|
109
|
+
_(hash[klass1_foo2]).must_equal :awyeah
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
@@ -7,11 +7,11 @@ describe AttrExtras::AttrInitialize::ParamsBuilder do
|
|
7
7
|
let(:names) { [ :foo, :bar, [ :baz, :qux!, quux: "Quux" ]] }
|
8
8
|
|
9
9
|
it "properly devides params by the type" do
|
10
|
-
subject.positional_args.must_equal [ :foo, :bar ]
|
11
|
-
subject.hash_args.must_equal [ :baz, :qux!, :quux ]
|
12
|
-
subject.hash_args_names.must_equal [ :baz, :qux, :quux ]
|
13
|
-
subject.hash_args_required.must_equal [ :qux ]
|
14
|
-
subject.default_values.must_equal({ quux: "Quux" })
|
10
|
+
_(subject.positional_args).must_equal [ :foo, :bar ]
|
11
|
+
_(subject.hash_args).must_equal [ :baz, :qux!, :quux ]
|
12
|
+
_(subject.hash_args_names).must_equal [ :baz, :qux, :quux ]
|
13
|
+
_(subject.hash_args_required).must_equal [ :qux ]
|
14
|
+
_(subject.default_values).must_equal({ quux: "Quux" })
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -19,11 +19,11 @@ describe AttrExtras::AttrInitialize::ParamsBuilder do
|
|
19
19
|
let(:names) { [ :foo, :bar] }
|
20
20
|
|
21
21
|
it "properly devides params by the type" do
|
22
|
-
subject.positional_args.must_equal [ :foo, :bar ]
|
23
|
-
subject.hash_args.must_be_empty
|
24
|
-
subject.hash_args_names.must_be_empty
|
25
|
-
subject.hash_args_required.must_be_empty
|
26
|
-
subject.default_values.must_be_empty
|
22
|
+
_(subject.positional_args).must_equal [ :foo, :bar ]
|
23
|
+
_(subject.hash_args).must_be_empty
|
24
|
+
_(subject.hash_args_names).must_be_empty
|
25
|
+
_(subject.hash_args_required).must_be_empty
|
26
|
+
_(subject.default_values).must_be_empty
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -31,11 +31,11 @@ describe AttrExtras::AttrInitialize::ParamsBuilder do
|
|
31
31
|
let(:names) { [[ { baz: "Baz" }, :qux!, { quux: "Quux" } ]] }
|
32
32
|
|
33
33
|
it "properly devides params by the type" do
|
34
|
-
subject.positional_args.must_be_empty
|
35
|
-
subject.hash_args.must_equal [ :baz, :qux!, :quux ]
|
36
|
-
subject.hash_args_names.must_equal [ :baz, :qux, :quux ]
|
37
|
-
subject.hash_args_required.must_equal [ :qux ]
|
38
|
-
subject.default_values.must_equal({ quux: "Quux", baz: "Baz" })
|
34
|
+
_(subject.positional_args).must_be_empty
|
35
|
+
_(subject.hash_args).must_equal [ :baz, :qux!, :quux ]
|
36
|
+
_(subject.hash_args_names).must_equal [ :baz, :qux, :quux ]
|
37
|
+
_(subject.hash_args_required).must_equal [ :qux ]
|
38
|
+
_(subject.default_values).must_equal({ quux: "Quux", baz: "Baz" })
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -43,11 +43,11 @@ describe AttrExtras::AttrInitialize::ParamsBuilder do
|
|
43
43
|
let(:names) { [] }
|
44
44
|
|
45
45
|
it "properly devides params by the type" do
|
46
|
-
subject.positional_args.must_be_empty
|
47
|
-
subject.hash_args.must_be_empty
|
48
|
-
subject.hash_args_names.must_be_empty
|
49
|
-
subject.hash_args_required.must_be_empty
|
50
|
-
subject.default_values.must_be_empty
|
46
|
+
_(subject.positional_args).must_be_empty
|
47
|
+
_(subject.hash_args).must_be_empty
|
48
|
+
_(subject.hash_args_names).must_be_empty
|
49
|
+
_(subject.hash_args_required).must_be_empty
|
50
|
+
_(subject.default_values).must_be_empty
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -7,7 +7,7 @@ describe Object, ".pattr_initialize" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
example = klass.new("Foo", "Bar")
|
10
|
-
example.send(:foo).must_equal "Foo"
|
10
|
+
_(example.send(:foo)).must_equal "Foo"
|
11
11
|
end
|
12
12
|
|
13
13
|
it "works with hash ivars" do
|
@@ -16,7 +16,7 @@ describe Object, ".pattr_initialize" do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
example = klass.new("Foo", bar: "Bar", baz: "Baz")
|
19
|
-
example.send(:baz).must_equal "Baz"
|
19
|
+
_(example.send(:baz)).must_equal "Baz"
|
20
20
|
end
|
21
21
|
|
22
22
|
it "works with hash ivars and default values" do
|
@@ -25,7 +25,7 @@ describe Object, ".pattr_initialize" do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
example = klass.new("Foo")
|
28
|
-
example.send(:baz).must_equal "Baz"
|
28
|
+
_(example.send(:baz)).must_equal "Baz"
|
29
29
|
end
|
30
30
|
|
31
31
|
it "can reference private initializer methods in an initializer block" do
|
@@ -39,7 +39,7 @@ describe Object, ".pattr_initialize" do
|
|
39
39
|
|
40
40
|
example = klass.new("expected")
|
41
41
|
|
42
|
-
example.copy.must_equal "expected"
|
42
|
+
_(example.copy).must_equal "expected"
|
43
43
|
end
|
44
44
|
|
45
45
|
it "accepts the alias attr_private_initialize" do
|
@@ -48,6 +48,6 @@ describe Object, ".pattr_initialize" do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
example = klass.new("Foo", "Bar")
|
51
|
-
example.send(:foo).must_equal "Foo"
|
51
|
+
_(example.send(:foo)).must_equal "Foo"
|
52
52
|
end
|
53
53
|
end
|
@@ -7,7 +7,7 @@ describe Object, ".rattr_initialize" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
example = klass.new("Foo", "Bar")
|
10
|
-
example.public_send(:foo).must_equal "Foo"
|
10
|
+
_(example.public_send(:foo)).must_equal "Foo"
|
11
11
|
end
|
12
12
|
|
13
13
|
it "works with hash ivars" do
|
@@ -16,7 +16,7 @@ describe Object, ".rattr_initialize" do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
example = klass.new("Foo", bar: "Bar", baz: "Baz")
|
19
|
-
example.public_send(:baz).must_equal "Baz"
|
19
|
+
_(example.public_send(:baz)).must_equal "Baz"
|
20
20
|
end
|
21
21
|
|
22
22
|
it "works with hash ivars and default values" do
|
@@ -25,7 +25,7 @@ describe Object, ".rattr_initialize" do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
example = klass.new("Foo")
|
28
|
-
example.send(:baz).must_equal "Baz"
|
28
|
+
_(example.send(:baz)).must_equal "Baz"
|
29
29
|
end
|
30
30
|
|
31
31
|
it "accepts the alias attr_reader_initialize" do
|
@@ -34,6 +34,6 @@ describe Object, ".rattr_initialize" do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
example = klass.new("Foo", "Bar")
|
37
|
-
example.public_send(:foo).must_equal "Foo"
|
37
|
+
_(example.public_send(:foo)).must_equal "Foo"
|
38
38
|
end
|
39
39
|
end
|
@@ -56,4 +56,34 @@ describe Object, ".static_facade" do
|
|
56
56
|
|
57
57
|
assert klass.foo { :bar } == :bar
|
58
58
|
end
|
59
|
+
|
60
|
+
it "does not blow up when the class method is called with an empty hash" do
|
61
|
+
klass = Class.new do
|
62
|
+
static_facade :foo,
|
63
|
+
:value
|
64
|
+
|
65
|
+
def foo
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
refute_raises_anything { klass.foo({}) }
|
70
|
+
end
|
71
|
+
|
72
|
+
it "does not emit warnings when the initializer is overridden with more keyword arguments" do
|
73
|
+
superklass = Class.new do
|
74
|
+
static_facade :something, [ :foo!, :bar! ]
|
75
|
+
|
76
|
+
def something
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
klass = Class.new(superklass) do
|
81
|
+
def initialize(extra:, **rest)
|
82
|
+
super(**rest)
|
83
|
+
@extra = extra
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
refute_warnings_emitted { klass.something(foo: 1, bar: 2, extra: "yay") }
|
88
|
+
end
|
59
89
|
end
|
@@ -5,15 +5,15 @@ describe AttrExtras::Utils do
|
|
5
5
|
subject { AttrExtras::Utils.flat_names(names) }
|
6
6
|
|
7
7
|
it "strips any bangs from a flat list of arguments" do
|
8
|
-
AttrExtras::Utils.flat_names([ :foo, :bar! ]).must_equal [ "foo", "bar" ]
|
8
|
+
_(AttrExtras::Utils.flat_names([ :foo, :bar! ])).must_equal [ "foo", "bar" ]
|
9
9
|
end
|
10
10
|
|
11
11
|
it "flattens hash arguments and strips any bangs" do
|
12
|
-
AttrExtras::Utils.flat_names([ :foo, [ :bar, :baz! ] ]).must_equal [ "foo", "bar", "baz" ]
|
12
|
+
_(AttrExtras::Utils.flat_names([ :foo, [ :bar, :baz! ] ])).must_equal [ "foo", "bar", "baz" ]
|
13
13
|
end
|
14
14
|
|
15
15
|
it "flattens hash arguments with defaults and strips any bangs" do
|
16
|
-
AttrExtras::Utils.flat_names([ :foo, [ bar: "Bar", baz!: "Baz"] ]).must_equal [ "foo", "bar", "baz" ]
|
16
|
+
_(AttrExtras::Utils.flat_names([ :foo, [ bar: "Bar", baz!: "Baz"] ])).must_equal [ "foo", "bar", "baz" ]
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -9,8 +9,8 @@ describe Object, ".vattr_initialize" do
|
|
9
9
|
example1 = klass.new("Foo", "Bar")
|
10
10
|
example2 = klass.new("Foo", "Bar")
|
11
11
|
|
12
|
-
example1.foo.must_equal "Foo"
|
13
|
-
example1.must_equal example2
|
12
|
+
_(example1.foo).must_equal "Foo"
|
13
|
+
_(example1).must_equal example2
|
14
14
|
end
|
15
15
|
|
16
16
|
it "works with hash ivars" do
|
@@ -20,8 +20,8 @@ describe Object, ".vattr_initialize" do
|
|
20
20
|
|
21
21
|
example1 = klass.new("Foo", bar: "Bar", baz: "Baz")
|
22
22
|
example2 = klass.new("Foo", bar: "Bar", baz: "Baz")
|
23
|
-
example1.baz.must_equal "Baz"
|
24
|
-
example1.must_equal example2
|
23
|
+
_(example1.baz).must_equal "Baz"
|
24
|
+
_(example1).must_equal example2
|
25
25
|
end
|
26
26
|
|
27
27
|
it "works with hash ivars and default values" do
|
@@ -31,8 +31,8 @@ describe Object, ".vattr_initialize" do
|
|
31
31
|
|
32
32
|
example1 = klass.new("Foo")
|
33
33
|
example2 = klass.new("Foo")
|
34
|
-
example1.baz.must_equal "Baz"
|
35
|
-
example1.must_equal example2
|
34
|
+
_(example1.baz).must_equal "Baz"
|
35
|
+
_(example1).must_equal example2
|
36
36
|
end
|
37
37
|
|
38
38
|
it "can accept an initializer block" do
|
@@ -45,7 +45,7 @@ describe Object, ".vattr_initialize" do
|
|
45
45
|
|
46
46
|
klass.new("expected")
|
47
47
|
|
48
|
-
called.must_equal true
|
48
|
+
_(called).must_equal true
|
49
49
|
end
|
50
50
|
|
51
51
|
it "accepts the alias attr_value_initialize" do
|
@@ -56,7 +56,7 @@ describe Object, ".vattr_initialize" do
|
|
56
56
|
example1 = klass.new("Foo", "Bar")
|
57
57
|
example2 = klass.new("Foo", "Bar")
|
58
58
|
|
59
|
-
example1.foo.must_equal "Foo"
|
60
|
-
example1.must_equal example2
|
59
|
+
_(example1.foo).must_equal "Foo"
|
60
|
+
_(example1).must_equal example2
|
61
61
|
end
|
62
62
|
end
|
data/spec/attr_extras_spec.rb
CHANGED
@@ -2,3 +2,20 @@ require "minitest/autorun"
|
|
2
2
|
require "minitest/pride"
|
3
3
|
|
4
4
|
$: << File.dirname(__FILE__) + "/../lib"
|
5
|
+
|
6
|
+
Minitest::Test.class_eval do
|
7
|
+
def refute_warnings_emitted(&block)
|
8
|
+
_, stderr = capture_io(&block)
|
9
|
+
|
10
|
+
assert stderr.empty?, -> do
|
11
|
+
warnings = stderr.strip.split("\n").map { |line| " #{line}" }.join("\n")
|
12
|
+
"Expected no warnings to be emitted, but these ones were:\n\n#{warnings}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def refute_raises_anything
|
17
|
+
yield
|
18
|
+
rescue => error
|
19
|
+
flunk "Expected no error to be raised, but got #{error.class} (#{error.message})."
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attr_extras
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.2.
|
4
|
+
version: 6.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henrik Nyh
|
8
8
|
- Joakim Kolsjö
|
9
|
+
- Tomas Skogberg
|
9
10
|
- Victor Arias
|
10
11
|
- Ola K
|
11
12
|
autorequire:
|
12
13
|
bindir: bin
|
13
14
|
cert_chain: []
|
14
|
-
date:
|
15
|
+
date: 2021-11-19 00:00:00.000000000 Z
|
15
16
|
dependencies:
|
16
17
|
- !ruby/object:Gem::Dependency
|
17
18
|
name: minitest
|
@@ -33,14 +34,14 @@ dependencies:
|
|
33
34
|
requirements:
|
34
35
|
- - "~>"
|
35
36
|
- !ruby/object:Gem::Version
|
36
|
-
version: 1.5.
|
37
|
+
version: 1.5.1
|
37
38
|
type: :development
|
38
39
|
prerelease: false
|
39
40
|
version_requirements: !ruby/object:Gem::Requirement
|
40
41
|
requirements:
|
41
42
|
- - "~>"
|
42
43
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.5.
|
44
|
+
version: 1.5.1
|
44
45
|
- !ruby/object:Gem::Dependency
|
45
46
|
name: rake
|
46
47
|
requirement: !ruby/object:Gem::Requirement
|
@@ -62,8 +63,8 @@ executables: []
|
|
62
63
|
extensions: []
|
63
64
|
extra_rdoc_files: []
|
64
65
|
files:
|
66
|
+
- ".github/workflows/ci.yml"
|
65
67
|
- ".gitignore"
|
66
|
-
- ".travis.yml"
|
67
68
|
- CHANGELOG.md
|
68
69
|
- Gemfile
|
69
70
|
- LICENSE.txt
|
@@ -101,7 +102,8 @@ files:
|
|
101
102
|
homepage: https://github.com/barsoom/attr_extras
|
102
103
|
licenses:
|
103
104
|
- MIT
|
104
|
-
metadata:
|
105
|
+
metadata:
|
106
|
+
rubygems_mfa_required: 'true'
|
105
107
|
post_install_message:
|
106
108
|
rdoc_options: []
|
107
109
|
require_paths:
|
@@ -117,8 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
119
|
- !ruby/object:Gem::Version
|
118
120
|
version: '0'
|
119
121
|
requirements: []
|
120
|
-
|
121
|
-
rubygems_version: 2.6.11
|
122
|
+
rubygems_version: 3.2.28
|
122
123
|
signing_key:
|
123
124
|
specification_version: 4
|
124
125
|
summary: Takes some boilerplate out of Ruby with methods like attr_initialize.
|