attributor 6.1 → 6.3
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/CHANGELOG.md +9 -1
- data/lib/attributor/attribute.rb +7 -0
- data/lib/attributor/types/hash.rb +17 -1
- data/lib/attributor/types/model.rb +5 -0
- data/lib/attributor/types/object.rb +12 -2
- data/lib/attributor/version.rb +1 -1
- data/spec/support/objects.rb +2 -0
- data/spec/types/hash_spec.rb +11 -4
- data/spec/types/model_spec.rb +22 -0
- data/spec/types/object_spec.rb +14 -0
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b30fd80bf80e1fba073207107cc6ee008d8f7f5edc3acd49863d58d27c9b2caa
|
4
|
+
data.tar.gz: 7549362dfe5fb7f1eb654ab7927996baee065f4b37cbdb74fcfb472189b8ea17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46fb615c0952564d354ed67e9ed4e794bead86868111cf3a1447f1aab92e9a8106addca135673b59acb67f58dfdbbc5ed8a49d9f5f5cebdf5a2439719c495768
|
7
|
+
data.tar.gz: 726a29e1f6a30025f51a62dfb63fc8331e3202a3553f031ad776679ee7a525a7e689feb75ed184d0eb306b6bbe6b7c03605bb6b396fd5e234e0ddc1fa751b2e8
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
# Attributor Changelog
|
2
2
|
|
3
3
|
## next
|
4
|
-
|
4
|
+
|
5
|
+
## 6.3 (10/21/2022)
|
6
|
+
- Added some small utility enhancements for dealing with attributes and types
|
7
|
+
* .duplicate an attribute, with a different inner type and/or options
|
8
|
+
* .slice a Hash/Model/Struct to reduce the number of keys that it holds
|
9
|
+
* .merge two Hash/Model/Struct keys into an existing one (even if the types differ)
|
10
|
+
|
11
|
+
## 6.2 (5/11/2022)
|
12
|
+
- Added .to_hash for Model/Struct, which returns a symbolized key hash (without recursing). This allows to splat instances of Model/Structs into functions that have keyword arguments.
|
5
13
|
|
6
14
|
## 6.1 (1/7/2022)
|
7
15
|
- added support for enum's out of values in json_schema generation
|
data/lib/attributor/attribute.rb
CHANGED
@@ -45,6 +45,13 @@ module Attributor
|
|
45
45
|
check_options!
|
46
46
|
end
|
47
47
|
|
48
|
+
def duplicate(type: nil, options: nil)
|
49
|
+
clone.tap do |cloned|
|
50
|
+
cloned.instance_variable_set(:@type, type) if type
|
51
|
+
cloned.instance_variable_set(:@options, options) if options
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
48
55
|
def ==(other)
|
49
56
|
raise ArgumentError, "can not compare Attribute with #{other.class.name}" unless other.is_a?(Attribute)
|
50
57
|
|
@@ -41,6 +41,13 @@ module Attributor
|
|
41
41
|
@error = false
|
42
42
|
@requirements = []
|
43
43
|
|
44
|
+
def self.slice!(*keys)
|
45
|
+
missing_keys = keys - @keys.keys
|
46
|
+
raise AttributorException, "Cannot slice! this type, because it does not contain one or more of the requested keys: #{missing_keys}" unless missing_keys.empty?
|
47
|
+
instance_variable_set(:@keys, @keys.slice(*keys))
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
44
51
|
def self.key_type=(key_type)
|
45
52
|
@key_type = Attributor.resolve_type(key_type)
|
46
53
|
@key_attribute = Attribute.new(@key_type)
|
@@ -461,6 +468,7 @@ module Attributor
|
|
461
468
|
else
|
462
469
|
hash[:value] = { type: value_type.describe(true) }
|
463
470
|
hash[:example] = example if example
|
471
|
+
hash[:attributes] = {}
|
464
472
|
end
|
465
473
|
|
466
474
|
hash
|
@@ -567,7 +575,15 @@ module Attributor
|
|
567
575
|
when self.class
|
568
576
|
self.class.new(contents.merge(h.contents))
|
569
577
|
when Attributor::Hash
|
570
|
-
|
578
|
+
source_key_type = self.class.key_type
|
579
|
+
source_value_type = self.class.value_type
|
580
|
+
# Allow merging hashes, but we'll need to coerce keys and/or values if they aren't the same type
|
581
|
+
coerced_contents = h.contents.each_with_object({}) do |(key, val), object|
|
582
|
+
k = (source_key_type && !k.is_a?(source_key_type)) ? source_key_type.load(key) : key
|
583
|
+
v = (source_value_type && !k.is_a?(source_value_type)) ? source_value_type.load(val) : val
|
584
|
+
object[k] = v
|
585
|
+
end
|
586
|
+
self.class.new(contents.merge(coerced_contents))
|
571
587
|
else
|
572
588
|
raise TypeError, "no implicit conversion of #{h.class} into Attributor::Hash"
|
573
589
|
end
|
@@ -179,6 +179,11 @@ module Attributor
|
|
179
179
|
ensure
|
180
180
|
@dumping = false
|
181
181
|
end
|
182
|
+
|
183
|
+
# This allows the splatting of these instances into method calls (top level hash conversion only)
|
184
|
+
def to_hash
|
185
|
+
@contents
|
186
|
+
end
|
182
187
|
end
|
183
188
|
|
184
189
|
# Override the generic way to get a value from an instance (models need to call the method)
|
@@ -13,10 +13,20 @@ module Attributor
|
|
13
13
|
def self.example(_context = nil, options: {})
|
14
14
|
'An Object'
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
|
+
# Not really used (we override as_json_schema to represent this as an Any Type),
|
18
|
+
# but if it _were_ used, this would be accurate.
|
17
19
|
def self.json_schema_type
|
18
|
-
:object
|
20
|
+
:object
|
19
21
|
end
|
20
22
|
|
23
|
+
# Represents Object as an OpenAPI Any Type.
|
24
|
+
#
|
25
|
+
# @see https://swagger.io/docs/specification/data-models/data-types/#any
|
26
|
+
def self.as_json_schema(**kwargs)
|
27
|
+
schema = super(**kwargs)
|
28
|
+
schema.delete(:type)
|
29
|
+
schema
|
30
|
+
end
|
21
31
|
end
|
22
32
|
end
|
data/lib/attributor/version.rb
CHANGED
data/spec/types/hash_spec.rb
CHANGED
@@ -1189,16 +1189,15 @@ describe Attributor::Hash do
|
|
1189
1189
|
end
|
1190
1190
|
|
1191
1191
|
context '#merge' do
|
1192
|
-
let(:hash_of_strings) { Attributor::Hash.of(key: String) }
|
1193
|
-
let(:
|
1192
|
+
let(:hash_of_strings) { Attributor::Hash.of(key: String, value: Integer) }
|
1193
|
+
let(:hash_of_symbols_and_string_vals) { Attributor::Hash.of(key: Symbol) }
|
1194
1194
|
|
1195
1195
|
let(:merger) { hash_of_strings.load({'a' => 1},nil) }
|
1196
1196
|
let(:good_mergee) { hash_of_strings.load({'b' => 2},nil) }
|
1197
|
-
let(:
|
1197
|
+
let(:different_hash_mergee) { hash_of_symbols_and_string_vals.load({c: '3'}) }
|
1198
1198
|
let(:result) { hash_of_strings.load({'a' => 1, 'b' => 2},nil) }
|
1199
1199
|
|
1200
1200
|
it 'validates that the mergee is of like type' do
|
1201
|
-
expect { merger.merge(bad_mergee) }.to raise_error(ArgumentError)
|
1202
1201
|
expect { merger.merge({}) }.to raise_error(TypeError)
|
1203
1202
|
expect { merger.merge(nil) }.to raise_error(TypeError)
|
1204
1203
|
end
|
@@ -1210,6 +1209,14 @@ describe Attributor::Hash do
|
|
1210
1209
|
it 'merges' do
|
1211
1210
|
expect(merger.merge(good_mergee)).to eq(result)
|
1212
1211
|
end
|
1212
|
+
|
1213
|
+
it 'allows Hash merges, even if they come from different types, by coercing keys/values' do
|
1214
|
+
merged = merger.merge(different_hash_mergee)
|
1215
|
+
expect(merged).to be_a(hash_of_strings)
|
1216
|
+
result = hash_of_strings.load({'a' => 1, 'c' => 3},nil)
|
1217
|
+
# :c is coerced to 'c' and values are coerced to integers
|
1218
|
+
expect(merged).to eq(result)
|
1219
|
+
end
|
1213
1220
|
end
|
1214
1221
|
|
1215
1222
|
context Attributor::InvalidDefinition do
|
data/spec/types/model_spec.rb
CHANGED
@@ -523,4 +523,26 @@ describe Attributor::Model do
|
|
523
523
|
expect(example.dump).to eq({})
|
524
524
|
end
|
525
525
|
end
|
526
|
+
|
527
|
+
context '#to_hash' do
|
528
|
+
let(:model_type) do
|
529
|
+
Class.new(Attributor::Model) do
|
530
|
+
attributes do
|
531
|
+
attribute :name, String
|
532
|
+
attribute :subkey do
|
533
|
+
attribute :id, Integer
|
534
|
+
end
|
535
|
+
end
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
subject { model_type.new(name: 'Praxis', subkey: { id: 1 }).to_hash }
|
540
|
+
it 'returns the top keys as a hash' do
|
541
|
+
expect(subject.keys).to eq([:name, :subkey])
|
542
|
+
end
|
543
|
+
it 'does not recurse down' do
|
544
|
+
expect(subject[:subkey]).to be_kind_of Attributor::Struct
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
526
548
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
2
|
+
|
3
|
+
describe Attributor::Object do
|
4
|
+
context 'JSON Schema representation' do
|
5
|
+
subject { UntypedObject.as_json_schema }
|
6
|
+
it 'is an Any Type' do
|
7
|
+
# "A schema without a type matches any data type – numbers, strings, objects, and so on."
|
8
|
+
# c.f. https://swagger.io/docs/specification/data-models/data-types/#any
|
9
|
+
expect(subject).not_to have_key(:type)
|
10
|
+
# but we still preserve Ruby type name, if anyone is curious
|
11
|
+
expect(subject[:"x-type_name"]).to eq("UntypedObject")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attributor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '6.
|
4
|
+
version: '6.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josep M. Blanquer
|
8
8
|
- Dane Jensen
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-10-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hashie
|
@@ -291,7 +291,7 @@ dependencies:
|
|
291
291
|
- - ">="
|
292
292
|
- !ruby/object:Gem::Version
|
293
293
|
version: '0'
|
294
|
-
description:
|
294
|
+
description:
|
295
295
|
email:
|
296
296
|
- blanquer@gmail.com
|
297
297
|
- dane.jensen@gmail.com
|
@@ -361,6 +361,7 @@ files:
|
|
361
361
|
- spec/support/hashes.rb
|
362
362
|
- spec/support/integers.rb
|
363
363
|
- spec/support/models.rb
|
364
|
+
- spec/support/objects.rb
|
364
365
|
- spec/support/polymorphics.rb
|
365
366
|
- spec/type_spec.rb
|
366
367
|
- spec/types/bigdecimal_spec.rb
|
@@ -377,6 +378,7 @@ files:
|
|
377
378
|
- spec/types/ids_spec.rb
|
378
379
|
- spec/types/integer_spec.rb
|
379
380
|
- spec/types/model_spec.rb
|
381
|
+
- spec/types/object_spec.rb
|
380
382
|
- spec/types/polymorphic_spec.rb
|
381
383
|
- spec/types/regexp_spec.rb
|
382
384
|
- spec/types/string_spec.rb
|
@@ -390,7 +392,7 @@ homepage: https://github.com/rightscale/attributor
|
|
390
392
|
licenses:
|
391
393
|
- MIT
|
392
394
|
metadata: {}
|
393
|
-
post_install_message:
|
395
|
+
post_install_message:
|
394
396
|
rdoc_options: []
|
395
397
|
require_paths:
|
396
398
|
- lib
|
@@ -406,7 +408,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
406
408
|
version: '0'
|
407
409
|
requirements: []
|
408
410
|
rubygems_version: 3.1.2
|
409
|
-
signing_key:
|
411
|
+
signing_key:
|
410
412
|
specification_version: 4
|
411
413
|
summary: A powerful attribute and type management library for Ruby
|
412
414
|
test_files:
|
@@ -422,6 +424,7 @@ test_files:
|
|
422
424
|
- spec/support/hashes.rb
|
423
425
|
- spec/support/integers.rb
|
424
426
|
- spec/support/models.rb
|
427
|
+
- spec/support/objects.rb
|
425
428
|
- spec/support/polymorphics.rb
|
426
429
|
- spec/type_spec.rb
|
427
430
|
- spec/types/bigdecimal_spec.rb
|
@@ -438,6 +441,7 @@ test_files:
|
|
438
441
|
- spec/types/ids_spec.rb
|
439
442
|
- spec/types/integer_spec.rb
|
440
443
|
- spec/types/model_spec.rb
|
444
|
+
- spec/types/object_spec.rb
|
441
445
|
- spec/types/polymorphic_spec.rb
|
442
446
|
- spec/types/regexp_spec.rb
|
443
447
|
- spec/types/string_spec.rb
|