attr_extras 6.1.0 → 6.2.4
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/.travis.yml +3 -7
- data/CHANGELOG.md +24 -3
- data/README.md +25 -3
- data/attr_extras.gemspec +3 -3
- data/lib/attr_extras/attr_implement.rb +1 -1
- data/lib/attr_extras/attr_initialize.rb +1 -1
- data/lib/attr_extras/explicit.rb +13 -6
- data/lib/attr_extras/utils.rb +3 -1
- data/lib/attr_extras/version.rb +1 -1
- data/spec/attr_extras/aattr_initialize_spec.rb +16 -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 +33 -20
- 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 +13 -4
- data/spec/attr_extras/rattr_initialize_spec.rb +13 -4
- data/spec/attr_extras/static_facade_spec.rb +30 -0
- data/spec/attr_extras/utils_spec.rb +19 -0
- data/spec/attr_extras/vattr_initialize_spec.rb +18 -7
- data/spec/attr_extras_spec.rb +1 -1
- data/spec/spec_helper_without_loading_attr_extras.rb +17 -0
- metadata +8 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: e4f8e12f94bbc166632e1a65a52f83ddc14e4982ad57f87043fa285e7e7a8cf2
|
|
4
|
+
data.tar.gz: 1d621e46616f5df763909d9481f983d60fe4e014a8a9a3b0dbfc2635d8867d71
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 44cade5ed299c18a1e8c01706e04767f1b49f3a934a53759542702fd6435c8ba225b360250dd276a78174fdea32e112ca1155cf20e172db765940ea05ecb3b03
|
|
7
|
+
data.tar.gz: 7fe165a6de71503666cb3344478c769385d50a31ca11de78cce7f934d87393867a5e2c3bc05703c7a3fdc86dd81da729703452c35d0999600f70b42a35851629
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,13 +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)
|
|
17
|
+
|
|
18
|
+
* Bugfix with keyword argument defaults. Thanks to [Roman Dubrovsky](https://github.com/barsoom/attr_extras/pull/29)!
|
|
19
|
+
|
|
20
|
+
## [6.2.0](https://github.com/barsoom/attr_extras/releases/tag/v6.2.0)
|
|
21
|
+
|
|
22
|
+
* Another bugfix when passing hash values to positional arguments.
|
|
23
|
+
|
|
24
|
+
## [6.1.0](https://github.com/barsoom/attr_extras/releases/tag/v6.1.0)
|
|
4
25
|
|
|
5
26
|
* Bugfix when passing hash values to positional arguments.
|
|
6
27
|
|
|
7
|
-
|
|
28
|
+
## 6.0.0 (yanked)
|
|
8
29
|
|
|
9
30
|
* Default arguments! Thanks to [Ola K](https://github.com/lesin). For example: `pattr_initialize [:foo, bar: "default value"]`
|
|
10
31
|
|
|
11
|
-
|
|
32
|
+
## [5.2.0](https://github.com/barsoom/attr_extras/releases/tag/v5.2.0) and earlier
|
|
12
33
|
|
|
13
34
|
Please [see Git history](https://github.com/barsoom/attr_extras/releases).
|
data/README.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
[](https://badge.fury.io/rb/attr_extras)
|
|
1
2
|
[](https://travis-ci.org/#!/barsoom/attr_extras/builds)
|
|
2
3
|
[](https://codeclimate.com/github/barsoom/attr_extras)
|
|
3
4
|
|
|
@@ -59,14 +60,35 @@ Also provides conveniences for creating value objects, method objects, query met
|
|
|
59
60
|
|
|
60
61
|
`attr_initialize [:bar, :baz!]` defines an initializer that takes two keyword arguments, assigning `@bar` (optional) and `@baz` (required).
|
|
61
62
|
|
|
62
|
-
Keyword arguments can have default values:
|
|
63
|
-
`attr_initialize [:bar, baz: "default value"]` defines an initializer that takes two keyword arguments, assigning `@bar` (optional) and `@baz` (optional with default value `"default value"`).
|
|
64
|
-
|
|
65
63
|
If you pass unknown keyword arguments, you will get an `ArgumentError`.
|
|
66
64
|
If you don't pass required arguments and don't define default value for them, you will get a `KeyError`.
|
|
67
65
|
|
|
68
66
|
`attr_initialize` can also accept a block which will be invoked after initialization. This is useful for e.g. initializing private data as necessary.
|
|
69
67
|
|
|
68
|
+
#### Default values
|
|
69
|
+
|
|
70
|
+
Keyword arguments can have default values:
|
|
71
|
+
|
|
72
|
+
`attr_initialize [:bar, baz: "default value"]` defines an initializer that takes two keyword arguments, assigning `@bar` (optional) and `@baz` (optional with default value `"default value"`).
|
|
73
|
+
|
|
74
|
+
Note that default values are evaluated *when the class is loaded* and not on every instantition. So `attr_initialize [time: Time.now]` might not do what you expect.
|
|
75
|
+
|
|
76
|
+
You can always use regular Ruby methods to achieve this:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
class Foo
|
|
80
|
+
attr_initialize [:time]
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def time
|
|
85
|
+
@time || Time.now
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Or just use a regular initializer with default values.
|
|
91
|
+
|
|
70
92
|
|
|
71
93
|
### `attr_private`
|
|
72
94
|
|
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"
|
|
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
|
16
16
|
gem.version = AttrExtras::VERSION
|
|
17
17
|
|
|
18
18
|
gem.add_development_dependency "minitest", ">= 5"
|
|
19
|
-
gem.add_development_dependency "m", "~> 1.5.
|
|
19
|
+
gem.add_development_dependency "m", "~> 1.5.1" # Running individual tests.
|
|
20
20
|
|
|
21
21
|
# For Travis CI.
|
|
22
22
|
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
|
|
@@ -19,7 +19,7 @@ class AttrExtras::AttrInitialize
|
|
|
19
19
|
validate_args = method(:validate_args)
|
|
20
20
|
|
|
21
21
|
klass.send(:define_method, :initialize) do |*values|
|
|
22
|
-
hash_values = values.
|
|
22
|
+
hash_values = (values[(klass_params.positional_args.length)..-1] || []).inject(:merge) || {}
|
|
23
23
|
|
|
24
24
|
validate_arity.call(values.length, self.class)
|
|
25
25
|
validate_args.call(values, klass_params)
|
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/utils.rb
CHANGED
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,17 +19,27 @@ 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
|
|
26
26
|
klass = Class.new do
|
|
27
|
-
aattr_initialize :foo, [:bar, :baz!]
|
|
27
|
+
aattr_initialize :foo, [ :bar, :baz! ]
|
|
28
28
|
end
|
|
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
|
+
end
|
|
34
|
+
|
|
35
|
+
it "works with hash ivars and default values" do
|
|
36
|
+
klass = Class.new do
|
|
37
|
+
aattr_initialize :foo, [ bar: "Bar", baz!: "Baz" ]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
example = klass.new("Foo")
|
|
41
|
+
|
|
42
|
+
_(example.baz).must_equal "Baz"
|
|
33
43
|
end
|
|
34
44
|
|
|
35
45
|
it "accepts a block for initialization" do
|
|
@@ -43,7 +53,7 @@ describe Object, ".aattr_initialize" do
|
|
|
43
53
|
|
|
44
54
|
example = klass.new("expected")
|
|
45
55
|
|
|
46
|
-
example.copy.must_equal "expected"
|
|
56
|
+
_(example.copy).must_equal "expected"
|
|
47
57
|
end
|
|
48
58
|
|
|
49
59
|
it "accepts the alias attr_accessor_initialize" do
|
|
@@ -53,6 +63,6 @@ describe Object, ".aattr_initialize" do
|
|
|
53
63
|
|
|
54
64
|
example = klass.new("Foo", "Bar")
|
|
55
65
|
|
|
56
|
-
example.foo.must_equal "Foo"
|
|
66
|
+
_(example.foo).must_equal "Foo"
|
|
57
67
|
end
|
|
58
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,21 @@ 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
|
+
end
|
|
105
|
+
|
|
106
|
+
# Regression.
|
|
107
|
+
it "doesn't store hash values to positional arguments as ivars" do
|
|
108
|
+
klass = Class.new do
|
|
109
|
+
attr_initialize :foo
|
|
110
|
+
attr_reader :foo
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Should not raise.
|
|
114
|
+
example = klass.new({ "invalid.ivar.name" => 123 })
|
|
115
|
+
|
|
116
|
+
_(example.foo).must_equal({ "invalid.ivar.name" => 123 })
|
|
104
117
|
end
|
|
105
118
|
|
|
106
119
|
it "accepts a block for initialization" do
|
|
@@ -114,6 +127,6 @@ describe Object, ".attr_initialize" do
|
|
|
114
127
|
|
|
115
128
|
example = klass.new("expected")
|
|
116
129
|
|
|
117
|
-
example.copy.must_equal "expected"
|
|
130
|
+
_(example.copy).must_equal "expected"
|
|
118
131
|
end
|
|
119
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,16 @@ 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
|
+
end
|
|
21
|
+
|
|
22
|
+
it "works with hash ivars and default values" do
|
|
23
|
+
klass = Class.new do
|
|
24
|
+
pattr_initialize :foo, [ bar: "Bar", baz!: "Baz" ]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
example = klass.new("Foo")
|
|
28
|
+
_(example.send(:baz)).must_equal "Baz"
|
|
20
29
|
end
|
|
21
30
|
|
|
22
31
|
it "can reference private initializer methods in an initializer block" do
|
|
@@ -30,7 +39,7 @@ describe Object, ".pattr_initialize" do
|
|
|
30
39
|
|
|
31
40
|
example = klass.new("expected")
|
|
32
41
|
|
|
33
|
-
example.copy.must_equal "expected"
|
|
42
|
+
_(example.copy).must_equal "expected"
|
|
34
43
|
end
|
|
35
44
|
|
|
36
45
|
it "accepts the alias attr_private_initialize" do
|
|
@@ -39,6 +48,6 @@ describe Object, ".pattr_initialize" do
|
|
|
39
48
|
end
|
|
40
49
|
|
|
41
50
|
example = klass.new("Foo", "Bar")
|
|
42
|
-
example.send(:foo).must_equal "Foo"
|
|
51
|
+
_(example.send(:foo)).must_equal "Foo"
|
|
43
52
|
end
|
|
44
53
|
end
|
|
@@ -7,16 +7,25 @@ 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
|
|
14
14
|
klass = Class.new do
|
|
15
|
-
rattr_initialize :foo, [:bar, :baz!]
|
|
15
|
+
rattr_initialize :foo, [ :bar, :baz! ]
|
|
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
|
+
end
|
|
21
|
+
|
|
22
|
+
it "works with hash ivars and default values" do
|
|
23
|
+
klass = Class.new do
|
|
24
|
+
rattr_initialize :foo, [ bar: "Bar", baz!: "Baz" ]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
example = klass.new("Foo")
|
|
28
|
+
_(example.send(:baz)).must_equal "Baz"
|
|
20
29
|
end
|
|
21
30
|
|
|
22
31
|
it "accepts the alias attr_reader_initialize" do
|
|
@@ -25,6 +34,6 @@ describe Object, ".rattr_initialize" do
|
|
|
25
34
|
end
|
|
26
35
|
|
|
27
36
|
example = klass.new("Foo", "Bar")
|
|
28
|
-
example.public_send(:foo).must_equal "Foo"
|
|
37
|
+
_(example.public_send(:foo)).must_equal "Foo"
|
|
29
38
|
end
|
|
30
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
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe AttrExtras::Utils do
|
|
4
|
+
describe ".flat_names" do
|
|
5
|
+
subject { AttrExtras::Utils.flat_names(names) }
|
|
6
|
+
|
|
7
|
+
it "strips any bangs from a flat list of arguments" do
|
|
8
|
+
_(AttrExtras::Utils.flat_names([ :foo, :bar! ])).must_equal [ "foo", "bar" ]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "flattens hash arguments and strips any bangs" do
|
|
12
|
+
_(AttrExtras::Utils.flat_names([ :foo, [ :bar, :baz! ] ])).must_equal [ "foo", "bar", "baz" ]
|
|
13
|
+
end
|
|
14
|
+
|
|
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" ]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
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,19 @@ 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
|
+
end
|
|
26
|
+
|
|
27
|
+
it "works with hash ivars and default values" do
|
|
28
|
+
klass = Class.new do
|
|
29
|
+
vattr_initialize :foo, [ bar: "Bar", baz!: "Baz" ]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
example1 = klass.new("Foo")
|
|
33
|
+
example2 = klass.new("Foo")
|
|
34
|
+
_(example1.baz).must_equal "Baz"
|
|
35
|
+
_(example1).must_equal example2
|
|
25
36
|
end
|
|
26
37
|
|
|
27
38
|
it "can accept an initializer block" do
|
|
@@ -34,7 +45,7 @@ describe Object, ".vattr_initialize" do
|
|
|
34
45
|
|
|
35
46
|
klass.new("expected")
|
|
36
47
|
|
|
37
|
-
called.must_equal true
|
|
48
|
+
_(called).must_equal true
|
|
38
49
|
end
|
|
39
50
|
|
|
40
51
|
it "accepts the alias attr_value_initialize" do
|
|
@@ -45,7 +56,7 @@ describe Object, ".vattr_initialize" do
|
|
|
45
56
|
example1 = klass.new("Foo", "Bar")
|
|
46
57
|
example2 = klass.new("Foo", "Bar")
|
|
47
58
|
|
|
48
|
-
example1.foo.must_equal "Foo"
|
|
49
|
-
example1.must_equal example2
|
|
59
|
+
_(example1.foo).must_equal "Foo"
|
|
60
|
+
_(example1).must_equal example2
|
|
50
61
|
end
|
|
51
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.
|
|
4
|
+
version: 6.2.4
|
|
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: 2020-06-08 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
|
|
@@ -93,6 +94,7 @@ files:
|
|
|
93
94
|
- spec/attr_extras/pattr_initialize_spec.rb
|
|
94
95
|
- spec/attr_extras/rattr_initialize_spec.rb
|
|
95
96
|
- spec/attr_extras/static_facade_spec.rb
|
|
97
|
+
- spec/attr_extras/utils_spec.rb
|
|
96
98
|
- spec/attr_extras/vattr_initialize_spec.rb
|
|
97
99
|
- spec/attr_extras_spec.rb
|
|
98
100
|
- spec/spec_helper.rb
|
|
@@ -116,8 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
116
118
|
- !ruby/object:Gem::Version
|
|
117
119
|
version: '0'
|
|
118
120
|
requirements: []
|
|
119
|
-
|
|
120
|
-
rubygems_version: 2.6.11
|
|
121
|
+
rubygems_version: 3.1.2
|
|
121
122
|
signing_key:
|
|
122
123
|
specification_version: 4
|
|
123
124
|
summary: Takes some boilerplate out of Ruby with methods like attr_initialize.
|
|
@@ -135,6 +136,7 @@ test_files:
|
|
|
135
136
|
- spec/attr_extras/pattr_initialize_spec.rb
|
|
136
137
|
- spec/attr_extras/rattr_initialize_spec.rb
|
|
137
138
|
- spec/attr_extras/static_facade_spec.rb
|
|
139
|
+
- spec/attr_extras/utils_spec.rb
|
|
138
140
|
- spec/attr_extras/vattr_initialize_spec.rb
|
|
139
141
|
- spec/attr_extras_spec.rb
|
|
140
142
|
- spec/spec_helper.rb
|