dry-initializer 1.2.0 → 1.3.0

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
2
  SHA1:
3
- metadata.gz: 77c08e7da9990b73b8c94815830a19694b424317
4
- data.tar.gz: df1ab88700f059cd3327e7c1745d41aaa901000a
3
+ metadata.gz: 1a64c90248831e6513871de4f8f489422f3522e0
4
+ data.tar.gz: bc6cfa16dd5a4922c54869d993fc3d8ac6e08bb6
5
5
  SHA512:
6
- metadata.gz: 8b04de090fba7b94c917791ebdbff775e3dfd4ae4bfb2c7d51ec9785ae7007324802870c476daf348a397a0ef3ff8c34d70c17fa28777cbb338eb4de44acb137
7
- data.tar.gz: 8bb88fc5ada80331a4c1a8d1a076200294db7d2c66009f6da79edef7742fe03e5094d69f5ac97ee57c336354504f00dcc95bf02ac527d21880dfb0ba2be043f4
6
+ metadata.gz: 615d1a7be21495edcfabe3d4884b637700c1ba032de7b8abc6cdd9d08c10abf00a1febcfc78ae98e6d4c2e0f25031c547326e6640fea561fc755236add5064e8
7
+ data.tar.gz: 2ca11b3bdaa8d57adc40c7ca07aa5f790a306aeb8d88facacb6233031eaa7be2524bce10e921c775b93edb6720791f8842946a492d2603dc0857b39cc94b6784
data/CHANGELOG.md CHANGED
@@ -1,34 +1,63 @@
1
+ ## v1.3.0 2017-03-05
2
+
3
+ ### Added
4
+ - No-undefined configuration of the initializer (nepalez, flash-gordon)
5
+
6
+ You can either extend or include module `Dry::Initializer` with additional option
7
+ `[undefined: false]`. This time `nil` will be assigned instead of
8
+ `Dry::Initializer::UNDEFINED`. Readers becomes faster because there is no need
9
+ to chech whether a variable was defined or not. At the same time the initializer
10
+ doesn't distinct cases when a variable was set to `nil` explicitly, and when it wasn's set at all:
11
+
12
+ class Foo # old behavior
13
+ extend Dry::Initializer
14
+ param :qux, optional: true
15
+ end
16
+
17
+ class Bar # new behavior
18
+ extend Dry::Initializer[undefined: false]
19
+ param :qux, optional: true
20
+ end
21
+
22
+ Foo.new.instance_variable_get(:@qux) # => Dry::Initializer::UNDEFINED
23
+ Bar.new.instance_variable_get(:@qux) # => nil
24
+
25
+ ### Internals
26
+ - Fixed method definitions for performance at the load time (nepalez, flash-gordon)
27
+
28
+ [Compare v1.2.0...v1.3.0](https://github.com/dry-rb/dry-initializer/compare/v1.2.0...v1.3.0)
29
+
1
30
  ## v1.2.0 2017-03-05
2
31
 
3
- # Fixed
32
+ ### Fixed
4
33
  - The `@__options__` variable collects renamed options after default values and coercions were applied (nepalez)
5
34
 
6
35
  [Compare v1.1.3...v1.2.0](https://github.com/dry-rb/dry-initializer/compare/v1.1.3...v1.2.0)
7
36
 
8
37
  ## v1.1.3 2017-03-01
9
38
 
10
- # Added
39
+ ### Added
11
40
  - Support for lambdas as default values (nepalez, gzigzigzeo)
12
41
 
13
42
  [Compare v1.1.2...v1.1.3](https://github.com/dry-rb/dry-initializer/compare/v1.1.2...v1.1.3)
14
43
 
15
44
  ## v1.1.2 2017-02-06
16
45
 
17
- # Internals
46
+ ### Internals
18
47
  - Remove previously defined methods before redefining them (flash-gordon)
19
48
 
20
49
  [Compare v1.1.1...v1.1.2](https://github.com/dry-rb/dry-initializer/compare/v1.1.1...v1.1.2)
21
50
 
22
51
  ## v1.1.1 2017-02-04
23
52
 
24
- # Bugs Fixed
53
+ ### Bugs Fixed
25
54
  - `@__options__` collects defined options only (nepalez)
26
55
 
27
56
  [Compare v1.1.0...v1.1.1](https://github.com/dry-rb/dry-initializer/compare/v1.1.0...v1.1.1)
28
57
 
29
58
  ## v1.1.0 2017-01-28
30
59
 
31
- # Added:
60
+ ### Added:
32
61
  - enhancement via `Dry::Initializer::Attribute.dispatchers` registry (nepalez)
33
62
 
34
63
  # Register dispatcher for `:string` option
@@ -44,7 +73,7 @@
44
73
 
45
74
  User.new(:Andy).name # => "Andy"
46
75
 
47
- # Internals:
76
+ ### Internals:
48
77
  - optimize assignments for performance (nepalez)
49
78
 
50
79
  [Compare v1.0.0...v1.1.0](https://github.com/dry-rb/dry-initializer/compare/v1.0.0...v1.1.0)
@@ -53,10 +82,10 @@
53
82
 
54
83
  In this version the code has been rewritten for simplicity
55
84
 
56
- # BREAKING CHANGES
85
+ ### BREAKING CHANGES
57
86
  - when `param` or `option` was not defined, the corresponding **variable** is set to `Dry::Initializer::UNDEFINED`, but the **reader** (when defined) will return `nil` (nepalez)
58
87
 
59
- # Added:
88
+ ### Added:
60
89
  - support for reloading `param` and `option` definitions (nepalez)
61
90
 
62
91
  class User
@@ -86,7 +115,7 @@ In this version the code has been rewritten for simplicity
86
115
  User.new(phone: '1234567890').phone # => '1234567890'
87
116
  User.new(number: '1234567890').phone # => '1234567890'
88
117
 
89
- # Internals
118
+ ### Internals
90
119
  - `Dry::Initializer` and `Dry::Initializer::Mixin` became aliases (nepalez)
91
120
 
92
121
  [Compare v0.11.0...v1.0.0](https://github.com/dry-rb/dry-initializer/compare/v0.11.0...v1.0.0)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = "dry-initializer"
3
- gem.version = "1.2.0"
3
+ gem.version = "1.3.0"
4
4
  gem.author = ["Vladimir Kochnev (marshall-lee)", "Andrew Kozin (nepalez)"]
5
5
  gem.email = ["hashtable@yandex.ru", "andrew.kozin@gmail.com"]
6
6
  gem.homepage = "https://github.com/dryrb/dry-initializer"
@@ -8,6 +8,7 @@ module Dry
8
8
  require_relative "initializer/param"
9
9
  require_relative "initializer/option"
10
10
  require_relative "initializer/builder"
11
+ require_relative "initializer/dsl"
11
12
 
12
13
  # rubocop: disable Style/ConstantName
13
14
  Mixin = self # for compatibility to versions below 0.12
@@ -17,36 +18,7 @@ module Dry
17
18
  obj.define_singleton_method(:inspect) { "Dry::Initializer::UNDEFINED" }
18
19
  end.freeze
19
20
 
20
- class << self
21
- def extended(klass)
22
- super
23
- mixin = klass.send(:__initializer_mixin__)
24
- builder = klass.send(:__initializer_builder__)
25
-
26
- builder.call(mixin)
27
- klass.include(mixin)
28
- klass.send(:define_method, :initialize) do |*args|
29
- __initialize__(*args)
30
- end
31
- end
32
-
33
- def define(fn = nil, &block)
34
- mixin = Module.new do
35
- def initialize(*args)
36
- __initialize__(*args)
37
- end
38
- end
39
-
40
- builder = Builder.new
41
- builder.instance_exec(&(fn || block))
42
- builder.call(mixin)
43
- mixin
44
- end
45
-
46
- def mixin(fn = nil, &block)
47
- define(fn, &block)
48
- end
49
- end
21
+ extend Dry::Initializer::DSL
50
22
 
51
23
  def param(*args)
52
24
  __initializer_builder__.param(*args).call(__initializer_mixin__)
@@ -66,8 +38,8 @@ module Dry
66
38
  end
67
39
  end
68
40
 
69
- def __initializer_builder__
70
- @__initializer_builder__ ||= Dry::Initializer::Builder.new
41
+ def __initializer_builder__(**settings)
42
+ @__initializer_builder__ ||= Dry::Initializer::Builder.new(settings)
71
43
  end
72
44
 
73
45
  def inherited(klass)
@@ -40,12 +40,13 @@ module Dry::Initializer
40
40
  attr_reader :source, :target, :coercer, :default, :optional, :reader
41
41
 
42
42
  def initialize(options)
43
- @source = options[:source]
44
- @target = options[:target]
45
- @coercer = options[:type]
46
- @default = options[:default]
47
- @optional = !!(options[:optional] || @default)
48
- @reader = options.fetch(:reader, :public)
43
+ @source = options[:source]
44
+ @target = options[:target]
45
+ @coercer = options[:type]
46
+ @default = options[:default]
47
+ @optional = !!(options[:optional] || @default)
48
+ @reader = options.fetch(:reader, :public)
49
+ @undefined = options.fetch(:undefined, true)
49
50
  validate
50
51
  end
51
52
 
@@ -58,12 +59,12 @@ module Dry::Initializer
58
59
  return unless reader
59
60
  command = %w(private protected).include?(reader.to_s) ? reader : :public
60
61
 
61
- <<-RUBY.gsub(/^ *\|/, "")
62
- |undef_method :#{target} if method_defined?(:#{target}) || protected_method_defined?(:#{target}) || private_method_defined?(:#{target})
63
- |def #{target}
64
- | @#{target} unless @#{target} == Dry::Initializer::UNDEFINED
65
- |end
66
- |#{command} :#{target}
62
+ <<-RUBY
63
+ undef_method :#{target} if method_defined?(:#{target}) ||
64
+ protected_method_defined?(:#{target}) ||
65
+ private_method_defined?(:#{target})
66
+ #{reader_definition}
67
+ #{command} :#{target}
67
68
  RUBY
68
69
  end
69
70
 
@@ -75,6 +76,18 @@ module Dry::Initializer
75
76
  validate_coercer
76
77
  end
77
78
 
79
+ def undefined
80
+ @undefined ? "Dry::Initializer::UNDEFINED" : "nil"
81
+ end
82
+
83
+ def reader_definition
84
+ if @undefined
85
+ "def #{target}; @#{target} unless @#{target} == #{undefined}; end"
86
+ else
87
+ "attr_reader :#{target}"
88
+ end
89
+ end
90
+
78
91
  def validate_target
79
92
  return if target =~ /\A\w+\Z/
80
93
  fail ArgumentError.new("Invalid name '#{target}' for the target variable")
@@ -96,7 +109,10 @@ module Dry::Initializer
96
109
 
97
110
  def coercer_hash(type)
98
111
  return {} unless coercer
99
- value = proc { |v| v == Dry::Initializer::UNDEFINED ? v : coercer.(v) }
112
+
113
+ value = coercer unless @undefined
114
+ value ||= proc { |v| v == Dry::Initializer::UNDEFINED ? v : coercer.(v) }
115
+
100
116
  { :"#{type}_#{source}" => value }
101
117
  end
102
118
  end
@@ -1,12 +1,12 @@
1
1
  module Dry::Initializer
2
2
  class Builder
3
- def param(*args)
4
- @params = insert(@params, Attribute.param(*args))
3
+ def param(*args, **opts)
4
+ @params = insert @params, Attribute.param(*args, **@config.merge(opts))
5
5
  validate_collections
6
6
  end
7
7
 
8
- def option(*args)
9
- @options = insert(@options, Attribute.option(*args))
8
+ def option(*args, **opts)
9
+ @options = insert @options, Attribute.option(*args, **@config.merge(opts))
10
10
  validate_collections
11
11
  end
12
12
 
@@ -20,12 +20,13 @@ module Dry::Initializer
20
20
 
21
21
  mixin.send(:define_method, :__defaults__) { defaults }
22
22
  mixin.send(:define_method, :__coercers__) { coercers }
23
- mixin.class_eval(code, __FILE__, __LINE__ + 1)
23
+ mixin.class_eval(code)
24
24
  end
25
25
 
26
26
  private
27
27
 
28
- def initialize
28
+ def initialize(**config)
29
+ @config = config
29
30
  @params = []
30
31
  @options = []
31
32
  end
@@ -40,18 +41,18 @@ module Dry::Initializer
40
41
  end
41
42
 
42
43
  def code
43
- <<-RUBY.gsub(/^ +\|/, "")
44
- |def __initialize__(#{initializer_signatures})
45
- | @__options__ = {}
46
- |#{initializer_presetters}
47
- |#{initializer_setters}
48
- |#{initializer_postsetters}
49
- |end
50
- |private :__initialize__
51
- |private :__defaults__
52
- |private :__coercers__
53
- |
54
- |#{getters}
44
+ <<-RUBY
45
+ def __initialize__(#{initializer_signatures})
46
+ @__options__ = {}
47
+ #{initializer_presetters}
48
+ #{initializer_setters}
49
+ #{initializer_postsetters}
50
+ end
51
+ private :__initialize__
52
+ private :__defaults__
53
+ private :__coercers__
54
+
55
+ #{getters}
55
56
  RUBY
56
57
  end
57
58
 
@@ -0,0 +1,44 @@
1
+ module Dry::Initializer
2
+ module DSL
3
+ attr_reader :config
4
+
5
+ def [](**settings)
6
+ Module.new do
7
+ extend Dry::Initializer::DSL
8
+ include Dry::Initializer
9
+ @config = settings
10
+ end
11
+ end
12
+
13
+ def define(fn = nil, &block)
14
+ mixin = Module.new do
15
+ def initialize(*args)
16
+ __initialize__(*args)
17
+ end
18
+ end
19
+
20
+ builder = Builder.new Hash(config)
21
+ builder.instance_exec(&(fn || block))
22
+ builder.call(mixin)
23
+ mixin
24
+ end
25
+
26
+ private
27
+
28
+ def extended(klass)
29
+ super
30
+ mixin = klass.send(:__initializer_mixin__)
31
+ builder = klass.send(:__initializer_builder__, Hash(config))
32
+
33
+ builder.call(mixin)
34
+ klass.include(mixin)
35
+ klass.send(:define_method, :initialize) do |*args|
36
+ __initialize__(*args)
37
+ end
38
+ end
39
+
40
+ def mixin(fn = nil, &block)
41
+ define(fn, &block)
42
+ end
43
+ end
44
+ end
@@ -7,7 +7,7 @@ module Dry::Initializer
7
7
 
8
8
  # parts of __initalizer__
9
9
  def presetter
10
- "@#{target} = Dry::Initializer::UNDEFINED" if dispensable?
10
+ "@#{target} = #{undefined}" if dispensable? && @undefined
11
11
  end
12
12
 
13
13
  def safe_setter
@@ -16,13 +16,14 @@ module Dry::Initializer
16
16
 
17
17
  def fast_setter
18
18
  return safe_setter unless dispensable?
19
- "@#{target} = __options__.key?(:'#{source}') ? #{safe_coerced} : " \
20
- "Dry::Initializer::UNDEFINED"
19
+ "@#{target} = __options__.key?(:'#{source}')" \
20
+ " ? #{safe_coerced}" \
21
+ " : #{undefined}"
21
22
  end
22
23
 
23
24
  def postsetter
24
25
  "@__options__[:#{target}] = @#{target}" \
25
- " unless @#{target} == Dry::Initializer::UNDEFINED"
26
+ " unless @#{target} == #{undefined}"
26
27
  end
27
28
 
28
29
  # part of __defaults__
@@ -2,7 +2,7 @@ module Dry::Initializer
2
2
  class Param < Attribute
3
3
  # part of __initializer__ definition
4
4
  def initializer_signature
5
- optional ? "#{target} = Dry::Initializer::UNDEFINED" : target
5
+ optional ? "#{target} = #{undefined}" : target
6
6
  end
7
7
 
8
8
  # parts of __initalizer__
@@ -46,7 +46,7 @@ module Dry::Initializer
46
46
 
47
47
  def default_part
48
48
  return unless default
49
- " == Dry::Initializer::UNDEFINED ?" \
49
+ " == #{undefined} ?" \
50
50
  " instance_exec(&__defaults__[:param_#{target}]) :" \
51
51
  " #{target}"
52
52
  end
@@ -0,0 +1,84 @@
1
+ describe "definition" do
2
+ shared_examples :initializer do |in_context|
3
+ subject { Test::Foo.new(1, bar: 2) }
4
+
5
+ it "sets variables when defined by #{in_context}" do
6
+ expect(subject.instance_variable_get(:@foo)).to eql 1
7
+ expect(subject.instance_variable_get(:@bar)).to eql 2
8
+ end
9
+ end
10
+
11
+ it_behaves_like :initializer, "extending Dry::Initializer" do
12
+ before do
13
+ class Test::Foo
14
+ extend Dry::Initializer
15
+ param :foo
16
+ option :bar
17
+ end
18
+ end
19
+ end
20
+
21
+ it_behaves_like :initializer, "extending Dry::Initializer::Mixin" do
22
+ before do
23
+ class Test::Foo
24
+ extend Dry::Initializer::Mixin
25
+ param :foo
26
+ option :bar
27
+ end
28
+ end
29
+ end
30
+
31
+ it_behaves_like :initializer, "extending Dry::Initializer[undefined: false]" do
32
+ before do
33
+ class Test::Foo
34
+ extend Dry::Initializer[undefined: false]
35
+ param :foo
36
+ option :bar
37
+ end
38
+ end
39
+ end
40
+
41
+ it_behaves_like :initializer, "including Dry::Initializer with block" do
42
+ before do
43
+ class Test::Foo
44
+ include Dry::Initializer.define {
45
+ param :foo
46
+ option :bar
47
+ }
48
+ end
49
+ end
50
+ end
51
+
52
+ it_behaves_like :initializer, "including Dry::Initializer with lambda" do
53
+ before do
54
+ class Test::Foo
55
+ include Dry::Initializer.define -> do
56
+ param :foo
57
+ option :bar
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ it_behaves_like :initializer, "including Dry::Initializer[undefined: false]" do
64
+ before do
65
+ class Test::Foo
66
+ include Dry::Initializer[undefined: false].define {
67
+ param :foo
68
+ option :bar
69
+ }
70
+ end
71
+ end
72
+ end
73
+
74
+ it_behaves_like :initializer, "including Dry::Initializer::Mixin" do
75
+ before do
76
+ class Test::Foo
77
+ include Dry::Initializer::Mixin.define {
78
+ param :foo
79
+ option :bar
80
+ }
81
+ end
82
+ end
83
+ end
84
+ end
@@ -29,6 +29,23 @@ describe "optional value" do
29
29
  end
30
30
  end
31
31
 
32
+ context "with undefined: false" do
33
+ before do
34
+ class Test::Foo
35
+ extend Dry::Initializer[undefined: false]
36
+
37
+ param :foo
38
+ param :bar, optional: true
39
+ end
40
+ end
41
+
42
+ it "sets undefined values to nil" do
43
+ subject = Test::Foo.new(1)
44
+
45
+ expect(subject.instance_variable_get(:@bar)).to be_nil
46
+ end
47
+ end
48
+
32
49
  context "when has a default value" do
33
50
  before do
34
51
  class Test::Foo
@@ -9,13 +9,21 @@ describe "value coercion via dry-types" do
9
9
  class Test::Foo
10
10
  extend Dry::Initializer::Mixin
11
11
 
12
- param :foo, type: Test::Types::Coercible::String
12
+ param :foo, type: Test::Types::Coercible::String
13
+ option :bar, proc(&:to_i), default: proc { "16" }
13
14
  end
14
15
  end
15
16
 
16
- subject { Test::Foo.new :foo }
17
+ it "coerces assigned values" do
18
+ subject = Test::Foo.new :foo, bar: "13"
17
19
 
18
- it "coerces values" do
19
20
  expect(subject.foo).to eql "foo"
21
+ expect(subject.bar).to eql 13
22
+ end
23
+
24
+ it "coerces defaults as well" do
25
+ subject = Test::Foo.new :foo
26
+
27
+ expect(subject.bar).to eql 16
20
28
  end
21
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-initializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Kochnev (marshall-lee)
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-03-05 00:00:00.000000000 Z
12
+ date: 2017-03-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -102,17 +102,16 @@ files:
102
102
  - lib/dry/initializer.rb
103
103
  - lib/dry/initializer/attribute.rb
104
104
  - lib/dry/initializer/builder.rb
105
+ - lib/dry/initializer/dsl.rb
105
106
  - lib/dry/initializer/exceptions/default_value_error.rb
106
107
  - lib/dry/initializer/exceptions/params_order_error.rb
107
108
  - lib/dry/initializer/exceptions/type_constraint_error.rb
108
109
  - lib/dry/initializer/option.rb
109
110
  - lib/dry/initializer/param.rb
110
- - spec/base_spec.rb
111
- - spec/container_spec.rb
112
111
  - spec/custom_initializer_spec.rb
113
- - spec/default_nil_spec.rb
114
112
  - spec/default_values_spec.rb
115
- - spec/enhancement_spec.rb
113
+ - spec/definition_spec.rb
114
+ - spec/gem_enhancement_spec.rb
116
115
  - spec/invalid_default_spec.rb
117
116
  - spec/missed_default_spec.rb
118
117
  - spec/optional_spec.rb
@@ -151,12 +150,10 @@ signing_key:
151
150
  specification_version: 4
152
151
  summary: DSL for declaring params and options of the initializer
153
152
  test_files:
154
- - spec/base_spec.rb
155
- - spec/container_spec.rb
156
153
  - spec/custom_initializer_spec.rb
157
- - spec/default_nil_spec.rb
158
154
  - spec/default_values_spec.rb
159
- - spec/enhancement_spec.rb
155
+ - spec/definition_spec.rb
156
+ - spec/gem_enhancement_spec.rb
160
157
  - spec/invalid_default_spec.rb
161
158
  - spec/missed_default_spec.rb
162
159
  - spec/optional_spec.rb
data/spec/base_spec.rb DELETED
@@ -1,21 +0,0 @@
1
- describe "base example" do
2
- before do
3
- class Test::Foo
4
- extend Dry::Initializer::Mixin
5
-
6
- param :foo
7
- param :bar
8
- option :baz
9
- option :qux
10
- end
11
- end
12
-
13
- it "instantiates attributes" do
14
- subject = Test::Foo.new(1, 2, baz: 3, qux: 4)
15
-
16
- expect(subject.foo).to eql 1
17
- expect(subject.bar).to eql 2
18
- expect(subject.baz).to eql 3
19
- expect(subject.qux).to eql 4
20
- end
21
- end
@@ -1,45 +0,0 @@
1
- describe "container" do
2
- context "with block syntax" do
3
- before do
4
- class Test::Foo
5
- include Dry::Initializer.define {
6
- param :foo
7
- param :bar
8
- option :baz
9
- option :qux
10
- }
11
- end
12
- end
13
-
14
- it "instantiates attributes" do
15
- subject = Test::Foo.new(1, 2, baz: 3, qux: 4)
16
-
17
- expect(subject.foo).to eql 1
18
- expect(subject.bar).to eql 2
19
- expect(subject.baz).to eql 3
20
- expect(subject.qux).to eql 4
21
- end
22
- end
23
-
24
- context "with lambda syntax" do
25
- before do
26
- class Test::Foo
27
- include Dry::Initializer.define -> do
28
- param :foo
29
- param :bar
30
- option :baz
31
- option :qux
32
- end
33
- end
34
- end
35
-
36
- it "instantiates attributes" do
37
- subject = Test::Foo.new(1, 2, baz: 3, qux: 4)
38
-
39
- expect(subject.foo).to eql 1
40
- expect(subject.bar).to eql 2
41
- expect(subject.baz).to eql 3
42
- expect(subject.qux).to eql 4
43
- end
44
- end
45
- end
@@ -1,17 +0,0 @@
1
- describe "default nil" do
2
- before do
3
- class Test::Foo
4
- extend Dry::Initializer::Mixin
5
-
6
- param :foo, default: proc { nil }
7
- param :bar, default: -> { nil }
8
- end
9
- end
10
-
11
- it "is assigned" do
12
- subject = Test::Foo.new(1)
13
-
14
- expect(subject.foo).to eql 1
15
- expect(subject.bar).to be_nil
16
- end
17
- end