smart_params 4.1.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -10
- data/lib/smart_params/error/invalid_property_type.rb +8 -2
- data/lib/smart_params/error/invalid_property_type_spec.rb +14 -4
- data/lib/smart_params/field.rb +26 -7
- data/lib/smart_params/version.rb +1 -1
- data/lib/smart_params.rb +9 -5
- data/lib/smart_params_spec.rb +8 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72ea358328d6d2de0b7cb159c3f7a02eaeeba1114428d0dd1eef74033311a4b5
|
4
|
+
data.tar.gz: 3b864136adce02b4393645f42e56f46086b4a7b0b8a1e75a326ffcb0ab3a6b49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6020bd0591d343040c21882a091e6bb9535132f116e6c538ea60edbe4f7da15581dafae6158d37fe81d0aa52f920827e416af88fdd25e4ea9e6da182a719096
|
7
|
+
data.tar.gz: 20c54169633985ed7febf49f4b5028c0b375017f793d6a3f0ee172ea9ce41e72869ec745cc5e6e854fdd4f6c3ae989e80cce6806f3b1e286e6e8be92c8f45c10
|
data/README.md
CHANGED
@@ -11,19 +11,19 @@ So lets say you have a complex set of incoming data, say a JSON:API-specificatio
|
|
11
11
|
class CreateAccountSchema
|
12
12
|
include SmartParams
|
13
13
|
|
14
|
-
schema
|
15
|
-
field :data,
|
16
|
-
field :id, type: Coercible::String
|
14
|
+
schema do
|
15
|
+
field :data, subschema: true do
|
16
|
+
field :id, type: Coercible::String, nullable: true
|
17
17
|
field :type, type: Strict::String
|
18
|
-
field :attributes,
|
19
|
-
field :email, type: Strict::String
|
20
|
-
field :username, type: Strict::String
|
21
|
-
field :name, type: Strict::String
|
22
|
-
field :password, type: Strict::String.
|
18
|
+
field :attributes, subschema: true, nullable: true do
|
19
|
+
field :email, type: Strict::String, nullable: true
|
20
|
+
field :username, type: Strict::String, nullable: true
|
21
|
+
field :name, type: Strict::String, nullable: true
|
22
|
+
field :password, type: Strict::String.default { SecureRandom.hex(32) }, nullable: true
|
23
23
|
end
|
24
24
|
end
|
25
|
-
field :meta,
|
26
|
-
field :included, type: Strict::Array
|
25
|
+
field :meta, Strict::Hash, nullable: true
|
26
|
+
field :included, type: Strict::Array, nullable: true
|
27
27
|
end
|
28
28
|
end
|
29
29
|
```
|
@@ -6,16 +6,22 @@ module SmartParams
|
|
6
6
|
attr_reader :keychain
|
7
7
|
attr_reader :wanted
|
8
8
|
attr_reader :raw
|
9
|
+
attr_reader :missing_key
|
9
10
|
|
10
|
-
def initialize(keychain:, wanted:, raw:)
|
11
|
+
def initialize(keychain:, wanted:, raw:, missing_key: nil)
|
11
12
|
super
|
12
13
|
@keychain = keychain
|
13
14
|
@wanted = wanted
|
14
15
|
@raw = raw
|
16
|
+
@missing_key = missing_key
|
15
17
|
end
|
16
18
|
|
17
19
|
def message
|
18
|
-
|
20
|
+
if missing_key
|
21
|
+
"expected #{keychain.inspect} to be #{wanted.name} with key #{missing_key.inspect}, but is #{raw.inspect}"
|
22
|
+
else
|
23
|
+
"expected #{keychain.inspect} to be #{wanted.name}, but is #{raw.inspect}"
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
def as_json
|
@@ -3,13 +3,23 @@
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
5
|
RSpec.describe SmartParams::Error::InvalidPropertyType do
|
6
|
-
let(:error) { described_class.new(keychain: [:data], wanted: SmartParams::Strict::Hash, raw: "") }
|
7
|
-
|
8
6
|
describe "#message" do
|
9
7
|
subject { error.message }
|
10
8
|
|
11
|
-
|
12
|
-
|
9
|
+
context "when the error is about the type mismatch" do
|
10
|
+
let(:error) { described_class.new(keychain: [:data], wanted: SmartParams::Strict::Hash, raw: "") }
|
11
|
+
|
12
|
+
it "returns the message" do
|
13
|
+
expect(subject).to eq("expected [:data] to be Hash, but is \"\"")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when the error is about a missing key" do
|
18
|
+
let(:error) { described_class.new(keychain: [:data], wanted: SmartParams::Strict::Hash.schema(data: SmartParams::Strict::String), raw: {}, missing_key: :data) }
|
19
|
+
|
20
|
+
it "returns the message" do
|
21
|
+
expect(subject).to eq("expected [:data] to be Hash with key :data, but is {}")
|
22
|
+
end
|
13
23
|
end
|
14
24
|
end
|
15
25
|
end
|
data/lib/smart_params/field.rb
CHANGED
@@ -5,18 +5,36 @@ module SmartParams
|
|
5
5
|
attr_reader :keychain
|
6
6
|
attr_reader :subfields
|
7
7
|
attr_reader :type
|
8
|
+
attr_reader :nullable
|
9
|
+
attr_reader :key
|
8
10
|
|
9
|
-
def
|
11
|
+
def inspect
|
12
|
+
"#<#{self.class.name}:#{__id__} #{[
|
13
|
+
('subschema' if @subschema),
|
14
|
+
("#/#{@keychain.join('/')}" if @keychain),
|
15
|
+
("-> #{type.name}" if @type),
|
16
|
+
("= #{@value.inspect}" if @value)
|
17
|
+
].compact.join(' ')}>"
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(keychain:, type:, key: nil, subschema: false, nullable: false, &nesting)
|
21
|
+
@key = key
|
10
22
|
@keychain = Array(keychain)
|
11
23
|
@subfields = Set.new
|
12
24
|
@type = type
|
13
25
|
@nullable = nullable
|
26
|
+
@subschema = subschema
|
14
27
|
@specified = false
|
15
28
|
@dirty = false
|
16
29
|
|
17
|
-
|
30
|
+
instance_eval(&nesting) if nesting
|
18
31
|
|
19
|
-
|
32
|
+
if subschema
|
33
|
+
@type = @type.schema(subfields.reduce({}) do |mapping, field|
|
34
|
+
mapping.merge("#{field.key}#{'?' if field.nullable}": field.type)
|
35
|
+
end).with_key_transform(&:to_sym)
|
36
|
+
end
|
37
|
+
@type = @type.optional if nullable
|
20
38
|
end
|
21
39
|
|
22
40
|
def deep?
|
@@ -72,8 +90,10 @@ module SmartParams
|
|
72
90
|
return type[dug(raw)] if deep?
|
73
91
|
|
74
92
|
@value = type[dug(raw)]
|
75
|
-
rescue Dry::Types::ConstraintError
|
93
|
+
rescue Dry::Types::ConstraintError => _constraint_exception
|
76
94
|
raise SmartParams::Error::InvalidPropertyType.new(keychain:, wanted: type, raw: keychain.empty? ? raw : raw.dig(*keychain))
|
95
|
+
rescue Dry::Types::MissingKeyError => missing_key_exception
|
96
|
+
raise SmartParams::Error::InvalidPropertyType.new(keychain:, wanted: type, raw: keychain.empty? ? raw : raw.dig(*keychain), missing_key: missing_key_exception.key)
|
77
97
|
end
|
78
98
|
|
79
99
|
def to_hash
|
@@ -95,9 +115,8 @@ module SmartParams
|
|
95
115
|
keychain.map(&:to_s)
|
96
116
|
end
|
97
117
|
|
98
|
-
private def field(key, type
|
99
|
-
|
100
|
-
@subfields << self.class.new(keychain: [*keychain, key], type:, nullable:, &subfield)
|
118
|
+
private def field(key, subschema: false, type: SmartParams::Hash, nullable: false, &subfield)
|
119
|
+
@subfields << self.class.new(key:, keychain: [*keychain, key], type:, nullable:, subschema:, &subfield)
|
101
120
|
end
|
102
121
|
|
103
122
|
# Very busy method with recent changes. TODO: clean-up
|
data/lib/smart_params/version.rb
CHANGED
data/lib/smart_params.rb
CHANGED
@@ -24,10 +24,14 @@ module SmartParams
|
|
24
24
|
@schema = self.class.instance_variable_get(:@schema)[name]
|
25
25
|
|
26
26
|
@fields = [@schema, *unfold(@schema.subfields)].sort_by(&:weight).each { |field| field.claim(raw) }
|
27
|
-
rescue SmartParams::Error::InvalidPropertyType =>
|
28
|
-
raise
|
27
|
+
rescue SmartParams::Error::InvalidPropertyType => invalid_property_exception
|
28
|
+
raise invalid_property_exception if safe?
|
29
29
|
|
30
|
-
@exception =
|
30
|
+
@exception = invalid_property_exception
|
31
|
+
end
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
"#<#{self.class.name}:#{__id__} @fields=#{@fields.inspect} @raw=#{@raw.inspect}>"
|
31
35
|
end
|
32
36
|
|
33
37
|
def payload
|
@@ -96,9 +100,9 @@ module SmartParams
|
|
96
100
|
end
|
97
101
|
|
98
102
|
class_methods do
|
99
|
-
def schema(name: :default, type
|
103
|
+
def schema(name: :default, type: Hash, subschema: false, &definitions)
|
100
104
|
@schema ||= {}
|
101
|
-
@schema[name] = Field.new(keychain: [], type:, &definitions)
|
105
|
+
@schema[name] = Field.new(keychain: [], type:, subschema:, &definitions)
|
102
106
|
end
|
103
107
|
end
|
104
108
|
end
|
data/lib/smart_params_spec.rb
CHANGED
@@ -12,12 +12,12 @@ RSpec.describe SmartParams do
|
|
12
12
|
let(:params) { {} }
|
13
13
|
|
14
14
|
it "throws an error with a message detailing the invalid property type and given properties" do
|
15
|
-
expect { schema }.to raise_exception(SmartParams::Error::InvalidPropertyType, "expected [:data] to be Hash, but
|
15
|
+
expect { schema }.to raise_exception(SmartParams::Error::InvalidPropertyType, "expected [:data] to be Hash, but is nil")
|
16
16
|
end
|
17
17
|
|
18
18
|
it "throws an error with the missing property and given properties" do
|
19
19
|
expect { schema }.to raise_exception do |exception|
|
20
|
-
expect(exception).to have_attributes(keychain: [:data], wanted:
|
20
|
+
expect(exception).to have_attributes(keychain: [:data], wanted: a_kind_of(Dry::Types::Constrained), raw: nil)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -26,12 +26,12 @@ RSpec.describe SmartParams do
|
|
26
26
|
let(:params) { { data: "" } }
|
27
27
|
|
28
28
|
it "throws an error with a message detailing the invalid property, expected type, given type, and given value" do
|
29
|
-
expect { schema }.to raise_exception(SmartParams::Error::InvalidPropertyType, "expected [:data] to be Hash, but
|
29
|
+
expect { schema }.to raise_exception(SmartParams::Error::InvalidPropertyType, "expected [:data] to be Hash, but is \"\"")
|
30
30
|
end
|
31
31
|
|
32
32
|
it "throws an error with the invalid property, expected type, given type, and given value" do
|
33
33
|
expect { schema }.to raise_exception do |exception|
|
34
|
-
expect(exception).to have_attributes(keychain: [:data], wanted:
|
34
|
+
expect(exception).to have_attributes(keychain: [:data], wanted: a_kind_of(Dry::Types::Constrained), raw: "")
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -456,18 +456,20 @@ RSpec.describe SmartParams do
|
|
456
456
|
let(:params) do
|
457
457
|
{
|
458
458
|
data: {
|
459
|
+
id: "x",
|
460
|
+
type: "y",
|
459
461
|
is: "garbage"
|
460
462
|
}
|
461
463
|
}
|
462
464
|
end
|
463
465
|
|
464
|
-
it "does not
|
466
|
+
it "does not return key that isn't specified" do
|
465
467
|
expect(
|
466
468
|
subject
|
467
469
|
).to match(
|
468
470
|
hash_excluding(
|
469
471
|
{
|
470
|
-
"
|
472
|
+
"is" => "garbage"
|
471
473
|
}
|
472
474
|
)
|
473
475
|
)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_params
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kurtis Rainbolt-Greene
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-09-
|
11
|
+
date: 2023-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|