attributor 5.1.0 → 5.5
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/.travis.yml +4 -3
- data/CHANGELOG.md +145 -135
- data/attributor.gemspec +5 -6
- data/lib/attributor.rb +17 -2
- data/lib/attributor/attribute.rb +39 -9
- data/lib/attributor/dsl_compiler.rb +17 -9
- data/lib/attributor/exceptions.rb +5 -0
- 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/smart_attribute_selector.rb +149 -0
- 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 +22 -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 +105 -21
- 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 +16 -6
- data/spec/extras/field_selector/field_selector_spec.rb +9 -0
- data/spec/hash_dsl_compiler_spec.rb +2 -2
- data/spec/smart_attribute_selector_spec.rb +272 -0
- 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 +181 -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 +24 -34
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
|
@@ -497,6 +498,22 @@ describe Attributor::Hash do
|
|
497
498
|
end
|
498
499
|
end
|
499
500
|
|
501
|
+
context '.requirements' do
|
502
|
+
let(:type) { Attributor::Hash.construct(block) }
|
503
|
+
|
504
|
+
context 'forces processing of lazy key initialization' do
|
505
|
+
let(:block) do
|
506
|
+
proc do
|
507
|
+
key 'name', String
|
508
|
+
requires 'name'
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
it 'lists the requirements' do
|
513
|
+
expect(type.requirements).to_not be_empty
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
500
517
|
context '#validate' do
|
501
518
|
context 'for a key and value typed hash' do
|
502
519
|
let(:key_type) { Integer }
|
@@ -651,7 +668,7 @@ describe Attributor::Hash do
|
|
651
668
|
at_least(1).of 'consistency', 'availability', 'partitioning'
|
652
669
|
end
|
653
670
|
# Silly example, just to show that block and inline requires can be combined
|
654
|
-
requires.at_most(
|
671
|
+
requires.at_most(1).of 'consistency', 'availability', 'partitioning'
|
655
672
|
end
|
656
673
|
end
|
657
674
|
|
@@ -663,6 +680,37 @@ describe Attributor::Hash do
|
|
663
680
|
)
|
664
681
|
end
|
665
682
|
end
|
683
|
+
context 'using a combo of things to test example gen' do
|
684
|
+
let(:block) do
|
685
|
+
proc do
|
686
|
+
key :req1, String
|
687
|
+
key :req2, String
|
688
|
+
key :exc3, String
|
689
|
+
key :exc4, String
|
690
|
+
key :least1, String
|
691
|
+
key :least2, String
|
692
|
+
key :exact1, String
|
693
|
+
key :exact2, String
|
694
|
+
key :most1, String
|
695
|
+
key :most2, String
|
696
|
+
|
697
|
+
requires.all :req1, :req2
|
698
|
+
requires.exclusive :exc3, :exc4
|
699
|
+
requires.at_least(2).of :least1, :least2
|
700
|
+
requires.exactly(1).of :exc3, :exact1, :exact2
|
701
|
+
requires.at_most(1).of :most1, :most2
|
702
|
+
requires.at_least(1).of :exc4, :exc3
|
703
|
+
end
|
704
|
+
end
|
705
|
+
it 'comes up with a reasonably good set' do
|
706
|
+
ex = type.example
|
707
|
+
expect(ex.keys).to match([:req1, :req2, :exc3, :least1, :least2, :most1])
|
708
|
+
end
|
709
|
+
it 'it favors picking attributes with data' do
|
710
|
+
ex = type.example(nil,most2: "data")
|
711
|
+
expect(ex.keys).to match([:req1, :req2, :exc3, :least1, :least2, :most2])
|
712
|
+
end
|
713
|
+
end
|
666
714
|
end
|
667
715
|
end
|
668
716
|
|
@@ -687,6 +735,13 @@ describe Attributor::Hash do
|
|
687
735
|
expect(description[:name]).to eq('Hash')
|
688
736
|
expect(description[:key]).to eq(type: { name: 'Object', id: 'Attributor-Object', family: 'any' })
|
689
737
|
expect(description[:value]).to eq(type: { name: 'Object', id: 'Attributor-Object', family: 'any' })
|
738
|
+
expect(description).to_not have_key(:example)
|
739
|
+
end
|
740
|
+
context 'when there is a given example' do
|
741
|
+
let(:example) { { 'one' => 1, two: 2 } }
|
742
|
+
it 'uses it, even though there are not individual keys' do
|
743
|
+
expect(description[:example]).to eq(example)
|
744
|
+
end
|
690
745
|
end
|
691
746
|
end
|
692
747
|
|
@@ -1096,10 +1151,10 @@ describe Attributor::Hash do
|
|
1096
1151
|
let(:hash_of_strings) { Attributor::Hash.of(key: String) }
|
1097
1152
|
let(:hash_of_symbols) { Attributor::Hash.of(key: Symbol) }
|
1098
1153
|
|
1099
|
-
let(:merger) { hash_of_strings.load('a' => 1) }
|
1100
|
-
let(:good_mergee) { hash_of_strings.load('b' => 2) }
|
1101
|
-
let(:bad_mergee) { hash_of_symbols.load(c: 3) }
|
1102
|
-
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) }
|
1103
1158
|
|
1104
1159
|
it 'validates that the mergee is of like type' do
|
1105
1160
|
expect { merger.merge(bad_mergee) }.to raise_error(ArgumentError)
|
@@ -1118,4 +1173,121 @@ describe Attributor::Hash do
|
|
1118
1173
|
|
1119
1174
|
context Attributor::InvalidDefinition do
|
1120
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
|
1121
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
|
|
data/spec/types/string_spec.rb
CHANGED
@@ -64,4 +64,14 @@ describe Attributor::String do
|
|
64
64
|
end.to raise_error(Attributor::IncompatibleTypeError)
|
65
65
|
end
|
66
66
|
end
|
67
|
+
|
68
|
+
context '.as_json_schema' do
|
69
|
+
subject(:js){ type.as_json_schema(attribute_options: { regexp: /^Foobar$/ }) }
|
70
|
+
it 'adds the right attributes' do
|
71
|
+
expect(js.keys).to include(:type, :'x-type_name')
|
72
|
+
expect(js[:type]).to eq(:string)
|
73
|
+
expect(js[:'x-type_name']).to eq('String')
|
74
|
+
expect(js[:pattern]).to eq('^Foobar$')
|
75
|
+
end
|
76
|
+
end
|
67
77
|
end
|