attr_extras 6.1.0 → 6.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d927809a2d8cd1a5da0e4e910942027d230dfb45
4
- data.tar.gz: 80988c71e715df538d82b902846ca660e5f5a4fb
2
+ SHA256:
3
+ metadata.gz: e4f8e12f94bbc166632e1a65a52f83ddc14e4982ad57f87043fa285e7e7a8cf2
4
+ data.tar.gz: 1d621e46616f5df763909d9481f983d60fe4e014a8a9a3b0dbfc2635d8867d71
5
5
  SHA512:
6
- metadata.gz: 8d9bd920c1a3227cd592dab70c0035124322bc0a358ed535b8aa5e42c6a8fb26bdcde0c85c8ef92a81131179e0b9fafbb928ccff2ab454164bc549cec36bd745
7
- data.tar.gz: 96ff27fb9e371d898f3056159a644cb3828ad2e10bc3c83273fb38ab8441661e78f46bf4f2960b59f0af09affaa39cb8033f5a75b64efbc74476705268a73735
6
+ metadata.gz: 44cade5ed299c18a1e8c01706e04767f1b49f3a934a53759542702fd6435c8ba225b360250dd276a78174fdea32e112ca1155cf20e172db765940ea05ecb3b03
7
+ data.tar.gz: 7fe165a6de71503666cb3344478c769385d50a31ca11de78cce7f934d87393867a5e2c3bc05703c7a3fdc86dd81da729703452c35d0999600f70b42a35851629
@@ -1,10 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.6.1
4
- - 2.5.3
5
- - 2.4.1
6
- - 2.3.3
3
+ - 2.7.1
4
+ - 2.6.6
5
+ - 2.5.8
7
6
  - jruby-head
8
- before_install: # For jruby-head to work.
9
- - gem install bundler
10
- - gem update bundler
@@ -1,13 +1,34 @@
1
1
  # Changelog
2
2
 
3
- # 6.1.0
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
- # 6.0.0 (yanked)
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
- # 5.2.0 and earlier
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
+ [![Gem Version](https://badge.fury.io/rb/attr_extras.svg)](https://badge.fury.io/rb/attr_extras)
1
2
  [![Build status](https://secure.travis-ci.org/barsoom/attr_extras.svg)](https://travis-ci.org/#!/barsoom/attr_extras/builds)
2
3
  [![Code Climate](https://codeclimate.com/github/barsoom/attr_extras/badges/gpa.svg)](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
 
@@ -1,8 +1,8 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/attr_extras/version', __FILE__)
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.0" # Running individual tests.
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.select { |name| name.is_a?(Hash) }.inject(:merge) || {}
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)
@@ -21,9 +21,8 @@ module AttrExtras
21
21
  end
22
22
 
23
23
  def attr_private(*names)
24
- # Need this to avoid "private attribute?" warnings when running
25
- # the full test suite; not sure why exactly.
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
- Array(method_name_or_names).each do |method_name|
66
- define_singleton_method(method_name) do |*values, &block|
67
- new(*values).public_send(method_name, &block)
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
 
@@ -1,5 +1,7 @@
1
1
  module AttrExtras::Utils
2
2
  def self.flat_names(names)
3
- names.flatten.map { |x| x.to_s.sub(/!\z/, "") }
3
+ names.flatten.
4
+ flat_map { |x| x.is_a?(Hash) ? x.keys : x }.
5
+ map { |x| x.to_s.sub(/!\z/, "") }
4
6
  end
5
7
  end
@@ -1,3 +1,3 @@
1
1
  module AttrExtras
2
- VERSION = "6.1.0"
2
+ VERSION = "6.2.4"
3
3
  end
@@ -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
@@ -15,6 +15,6 @@ describe Object, ".attr_id_query" do
15
15
  end
16
16
 
17
17
  it "requires a trailing questionmark" do
18
- lambda { Object.attr_id_query(:foo) }.must_raise ArgumentError
18
+ _(lambda { Object.attr_id_query(:foo) }).must_raise ArgumentError
19
19
  end
20
20
  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
@@ -14,6 +14,6 @@ describe Object, ".attr_query" do
14
14
  end
15
15
 
16
16
  it "requires a trailing questionmark" do
17
- lambda { Object.attr_query(:foo) }.must_raise ArgumentError
17
+ _(lambda { Object.attr_query(:foo) }).must_raise ArgumentError
18
18
  end
19
19
  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
@@ -10,6 +10,6 @@ describe AttrExtras do
10
10
  include mod
11
11
  end
12
12
 
13
- klass.new("Hello").send(:name).must_equal "Hello"
13
+ _(klass.new("Hello").send(:name)).must_equal "Hello"
14
14
  end
15
15
  end
@@ -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.1.0
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: 2019-01-31 00:00:00.000000000 Z
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.0
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.0
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
- rubyforge_project:
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