attributor 5.2.0 → 5.6
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 +4 -3
- data/CHANGELOG.md +146 -140
- data/attributor.gemspec +4 -5
- data/lib/attributor.rb +16 -2
- data/lib/attributor/attribute.rb +42 -9
- data/lib/attributor/extras/field_selector.rb +4 -0
- data/lib/attributor/families/numeric.rb +19 -6
- data/lib/attributor/families/temporal.rb +16 -9
- data/lib/attributor/hash_dsl_compiler.rb +6 -6
- data/lib/attributor/type.rb +27 -4
- data/lib/attributor/types/bigdecimal.rb +7 -2
- data/lib/attributor/types/boolean.rb +7 -2
- data/lib/attributor/types/class.rb +2 -2
- data/lib/attributor/types/collection.rb +24 -5
- data/lib/attributor/types/container.rb +3 -3
- data/lib/attributor/types/csv.rb +5 -1
- data/lib/attributor/types/date.rb +9 -3
- data/lib/attributor/types/date_time.rb +8 -2
- data/lib/attributor/types/float.rb +4 -3
- data/lib/attributor/types/hash.rb +82 -18
- data/lib/attributor/types/integer.rb +7 -1
- data/lib/attributor/types/model.rb +2 -2
- data/lib/attributor/types/object.rb +5 -0
- data/lib/attributor/types/polymorphic.rb +3 -2
- data/lib/attributor/types/string.rb +20 -1
- data/lib/attributor/types/struct.rb +1 -1
- data/lib/attributor/types/symbol.rb +5 -0
- data/lib/attributor/types/tempfile.rb +4 -0
- data/lib/attributor/types/time.rb +7 -3
- data/lib/attributor/types/uri.rb +9 -1
- data/lib/attributor/version.rb +1 -1
- data/spec/attribute_spec.rb +42 -7
- data/spec/dsl_compiler_spec.rb +7 -7
- data/spec/extras/field_selector/field_selector_spec.rb +9 -0
- data/spec/hash_dsl_compiler_spec.rb +2 -2
- data/spec/support/integers.rb +7 -0
- data/spec/type_spec.rb +1 -1
- data/spec/types/bigdecimal_spec.rb +8 -0
- data/spec/types/boolean_spec.rb +10 -0
- data/spec/types/class_spec.rb +0 -1
- data/spec/types/collection_spec.rb +16 -0
- data/spec/types/date_spec.rb +9 -0
- data/spec/types/date_time_spec.rb +9 -0
- data/spec/types/float_spec.rb +8 -0
- data/spec/types/hash_spec.rb +127 -9
- data/spec/types/integer_spec.rb +10 -1
- data/spec/types/model_spec.rb +14 -3
- data/spec/types/string_spec.rb +10 -0
- data/spec/types/temporal_spec.rb +5 -1
- data/spec/types/time_spec.rb +9 -0
- data/spec/types/uri_spec.rb +9 -0
- metadata +21 -34
data/spec/dsl_compiler_spec.rb
CHANGED
@@ -4,7 +4,7 @@ describe Attributor::DSLCompiler do
|
|
4
4
|
let(:target) { double('model', attributes: {}) }
|
5
5
|
|
6
6
|
let(:dsl_compiler_options) { {} }
|
7
|
-
subject(:dsl_compiler) { Attributor::DSLCompiler.new(target, dsl_compiler_options) }
|
7
|
+
subject(:dsl_compiler) { Attributor::DSLCompiler.new(target, **dsl_compiler_options) }
|
8
8
|
|
9
9
|
let(:attribute_name) { :name }
|
10
10
|
let(:type) { Attributor::String }
|
@@ -35,7 +35,7 @@ describe Attributor::DSLCompiler do
|
|
35
35
|
|
36
36
|
it 'creates an attribute given a name, type, and options' do
|
37
37
|
expect(Attributor::Attribute).to receive(:new).with(expected_type, expected_options)
|
38
|
-
dsl_compiler.attribute(attribute_name, type, attribute_options)
|
38
|
+
dsl_compiler.attribute(attribute_name, type, **attribute_options)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -60,11 +60,11 @@ describe Attributor::DSLCompiler do
|
|
60
60
|
end
|
61
61
|
|
62
62
|
it 'creates an attribute with the inherited type and merged options' do
|
63
|
-
dsl_compiler.attribute(attribute_name, attribute_options)
|
63
|
+
dsl_compiler.attribute(attribute_name, **attribute_options)
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'accepts explicit nil type' do
|
67
|
-
dsl_compiler.attribute(attribute_name, nil, attribute_options)
|
67
|
+
dsl_compiler.attribute(attribute_name, nil, **attribute_options)
|
68
68
|
end
|
69
69
|
|
70
70
|
context 'but with the attribute also specifying a reference' do
|
@@ -73,7 +73,7 @@ describe Attributor::DSLCompiler do
|
|
73
73
|
let(:expected_options) { attribute_options }
|
74
74
|
it 'attribute reference takes precedence over the compiler one (and merges no options)' do
|
75
75
|
expect(attribute_options[:reference]).to_not eq(dsl_compiler_options[:reference])
|
76
|
-
dsl_compiler.attribute(attribute_name, attribute_options)
|
76
|
+
dsl_compiler.attribute(attribute_name, **attribute_options)
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -113,12 +113,12 @@ describe Attributor::DSLCompiler do
|
|
113
113
|
it 'sets the type of the attribute to Struct' do
|
114
114
|
expect(Attributor::Attribute).to receive(:new)
|
115
115
|
.with(expected_type, description: 'The turkey', reference: Turkey)
|
116
|
-
dsl_compiler.attribute(attribute_name, attribute_options, &attribute_block)
|
116
|
+
dsl_compiler.attribute(attribute_name, **attribute_options, &attribute_block)
|
117
117
|
end
|
118
118
|
|
119
119
|
it 'passes the correct reference to the created attribute' do
|
120
120
|
expect(Attributor::Attribute).to receive(:new).with(expected_type, expected_options)
|
121
|
-
dsl_compiler.attribute(attribute_name, type, attribute_options, &attribute_block)
|
121
|
+
dsl_compiler.attribute(attribute_name, type, **attribute_options, &attribute_block)
|
122
122
|
end
|
123
123
|
end
|
124
124
|
end
|
@@ -33,4 +33,13 @@ describe Attributor::FieldSelector do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
context '.as_json_schema' do
|
38
|
+
subject(:js){ type.as_json_schema }
|
39
|
+
it 'adds the right attributes' do
|
40
|
+
expect(js.keys).to include(:type, :'x-type_name')
|
41
|
+
expect(js[:type]).to eq(:string)
|
42
|
+
expect(js[:'x-type_name']).to eq('FieldSelector')
|
43
|
+
end
|
44
|
+
end
|
36
45
|
end
|
@@ -4,7 +4,7 @@ describe Attributor::HashDSLCompiler do
|
|
4
4
|
let(:target) { double('model', attributes: {}) }
|
5
5
|
|
6
6
|
let(:dsl_compiler_options) { {} }
|
7
|
-
subject(:dsl_compiler) { Attributor::HashDSLCompiler.new(target, dsl_compiler_options) }
|
7
|
+
subject(:dsl_compiler) { Attributor::HashDSLCompiler.new(target, **dsl_compiler_options) }
|
8
8
|
|
9
9
|
it 'returns the requirements DSL attached to the right target' do
|
10
10
|
req_dsl = dsl_compiler._requirements_dsl
|
@@ -103,7 +103,7 @@ describe Attributor::HashDSLCompiler do
|
|
103
103
|
end
|
104
104
|
|
105
105
|
context 'Requirement#validate' do
|
106
|
-
let(:requirement) { req_class.new(arguments) }
|
106
|
+
let(:requirement) { req_class.new(**arguments) }
|
107
107
|
let(:subject) { requirement.validate(value, ['$'], nil) }
|
108
108
|
|
109
109
|
context 'for :all' do
|
data/spec/type_spec.rb
CHANGED
@@ -68,7 +68,7 @@ describe Attributor::Type do
|
|
68
68
|
let(:context) { %w(top sub) }
|
69
69
|
|
70
70
|
it 'raises an exception' do
|
71
|
-
expect { test_type.load(value, context) }.to raise_error(Attributor::IncompatibleTypeError, /cannot load values of type Fixnum.*while loading top.sub/)
|
71
|
+
expect { test_type.load(value, context) }.to raise_error(Attributor::IncompatibleTypeError, /cannot load values of type (Fixnum|Integer).*while loading top.sub/)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -45,4 +45,12 @@ describe Attributor::BigDecimal do
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
|
+
context '.as_json_schema' do
|
49
|
+
subject(:js){ type.as_json_schema }
|
50
|
+
it 'adds the right attributes' do
|
51
|
+
expect(js.keys).to include(:type, :'x-type_name')
|
52
|
+
expect(js[:type]).to eq(:number)
|
53
|
+
expect(js[:'x-type_name']).to eq('BigDecimal')
|
54
|
+
end
|
55
|
+
end
|
48
56
|
end
|
data/spec/types/boolean_spec.rb
CHANGED
@@ -7,6 +7,8 @@ describe Attributor::Boolean do
|
|
7
7
|
expect(type.new.is_a?(Attributor::Dumpable)).not_to be(true)
|
8
8
|
end
|
9
9
|
|
10
|
+
its(:json_schema_type){ should eq(:boolean)}
|
11
|
+
|
10
12
|
context '.valid_type?' do
|
11
13
|
context 'for incoming Boolean values' do
|
12
14
|
[false, true].each do |value|
|
@@ -63,4 +65,12 @@ describe Attributor::Boolean do
|
|
63
65
|
end
|
64
66
|
end
|
65
67
|
end
|
68
|
+
context '.as_json_schema' do
|
69
|
+
subject(:js){ type.as_json_schema }
|
70
|
+
it 'adds the right attributes' do
|
71
|
+
expect(js.keys).to include(:type, :'x-type_name')
|
72
|
+
expect(js[:type]).to eq(:boolean)
|
73
|
+
expect(js[:'x-type_name']).to eq('Boolean')
|
74
|
+
end
|
75
|
+
end
|
66
76
|
end
|
data/spec/types/class_spec.rb
CHANGED
@@ -344,4 +344,20 @@ describe Attributor::Collection do
|
|
344
344
|
end.to_not raise_error
|
345
345
|
end
|
346
346
|
end
|
347
|
+
|
348
|
+
context '.as_json_schema' do
|
349
|
+
let(:member_type) { Attributor::String }
|
350
|
+
let(:type) { Attributor::Collection.of(member_type) }
|
351
|
+
let(:attribute_options) do
|
352
|
+
{}
|
353
|
+
end
|
354
|
+
subject(:js){ type.as_json_schema(attribute_options: attribute_options) }
|
355
|
+
|
356
|
+
it 'adds the right attributes' do
|
357
|
+
expect(js.keys).to include(:type, :'x-type_name', :items)
|
358
|
+
expect(js[:type]).to eq(:array)
|
359
|
+
expect(js[:'x-type_name']).to eq('Collection')
|
360
|
+
expect(js[:items]).to eq(member_type.as_json_schema)
|
361
|
+
end
|
362
|
+
end
|
347
363
|
end
|
data/spec/types/date_spec.rb
CHANGED
@@ -92,4 +92,13 @@ describe Attributor::Date do
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
end
|
95
|
+
context '.as_json_schema' do
|
96
|
+
subject(:js){ type.as_json_schema }
|
97
|
+
it 'adds the right attributes' do
|
98
|
+
expect(js.keys).to include(:type, :'x-type_name')
|
99
|
+
expect(js[:type]).to eq(:string)
|
100
|
+
expect(js[:format]).to eq(:'date')
|
101
|
+
expect(js[:'x-type_name']).to eq('Date')
|
102
|
+
end
|
103
|
+
end
|
95
104
|
end
|
@@ -92,4 +92,13 @@ describe Attributor::DateTime do
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
end
|
95
|
+
context '.as_json_schema' do
|
96
|
+
subject(:js){ type.as_json_schema }
|
97
|
+
it 'adds the right attributes' do
|
98
|
+
expect(js.keys).to include(:type, :'x-type_name', :format)
|
99
|
+
expect(js[:type]).to eq(:string)
|
100
|
+
expect(js[:format]).to eq(:'date-time')
|
101
|
+
expect(js[:'x-type_name']).to eq('DateTime')
|
102
|
+
end
|
103
|
+
end
|
95
104
|
end
|
data/spec/types/float_spec.rb
CHANGED
@@ -76,4 +76,12 @@ describe Attributor::Float do
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
79
|
+
context '.as_json_schema' do
|
80
|
+
subject(:js){ type.as_json_schema }
|
81
|
+
it 'adds the right attributes' do
|
82
|
+
expect(js.keys).to include(:type, :'x-type_name')
|
83
|
+
expect(js[:type]).to eq(:number)
|
84
|
+
expect(js[:'x-type_name']).to eq('Float')
|
85
|
+
end
|
86
|
+
end
|
79
87
|
end
|
data/spec/types/hash_spec.rb
CHANGED
@@ -7,6 +7,7 @@ describe Attributor::Hash do
|
|
7
7
|
its(:key_type) { should be(Attributor::Object) }
|
8
8
|
its(:value_type) { should be(Attributor::Object) }
|
9
9
|
its(:dsl_class) { should be(Attributor::HashDSLCompiler) }
|
10
|
+
its(:json_schema_type) { should be(:object) }
|
10
11
|
|
11
12
|
context 'attributes' do
|
12
13
|
context 'with an exception from the definition block' do
|
@@ -359,7 +360,7 @@ describe Attributor::Hash do
|
|
359
360
|
context 'with unknown keys in input' do
|
360
361
|
it 'raises an error' do
|
361
362
|
expect do
|
362
|
-
type.load('other_key' => :value)
|
363
|
+
type.load({'other_key' => :value})
|
363
364
|
end.to raise_error(Attributor::AttributorException)
|
364
365
|
end
|
365
366
|
end
|
@@ -453,7 +454,7 @@ describe Attributor::Hash do
|
|
453
454
|
|
454
455
|
context 'for a simple (untyped) hash' do
|
455
456
|
it 'returns the untouched hash value' do
|
456
|
-
expect(type.dump(value, opts)).to eq(value)
|
457
|
+
expect(type.dump(value, **opts)).to eq(value)
|
457
458
|
end
|
458
459
|
end
|
459
460
|
|
@@ -475,7 +476,7 @@ describe Attributor::Hash do
|
|
475
476
|
let(:type) { Attributor::Hash.of(key: String, value: subtype) }
|
476
477
|
|
477
478
|
it 'returns a hash with the dumped values and keys' do
|
478
|
-
dumped_value = type.dump(value, opts)
|
479
|
+
dumped_value = type.dump(value, **opts)
|
479
480
|
expect(dumped_value).to be_kind_of(::Hash)
|
480
481
|
expect(dumped_value.keys).to match_array %w(id1 id2)
|
481
482
|
expect(dumped_value.values).to have(2).items
|
@@ -487,7 +488,7 @@ describe Attributor::Hash do
|
|
487
488
|
let(:value) { { id1: nil, id2: subtype.new(value2) } }
|
488
489
|
|
489
490
|
it 'correctly returns nil rather than trying to dump their contents' do
|
490
|
-
dumped_value = type.dump(value, opts)
|
491
|
+
dumped_value = type.dump(value, **opts)
|
491
492
|
expect(dumped_value).to be_kind_of(::Hash)
|
492
493
|
expect(dumped_value.keys).to match_array %w(id1 id2)
|
493
494
|
expect(dumped_value['id1']).to be nil
|
@@ -706,7 +707,7 @@ describe Attributor::Hash do
|
|
706
707
|
expect(ex.keys).to match([:req1, :req2, :exc3, :least1, :least2, :most1])
|
707
708
|
end
|
708
709
|
it 'it favors picking attributes with data' do
|
709
|
-
ex = type.example(nil,
|
710
|
+
ex = type.example(nil,most2: "data")
|
710
711
|
expect(ex.keys).to match([:req1, :req2, :exc3, :least1, :least2, :most2])
|
711
712
|
end
|
712
713
|
end
|
@@ -1150,10 +1151,10 @@ describe Attributor::Hash do
|
|
1150
1151
|
let(:hash_of_strings) { Attributor::Hash.of(key: String) }
|
1151
1152
|
let(:hash_of_symbols) { Attributor::Hash.of(key: Symbol) }
|
1152
1153
|
|
1153
|
-
let(:merger) { hash_of_strings.load('a' => 1) }
|
1154
|
-
let(:good_mergee) { hash_of_strings.load('b' => 2) }
|
1155
|
-
let(:bad_mergee) { hash_of_symbols.load(c: 3) }
|
1156
|
-
let(:result) { hash_of_strings.load('a' => 1, 'b' => 2) }
|
1154
|
+
let(:merger) { hash_of_strings.load({'a' => 1},nil) }
|
1155
|
+
let(:good_mergee) { hash_of_strings.load({'b' => 2},nil) }
|
1156
|
+
let(:bad_mergee) { hash_of_symbols.load({c: 3}) }
|
1157
|
+
let(:result) { hash_of_strings.load({'a' => 1, 'b' => 2},nil) }
|
1157
1158
|
|
1158
1159
|
it 'validates that the mergee is of like type' do
|
1159
1160
|
expect { merger.merge(bad_mergee) }.to raise_error(ArgumentError)
|
@@ -1172,4 +1173,121 @@ describe Attributor::Hash do
|
|
1172
1173
|
|
1173
1174
|
context Attributor::InvalidDefinition do
|
1174
1175
|
end
|
1176
|
+
|
1177
|
+
|
1178
|
+
context '.as_json_hash' do
|
1179
|
+
let(:example){ nil }
|
1180
|
+
subject(:description) { type.as_json_schema(example: example) }
|
1181
|
+
its([:type]){ should eq(:object)}
|
1182
|
+
its([:'x-type_name']){ should eq('Hash')}
|
1183
|
+
|
1184
|
+
context 'for hashes with explicit key and value types' do
|
1185
|
+
let(:key_type){ String }
|
1186
|
+
let(:value_type){ Integer }
|
1187
|
+
|
1188
|
+
subject(:type) { Attributor::Hash.of(key: key_type, value: value_type) }
|
1189
|
+
|
1190
|
+
it 'describes the key type correctly' do
|
1191
|
+
expect(description.keys).to include( :'x-key_type' )
|
1192
|
+
expect(description[:'x-key_type']).to be_kind_of(::Hash)
|
1193
|
+
expect(description[:'x-key_type'][:type]).to eq( :string )
|
1194
|
+
end
|
1195
|
+
|
1196
|
+
it 'describes the value type correctly' do
|
1197
|
+
expect(description.keys).to include( :'x-value_type' )
|
1198
|
+
expect(description[:'x-value_type']).to be_kind_of(::Hash)
|
1199
|
+
expect(description[:'x-value_type'][:type]).to eq( :integer )
|
1200
|
+
end
|
1201
|
+
|
1202
|
+
end
|
1203
|
+
|
1204
|
+
|
1205
|
+
context 'for hashes with specific keys defined' do
|
1206
|
+
let(:block) do
|
1207
|
+
proc do
|
1208
|
+
key 'a string', String
|
1209
|
+
key '1', Integer, min: 1, max: 20
|
1210
|
+
key 'some_date', DateTime
|
1211
|
+
key 'defaulted', String, default: 'default value'
|
1212
|
+
requires do
|
1213
|
+
all.of '1','some_date'
|
1214
|
+
exclusive 'some_date', 'defaulted'
|
1215
|
+
at_least(1).of 'a string', 'some_date'
|
1216
|
+
at_most(2).of 'a string', 'some_date'
|
1217
|
+
exactly(1).of 'a string', 'some_date'
|
1218
|
+
end
|
1219
|
+
end
|
1220
|
+
end
|
1221
|
+
|
1222
|
+
let(:type) { Attributor::Hash.of(key: String).construct(block) }
|
1223
|
+
|
1224
|
+
it 'describes the basic type options correctly' do
|
1225
|
+
expect(description[:type]).to eq(:object)
|
1226
|
+
expect(description[:'x-key_type']).to eq( type: :string , 'x-type_name': 'String')
|
1227
|
+
expect(description).to_not have_key(:'x-value_type')
|
1228
|
+
end
|
1229
|
+
|
1230
|
+
it 'describes the type attributes correctly' do
|
1231
|
+
props = description[:properties]
|
1232
|
+
|
1233
|
+
expect(props['a string']).to eq(type: :string, 'x-type_name': 'String')
|
1234
|
+
expect(props['1']).to eq(type: :integer, 'x-type_name': 'Integer', minimum: 1, maximum: 20)
|
1235
|
+
expect(props['some_date']).to eq(type: :string, 'x-type_name': 'DateTime', format: :'date-time')
|
1236
|
+
expect(props['defaulted']).to eq(type: :string, 'x-type_name': 'String', default: 'default value')
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
it 'describes the attribute requirements correctly' do
|
1240
|
+
reqs = description[:required]
|
1241
|
+
expect(reqs).to be_kind_of(Array)
|
1242
|
+
expect(reqs).to eq( ['1','some_date'] )
|
1243
|
+
end
|
1244
|
+
|
1245
|
+
it 'describes the extended requirements correctly' do
|
1246
|
+
reqs = description[:'x-requirements']
|
1247
|
+
expect(reqs).to be_kind_of(Array)
|
1248
|
+
expect(reqs.size).to be(5)
|
1249
|
+
expect(reqs).to include( type: :all, attributes: ['1','some_date'] )
|
1250
|
+
expect(reqs).to include( type: :exclusive, attributes: ['some_date','defaulted'] )
|
1251
|
+
expect(reqs).to include( type: :at_least, attributes: ['a string','some_date'], count: 1 )
|
1252
|
+
expect(reqs).to include( type: :at_most, attributes: ['a string','some_date'], count: 2 )
|
1253
|
+
expect(reqs).to include( type: :exactly, attributes: ['a string','some_date'], count: 1 )
|
1254
|
+
end
|
1255
|
+
|
1256
|
+
context 'merging requires.all with attribute required: true' do
|
1257
|
+
let(:block) do
|
1258
|
+
proc do
|
1259
|
+
key 'required string', String, required: true
|
1260
|
+
key '1', Integer
|
1261
|
+
key 'some_date', DateTime
|
1262
|
+
requires do
|
1263
|
+
all.of 'some_date'
|
1264
|
+
end
|
1265
|
+
end
|
1266
|
+
end
|
1267
|
+
it 'includes attributes with required: true into :required' do
|
1268
|
+
expect(description[:required].size).to eq(2)
|
1269
|
+
expect(description[:required]).to include( 'required string','some_date' )
|
1270
|
+
end
|
1271
|
+
|
1272
|
+
it 'includes attributes with required: true into the :all requirements' do
|
1273
|
+
req_all = description[:'x-requirements'].select{|r| r[:type] == :all}.first
|
1274
|
+
expect(req_all[:attributes]).to include( 'required string','some_date' )
|
1275
|
+
end
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
|
1279
|
+
context 'with an example' do
|
1280
|
+
let(:example){ type.example }
|
1281
|
+
|
1282
|
+
it 'should have the matching example for each leaf key' do
|
1283
|
+
expect(description[:properties].keys).to include(*type.keys.keys)
|
1284
|
+
description[:properties].each do |name,sub_description|
|
1285
|
+
expect(sub_description).to have_key(:example)
|
1286
|
+
val = type.attributes[name].dump(example[name])
|
1287
|
+
expect(sub_description[:example]).to eq val
|
1288
|
+
end
|
1289
|
+
end
|
1290
|
+
end
|
1291
|
+
end
|
1292
|
+
end
|
1175
1293
|
end
|
data/spec/types/integer_spec.rb
CHANGED
@@ -97,7 +97,7 @@ describe Attributor::Integer do
|
|
97
97
|
it "raises for the invalid range [#{min.inspect}, #{max.inspect}]" do
|
98
98
|
opts = { options: { max: max, min: min } }
|
99
99
|
expect do
|
100
|
-
type.example(nil, opts)
|
100
|
+
type.example(nil, **opts)
|
101
101
|
end.to raise_error(Attributor::AttributorException, "Invalid range: [#{min.inspect}, #{max.inspect}]")
|
102
102
|
end
|
103
103
|
end
|
@@ -146,4 +146,13 @@ describe Attributor::Integer do
|
|
146
146
|
end
|
147
147
|
end
|
148
148
|
end
|
149
|
+
|
150
|
+
context '.as_json_schema' do
|
151
|
+
subject(:js){ type.as_json_schema }
|
152
|
+
it 'adds the right stuff' do
|
153
|
+
expect(js.keys).to include(:type, :'x-type_name')
|
154
|
+
expect(js[:type]).to eq(:integer)
|
155
|
+
expect(js[:'x-type_name']).to eq('Integer')
|
156
|
+
end
|
157
|
+
end
|
149
158
|
end
|
data/spec/types/model_spec.rb
CHANGED
@@ -369,7 +369,7 @@ describe Attributor::Model do
|
|
369
369
|
end
|
370
370
|
|
371
371
|
context 'for models using the "requires" DSL' do
|
372
|
-
subject(:address) { Address.load(state: 'CA') }
|
372
|
+
subject(:address) { Address.load({state: 'CA'}) }
|
373
373
|
its(:validate) { should_not be_empty }
|
374
374
|
its(:validate) { should include 'Key name is required for $.' }
|
375
375
|
end
|
@@ -380,8 +380,8 @@ describe Attributor::Model do
|
|
380
380
|
end
|
381
381
|
|
382
382
|
context 'that are both invalid' do
|
383
|
-
subject(:person) { Person.load(name: 'Joe', title: 'dude', okay: true) }
|
384
|
-
let(:address) { Address.load(name: '1 Main St', state: 'ME') }
|
383
|
+
subject(:person) { Person.load({name: 'Joe', title: 'dude', okay: true}) }
|
384
|
+
let(:address) { Address.load({name: '1 Main St', state: 'ME'}) }
|
385
385
|
before do
|
386
386
|
person.address = address
|
387
387
|
address.person = person
|
@@ -413,6 +413,17 @@ describe Attributor::Model do
|
|
413
413
|
expect(person.address.person).to be(person)
|
414
414
|
expect(output[:address][:person]).to eq(Attributor::Model::CIRCULAR_REFERENCE_MARKER)
|
415
415
|
end
|
416
|
+
|
417
|
+
it 'passes kwargs' do
|
418
|
+
person.class.attributes.values.each do |attr|
|
419
|
+
expect(attr).to receive(:dump).with(
|
420
|
+
anything,
|
421
|
+
context: anything,
|
422
|
+
custom_arg: :custom_value
|
423
|
+
)
|
424
|
+
end
|
425
|
+
person.dump(custom_arg: :custom_value)
|
426
|
+
end
|
416
427
|
end
|
417
428
|
end
|
418
429
|
|