attributor 5.0.2 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +30 -0
- data/.travis.yml +6 -4
- data/CHANGELOG.md +6 -1
- data/Gemfile +1 -1
- data/Guardfile +14 -8
- data/Rakefile +4 -5
- data/attributor.gemspec +34 -29
- data/lib/attributor.rb +23 -29
- data/lib/attributor/attribute.rb +108 -127
- data/lib/attributor/attribute_resolver.rb +12 -26
- data/lib/attributor/dsl_compiler.rb +17 -21
- data/lib/attributor/dumpable.rb +1 -2
- data/lib/attributor/example_mixin.rb +5 -8
- data/lib/attributor/exceptions.rb +5 -6
- data/lib/attributor/extensions/randexp.rb +3 -5
- data/lib/attributor/extras/field_selector.rb +4 -4
- data/lib/attributor/extras/field_selector/transformer.rb +6 -7
- data/lib/attributor/families/numeric.rb +0 -2
- data/lib/attributor/families/temporal.rb +1 -4
- data/lib/attributor/hash_dsl_compiler.rb +22 -25
- data/lib/attributor/type.rb +24 -32
- data/lib/attributor/types/bigdecimal.rb +7 -14
- data/lib/attributor/types/boolean.rb +5 -8
- data/lib/attributor/types/class.rb +9 -10
- data/lib/attributor/types/collection.rb +34 -44
- data/lib/attributor/types/container.rb +9 -15
- data/lib/attributor/types/csv.rb +7 -10
- data/lib/attributor/types/date.rb +20 -25
- data/lib/attributor/types/date_time.rb +7 -14
- data/lib/attributor/types/float.rb +4 -6
- data/lib/attributor/types/hash.rb +171 -196
- data/lib/attributor/types/ids.rb +2 -6
- data/lib/attributor/types/integer.rb +12 -17
- data/lib/attributor/types/model.rb +39 -48
- data/lib/attributor/types/object.rb +2 -4
- data/lib/attributor/types/polymorphic.rb +118 -0
- data/lib/attributor/types/regexp.rb +4 -5
- data/lib/attributor/types/string.rb +6 -7
- data/lib/attributor/types/struct.rb +8 -15
- data/lib/attributor/types/symbol.rb +3 -6
- data/lib/attributor/types/tempfile.rb +5 -6
- data/lib/attributor/types/time.rb +11 -11
- data/lib/attributor/types/uri.rb +9 -10
- data/lib/attributor/version.rb +1 -1
- data/spec/attribute_resolver_spec.rb +57 -78
- data/spec/attribute_spec.rb +174 -216
- data/spec/attributor_spec.rb +11 -15
- data/spec/dsl_compiler_spec.rb +19 -33
- data/spec/dumpable_spec.rb +6 -7
- data/spec/extras/field_selector/field_selector_spec.rb +1 -1
- data/spec/families_spec.rb +1 -3
- data/spec/hash_dsl_compiler_spec.rb +65 -74
- data/spec/spec_helper.rb +9 -3
- data/spec/support/hashes.rb +2 -3
- data/spec/support/models.rb +30 -36
- data/spec/support/polymorphics.rb +10 -0
- data/spec/type_spec.rb +38 -61
- data/spec/types/bigdecimal_spec.rb +11 -15
- data/spec/types/boolean_spec.rb +12 -39
- data/spec/types/class_spec.rb +10 -11
- data/spec/types/collection_spec.rb +72 -81
- data/spec/types/container_spec.rb +22 -26
- data/spec/types/csv_spec.rb +15 -16
- data/spec/types/date_spec.rb +16 -33
- data/spec/types/date_time_spec.rb +16 -33
- data/spec/types/file_upload_spec.rb +1 -2
- data/spec/types/float_spec.rb +7 -14
- data/spec/types/hash_spec.rb +285 -289
- data/spec/types/ids_spec.rb +5 -7
- data/spec/types/integer_spec.rb +37 -46
- data/spec/types/model_spec.rb +111 -128
- data/spec/types/polymorphic_spec.rb +134 -0
- data/spec/types/regexp_spec.rb +4 -7
- data/spec/types/string_spec.rb +17 -21
- data/spec/types/struct_spec.rb +40 -47
- data/spec/types/tempfile_spec.rb +1 -2
- data/spec/types/temporal_spec.rb +9 -0
- data/spec/types/time_spec.rb +16 -32
- data/spec/types/type_spec.rb +15 -0
- data/spec/types/uri_spec.rb +6 -7
- metadata +77 -25
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
2
|
+
|
3
|
+
describe Attributor::Polymorphic do
|
4
|
+
subject(:type) do
|
5
|
+
Attributor::Polymorphic.on(:type)
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
type.given :chicken, Chicken
|
10
|
+
type.given :duck, Duck
|
11
|
+
type.given :turkey, Turkey
|
12
|
+
end
|
13
|
+
|
14
|
+
its(:discriminator) { should be :type }
|
15
|
+
its(:types) { should eq(chicken: Chicken, duck: Duck, turkey: Turkey) }
|
16
|
+
its(:native_type) { should be type }
|
17
|
+
|
18
|
+
context '.load' do
|
19
|
+
let(:chicken) { Chicken.example }
|
20
|
+
let(:duck) { Duck.example }
|
21
|
+
let(:turkey) { Turkey.example }
|
22
|
+
|
23
|
+
it 'loads' do
|
24
|
+
expect(type.load(chicken.dump)).to be_kind_of(Chicken)
|
25
|
+
expect(type.load(duck.dump)).to be_kind_of(Duck)
|
26
|
+
expect(type.load(turkey.dump)).to be_kind_of(Turkey)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'loads a hash with string keys' do
|
30
|
+
data = { 'type' => :chicken }
|
31
|
+
expect(type.load(data)).to be_kind_of(Chicken)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'raises a LoadError if the discriminator value is unknown' do
|
35
|
+
data = { type: :turducken }
|
36
|
+
expect { type.load(data) }.to raise_error(Attributor::LoadError)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises a LoadError if the discriminator value is missing' do
|
40
|
+
data = { id: 1 }
|
41
|
+
expect { type.load(data) }.to raise_error(Attributor::LoadError)
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'for a type with a string discriminator' do
|
45
|
+
subject(:string_type) do
|
46
|
+
Attributor::Polymorphic.on('type')
|
47
|
+
end
|
48
|
+
it 'loads a hash with symbol keys' do
|
49
|
+
data = { 'type' => :chicken }
|
50
|
+
expect(type.load(data)).to be_kind_of(Chicken)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context '.dump' do
|
56
|
+
context 'when used in a model' do
|
57
|
+
let(:example) { Sandwich.example }
|
58
|
+
subject(:dumped) { example.dump }
|
59
|
+
|
60
|
+
it 'properly dumps the attribute' do
|
61
|
+
expect(dumped[:meat]).to eq example.meat.dump
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context '.valid_type?' do
|
67
|
+
it 'is true for instances of possible types' do
|
68
|
+
[Chicken, Duck, Turkey].each do |bird_type|
|
69
|
+
example = bird_type.example
|
70
|
+
expect(type.valid_type?(example)).to be_truthy
|
71
|
+
end
|
72
|
+
end
|
73
|
+
it 'is false for other model types' do
|
74
|
+
[Address, Person].each do |other_type|
|
75
|
+
example = other_type.example
|
76
|
+
expect(type.valid_type?(example)).to be_falsey
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context '.example' do
|
82
|
+
subject(:example) { type.example }
|
83
|
+
it do
|
84
|
+
expect([Chicken, Duck, Turkey]).to include(type.example.class)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context '.describe' do
|
89
|
+
let(:example) { nil }
|
90
|
+
subject(:description) { type.describe(example: example) }
|
91
|
+
|
92
|
+
its([:discriminator]) { should eq :type }
|
93
|
+
context 'types' do
|
94
|
+
subject(:types) { description[:types] }
|
95
|
+
its(:keys) { should eq type.types.keys }
|
96
|
+
it do
|
97
|
+
expect(types[:chicken]).to eq(type: Chicken.describe(true))
|
98
|
+
expect(types[:turkey]).to eq(type: Turkey.describe(true))
|
99
|
+
expect(types[:duck]).to eq(type: Duck.describe(true))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'in a Model' do
|
104
|
+
subject(:description) { Sandwich.describe[:attributes][:meat][:type] }
|
105
|
+
its([:discriminator]) { should eq :type }
|
106
|
+
context 'types' do
|
107
|
+
subject(:types) { description[:types] }
|
108
|
+
its(:keys) { should match_array [:chicken, :turkey, :duck] }
|
109
|
+
it do
|
110
|
+
expect(types[:chicken]).to eq(type: Chicken.describe(true))
|
111
|
+
expect(types[:turkey]).to eq(type: Turkey.describe(true))
|
112
|
+
expect(types[:duck]).to eq(type: Duck.describe(true))
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'as an attribute in a model' do
|
119
|
+
let(:model) { Sandwich }
|
120
|
+
subject(:example) { model.example }
|
121
|
+
it 'generates an example properly' do
|
122
|
+
expect([Chicken, Duck, Turkey]).to include(example.meat.class)
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'loading' do
|
126
|
+
[Chicken, Duck, Turkey].each do |meat_class|
|
127
|
+
it "loads #{meat_class}" do
|
128
|
+
data = { meat: meat_class.example.dump }
|
129
|
+
expect(Sandwich.load(data).meat).to be_kind_of(meat_class)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/spec/types/regexp_spec.rb
CHANGED
@@ -1,32 +1,29 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
2
2
|
|
3
3
|
describe Attributor::Regexp do
|
4
|
-
|
5
4
|
subject(:type) { Attributor::Regexp }
|
6
5
|
|
7
6
|
it 'it is not Dumpable' do
|
8
|
-
type.new.is_a?(Attributor::Dumpable).
|
7
|
+
expect(type.new.is_a?(Attributor::Dumpable)).not_to be(true)
|
9
8
|
end
|
10
9
|
|
11
10
|
its(:native_type) { should be(::Regexp) }
|
12
11
|
its(:example) { should be_a(::String) }
|
13
|
-
its(:family) { should
|
12
|
+
its(:family) { should eq 'string' }
|
14
13
|
|
15
14
|
context '.load' do
|
16
15
|
let(:value) { nil }
|
17
16
|
|
18
17
|
it 'returns nil for nil' do
|
19
|
-
type.load(nil).
|
18
|
+
expect(type.load(nil)).to be(nil)
|
20
19
|
end
|
21
20
|
|
22
21
|
context 'for incoming String values' do
|
23
|
-
|
24
22
|
{ 'foo' => /foo/, '^pattern$' => /^pattern$/ }.each do |value, expected|
|
25
23
|
it "loads '#{value}' as #{expected.inspect}" do
|
26
|
-
type.load(value).
|
24
|
+
expect(type.load(value)).to eq(expected)
|
27
25
|
end
|
28
26
|
end
|
29
|
-
|
30
27
|
end
|
31
28
|
end
|
32
29
|
end
|
data/spec/types/string_spec.rb
CHANGED
@@ -1,61 +1,57 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
2
2
|
|
3
3
|
describe Attributor::String do
|
4
|
-
|
5
4
|
subject(:type) { Attributor::String }
|
6
5
|
|
7
6
|
it 'it is not Dumpable' do
|
8
|
-
type.new.is_a?(Attributor::Dumpable).
|
7
|
+
expect(type.new.is_a?(Attributor::Dumpable)).not_to be(true)
|
9
8
|
end
|
10
9
|
|
11
10
|
context '.native_type' do
|
12
|
-
it
|
13
|
-
type.native_type.
|
11
|
+
it 'returns String' do
|
12
|
+
expect(type.native_type).to be(::String)
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
16
|
context '.example' do
|
18
|
-
it
|
19
|
-
type.example(options:{regexp: /\w\d{2,3}/}).
|
17
|
+
it 'should return a valid String' do
|
18
|
+
expect(type.example(options: { regexp: /\w\d{2,3}/ })).to be_a(::String)
|
20
19
|
end
|
21
20
|
|
22
|
-
it
|
23
|
-
type.example.
|
21
|
+
it 'should return a valid String' do
|
22
|
+
expect(type.example).to be_a(::String)
|
24
23
|
end
|
25
24
|
|
26
25
|
it 'handles regexps that Randexp can not (#72)' do
|
27
26
|
regex = /\w+(,\w+)*/
|
28
|
-
expect
|
29
|
-
val = Attributor::String.example(options:{regexp: regex})
|
30
|
-
val.
|
31
|
-
val.
|
32
|
-
|
27
|
+
expect do
|
28
|
+
val = Attributor::String.example(options: { regexp: regex })
|
29
|
+
expect(val).to be_a(::String)
|
30
|
+
expect(val).to match(/Failed to generate.+is too vague/)
|
31
|
+
end.to_not raise_error
|
33
32
|
end
|
34
|
-
|
35
33
|
end
|
36
34
|
|
37
35
|
context '.load' do
|
38
36
|
let(:value) { nil }
|
39
37
|
|
40
38
|
it 'returns nil for nil' do
|
41
|
-
type.load(nil).
|
39
|
+
expect(type.load(nil)).to be(nil)
|
42
40
|
end
|
43
41
|
|
44
42
|
context 'for incoming String values' do
|
45
|
-
|
46
43
|
it 'returns the incoming value' do
|
47
44
|
['', 'foo', '0.0', '-1.0', '1.0', '1e-10', 1].each do |value|
|
48
|
-
type.load(value).
|
45
|
+
expect(type.load(value)).to eq(String(value))
|
49
46
|
end
|
50
47
|
end
|
51
48
|
end
|
52
|
-
|
53
49
|
end
|
54
50
|
|
55
51
|
context 'for incoming Symbol values' do
|
56
52
|
let(:value) { :something }
|
57
53
|
it 'returns the stringified-value' do
|
58
|
-
type.load(value).
|
54
|
+
expect(type.load(value)).to eq value.to_s
|
59
55
|
end
|
60
56
|
end
|
61
57
|
|
@@ -63,9 +59,9 @@ describe Attributor::String do
|
|
63
59
|
let(:value) { [1] }
|
64
60
|
|
65
61
|
it 'raises IncompatibleTypeError' do
|
66
|
-
expect
|
62
|
+
expect do
|
67
63
|
type.load(value)
|
68
|
-
|
64
|
+
end.to raise_error(Attributor::IncompatibleTypeError)
|
69
65
|
end
|
70
66
|
end
|
71
67
|
end
|
data/spec/types/struct_spec.rb
CHANGED
@@ -1,36 +1,33 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
2
2
|
|
3
3
|
describe Attributor::Struct do
|
4
|
-
|
5
4
|
context '.definition for a Struct with no sub-attributes' do
|
6
5
|
subject { Attributor::Struct }
|
7
6
|
it 'raises an error' do
|
8
|
-
expect
|
7
|
+
expect do
|
9
8
|
subject.definition
|
10
|
-
|
9
|
+
end.to raise_error(Attributor::AttributorException, 'Can not use a pure Struct without defining sub-attributes')
|
11
10
|
end
|
12
|
-
|
13
11
|
end
|
14
12
|
context '.construct' do
|
15
|
-
|
16
13
|
context 'empty struct' do
|
17
14
|
let(:attribute_definition) do
|
18
|
-
|
15
|
+
proc {}
|
19
16
|
end
|
20
17
|
|
21
18
|
subject(:empty_struct) { Attributor::Struct.construct(attribute_definition) }
|
22
19
|
|
23
20
|
it 'constructs a struct with no attributes' do
|
24
|
-
empty_struct.
|
21
|
+
expect(empty_struct).to be_subclass_of Attributor::Struct
|
25
22
|
|
26
23
|
attributes = empty_struct.attributes
|
27
|
-
attributes.
|
24
|
+
expect(attributes).to be_empty
|
28
25
|
end
|
29
26
|
end
|
30
27
|
|
31
28
|
context 'simple struct' do
|
32
29
|
let(:attribute_definition) do
|
33
|
-
|
30
|
+
proc do
|
34
31
|
attribute :age, Attributor::Integer
|
35
32
|
end
|
36
33
|
end
|
@@ -38,16 +35,16 @@ describe Attributor::Struct do
|
|
38
35
|
subject(:simple_struct) { Attributor::Struct.construct(attribute_definition) }
|
39
36
|
|
40
37
|
it 'constructs a struct with one attribute' do
|
41
|
-
simple_struct.
|
38
|
+
expect(simple_struct).to be_subclass_of Attributor::Struct
|
42
39
|
|
43
40
|
attributes = simple_struct.attributes
|
44
|
-
attributes.
|
41
|
+
expect(attributes).to have_key :age
|
45
42
|
end
|
46
43
|
end
|
47
44
|
|
48
45
|
context 'less simple struct' do
|
49
46
|
let(:attribute_definition) do
|
50
|
-
|
47
|
+
proc do
|
51
48
|
attribute :age, Attributor::Integer
|
52
49
|
attribute :name, Attributor::String
|
53
50
|
attribute :employed?, Attributor::Boolean
|
@@ -59,20 +56,20 @@ describe Attributor::Struct do
|
|
59
56
|
subject(:large_struct) { Attributor::Struct.construct(attribute_definition) }
|
60
57
|
|
61
58
|
it 'constructs a struct with five attributes' do
|
62
|
-
large_struct.
|
59
|
+
expect(large_struct).to be_subclass_of Attributor::Struct
|
63
60
|
|
64
61
|
attributes = large_struct.attributes
|
65
|
-
attributes.
|
66
|
-
attributes.
|
67
|
-
attributes.
|
68
|
-
attributes.
|
69
|
-
attributes.
|
62
|
+
expect(attributes).to have_key :age
|
63
|
+
expect(attributes).to have_key :name
|
64
|
+
expect(attributes).to have_key :employed?
|
65
|
+
expect(attributes).to have_key :salary
|
66
|
+
expect(attributes).to have_key :hired_at
|
70
67
|
end
|
71
68
|
end
|
72
69
|
|
73
70
|
context 'complex struct containing model' do
|
74
71
|
let(:attribute_definition) do
|
75
|
-
|
72
|
+
proc do
|
76
73
|
attribute :pet, ::Chicken
|
77
74
|
end
|
78
75
|
end
|
@@ -80,16 +77,16 @@ describe Attributor::Struct do
|
|
80
77
|
subject(:struct_of_models) { Attributor::Struct.construct(attribute_definition) }
|
81
78
|
|
82
79
|
it 'constructs a struct with a model attribute' do
|
83
|
-
struct_of_models.
|
80
|
+
expect(struct_of_models).to be_subclass_of Attributor::Struct
|
84
81
|
|
85
82
|
attributes = struct_of_models.attributes
|
86
|
-
attributes.
|
83
|
+
expect(attributes).to have_key :pet
|
87
84
|
end
|
88
85
|
end
|
89
86
|
|
90
87
|
context 'complex struct containing named struct' do
|
91
88
|
let(:attribute_definition) do
|
92
|
-
|
89
|
+
proc do
|
93
90
|
attribute :stats, Attributor::Struct do
|
94
91
|
attribute :months, Attributor::Integer
|
95
92
|
attribute :days, Attributor::Integer
|
@@ -100,20 +97,20 @@ describe Attributor::Struct do
|
|
100
97
|
subject(:struct_of_structs) { Attributor::Struct.construct(attribute_definition) }
|
101
98
|
|
102
99
|
it 'constructs a struct with a named struct attribute' do
|
103
|
-
struct_of_structs.
|
100
|
+
expect(struct_of_structs).to be_subclass_of Attributor::Struct
|
104
101
|
|
105
102
|
attributes = struct_of_structs.attributes
|
106
|
-
attributes.
|
103
|
+
expect(attributes).to have_key :stats
|
107
104
|
|
108
105
|
stats = attributes[:stats].attributes
|
109
|
-
stats.
|
110
|
-
stats.
|
106
|
+
expect(stats).to have_key :months
|
107
|
+
expect(stats).to have_key :days
|
111
108
|
end
|
112
109
|
end
|
113
110
|
|
114
111
|
context 'complex struct containing multi-level recursive structs' do
|
115
112
|
let(:attribute_definition) do
|
116
|
-
|
113
|
+
proc do
|
117
114
|
attribute :arthropods, Attributor::Struct do
|
118
115
|
attribute :insects, Attributor::Struct do
|
119
116
|
attribute :ants, Attributor::Struct do
|
@@ -129,21 +126,21 @@ describe Attributor::Struct do
|
|
129
126
|
subject(:multi_level_struct_of_structs) { Attributor::Struct.construct(attribute_definition) }
|
130
127
|
|
131
128
|
it 'constructs a struct with multiple levels of named struct attributes' do
|
132
|
-
multi_level_struct_of_structs.
|
129
|
+
expect(multi_level_struct_of_structs).to be_subclass_of Attributor::Struct
|
133
130
|
|
134
131
|
root = multi_level_struct_of_structs.attributes
|
135
|
-
root.
|
132
|
+
expect(root).to have_key :arthropods
|
136
133
|
|
137
134
|
arthropods = root[:arthropods].attributes
|
138
|
-
arthropods.
|
135
|
+
expect(arthropods).to have_key :insects
|
139
136
|
|
140
137
|
insects = arthropods[:insects].attributes
|
141
|
-
insects.
|
138
|
+
expect(insects).to have_key :ants
|
142
139
|
|
143
140
|
ants = insects[:ants].attributes
|
144
|
-
ants.
|
145
|
-
ants.
|
146
|
-
ants.
|
141
|
+
expect(ants).to have_key :name
|
142
|
+
expect(ants).to have_key :age
|
143
|
+
expect(ants).to have_key :weight
|
147
144
|
end
|
148
145
|
end
|
149
146
|
|
@@ -153,37 +150,33 @@ describe Attributor::Struct do
|
|
153
150
|
proc do
|
154
151
|
end
|
155
152
|
end
|
156
|
-
subject(:struct) { Attributor::Struct.construct(attribute_definition, options)}
|
153
|
+
subject(:struct) { Attributor::Struct.construct(attribute_definition, options) }
|
157
154
|
|
158
155
|
context 'with new type-level options' do
|
159
|
-
let(:options) { {reference: reference} }
|
156
|
+
let(:options) { { reference: reference } }
|
160
157
|
its(:options) { should have_key(:identity) }
|
161
158
|
it 'inherits from the reference' do
|
162
|
-
struct.options[:identity].
|
159
|
+
expect(struct.options[:identity]).to eq(reference.options[:identity])
|
163
160
|
end
|
164
161
|
it 'does not raise an error when used in an attribute' do
|
165
|
-
expect
|
162
|
+
expect do
|
166
163
|
Attributor::Attribute.new(struct)
|
167
|
-
|
164
|
+
end.to_not raise_error
|
168
165
|
end
|
169
166
|
end
|
170
167
|
|
171
168
|
context 'with existing type-level options' do
|
172
|
-
let(:options) { {reference: reference, identity: :name} }
|
169
|
+
let(:options) { { reference: reference, identity: :name } }
|
173
170
|
its(:options) { should have_key(:identity) }
|
174
171
|
it 'does not override from the reference' do
|
175
|
-
struct.options[:identity].
|
172
|
+
expect(struct.options[:identity]).to eq(:name)
|
176
173
|
end
|
177
174
|
it 'does not raise an error when used in an attribute' do
|
178
|
-
expect
|
175
|
+
expect do
|
179
176
|
Attributor::Attribute.new(struct)
|
180
|
-
|
177
|
+
end.to_not raise_error
|
181
178
|
end
|
182
|
-
|
183
179
|
end
|
184
180
|
end
|
185
|
-
|
186
|
-
|
187
181
|
end
|
188
|
-
|
189
182
|
end
|