attributor 5.2.1 → 5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +4 -2
- data/CHANGELOG.md +136 -142
- data/attributor.gemspec +4 -4
- data/lib/attributor.rb +1 -1
- data/lib/attributor/attribute.rb +1 -1
- data/lib/attributor/hash_dsl_compiler.rb +6 -6
- data/lib/attributor/type.rb +1 -1
- data/lib/attributor/types/bigdecimal.rb +1 -1
- data/lib/attributor/types/boolean.rb +2 -2
- data/lib/attributor/types/class.rb +1 -1
- data/lib/attributor/types/collection.rb +5 -5
- data/lib/attributor/types/container.rb +3 -3
- data/lib/attributor/types/csv.rb +1 -1
- data/lib/attributor/types/date.rb +2 -2
- data/lib/attributor/types/date_time.rb +1 -1
- data/lib/attributor/types/hash.rb +8 -8
- data/lib/attributor/types/model.rb +1 -1
- data/lib/attributor/types/string.rb +1 -1
- data/lib/attributor/types/struct.rb +1 -1
- data/lib/attributor/types/time.rb +1 -1
- data/lib/attributor/types/uri.rb +1 -1
- data/lib/attributor/version.rb +1 -1
- data/spec/attribute_spec.rb +5 -1
- data/spec/dsl_compiler_spec.rb +7 -7
- data/spec/hash_dsl_compiler_spec.rb +2 -2
- data/spec/type_spec.rb +1 -1
- data/spec/types/hash_spec.rb +9 -9
- data/spec/types/integer_spec.rb +1 -1
- data/spec/types/model_spec.rb +3 -3
- metadata +15 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a11bd68a97257cb5818f1bcebf57f02bde25bf22904c878117f7e729e5bd0b94
|
4
|
+
data.tar.gz: 3e5e895e7f60be40aad375c37cac20f031b9687cd08f0496fa5457954e29df3d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72386a9b285c56eed7c6a5d5a06b35fe2e892d3f2e8e689412b02e07eaabbbefe768d6b9739f63523276b2ffd89b47cb24c9cdaf43d7fca65da16e0741cc184a
|
7
|
+
data.tar.gz: 6261ac3f99788710e20e3fb7acbe4c4808da4eb77e3c346b329148c791d59ea490fe256552420b0373e2ef82c9cc6e7a7b86e57b0b0a72469ac46dd455a1fdc4
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,50 +2,53 @@
|
|
2
2
|
|
3
3
|
## next
|
4
4
|
|
5
|
-
## 5.
|
5
|
+
## 5.3 (24/04/2020)
|
6
6
|
|
7
|
-
|
7
|
+
- Fixed deprecation warnings in Ruby 2.7
|
8
8
|
|
9
|
-
## 5.2 (
|
9
|
+
## 5.2.1 (25/08/2019)
|
10
|
+
|
11
|
+
- Propertly pass options down when dumping an Model
|
10
12
|
|
11
|
-
|
12
|
-
* Fix bug that would occur when defining an attribute carrying a reference object, for which the reference type didn't have `attributes` (for example a Collection).
|
13
|
-
* Allows an attribute to override the reference object through its options of its parent (even when its containing object already has one defined).
|
14
|
-
* Built code to generate examples in a smarter way when complex conditional requirements are specified.
|
13
|
+
## 5.2 (12/09/2017)
|
15
14
|
|
15
|
+
- Fixed describing `Hash` with no keys defined, to still use a given example (no example outputted before this)
|
16
|
+
- Fix bug that would occur when defining an attribute carrying a reference object, for which the reference type didn't have `attributes` (for example a Collection).
|
17
|
+
- Allows an attribute to override the reference object through its options of its parent (even when its containing object already has one defined).
|
18
|
+
- Built code to generate examples in a smarter way when complex conditional requirements are specified.
|
16
19
|
|
17
20
|
## 5.1
|
18
21
|
|
19
|
-
|
22
|
+
- Added `Polymorphic` type. See [polymorphics.rb](spec/support/polymorphics.rb) for example usage.
|
20
23
|
|
21
24
|
## 5.0.2
|
22
25
|
|
23
|
-
|
24
|
-
will respond to the `.dump` method, as a way to convert their internal substructure to primitive Ruby objects.
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
- Introduce the `Dumpable` (empty) module as an interface to indicate that instances of types that include it
|
27
|
+
will respond to the `.dump` method, as a way to convert their internal substructure to primitive Ruby objects.
|
28
|
+
- Currently the only two directly dumpable types are Collection and Hash (with the caveat that there are several others that derive from them..i.e., CSV, Model, etc...)
|
29
|
+
- The rest of types have `native_types` that are already Ruby primitive Objects.
|
30
|
+
- Fixed Hash and Model requirements to treat nil values as missing keys (to be compatible with the `required: true` option on an attribute).
|
28
31
|
|
29
32
|
## 5.0.1
|
30
33
|
|
31
|
-
|
34
|
+
- Fix bug that made Struct/Models skip validation of requirements using the `requires` DSL
|
32
35
|
|
33
36
|
## 5.0
|
34
37
|
|
35
|
-
|
36
|
-
|
38
|
+
- Changed `FieldSelector` sub-attribute selection to use `{}` instead of `()`.
|
37
39
|
|
38
40
|
## 4.2.0
|
39
41
|
|
40
|
-
|
41
|
-
* This is a simple documentation bit, that might help the clients to document the type properly (i.e. treat it as if the type was anonymously defined whenever is used, rather than reachable by id/name from anywhere)
|
42
|
+
- Added an "anonymous" DSL for base `Attributor::Type` which is reported in its `.describe` call.
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
- This is a simple documentation bit, that might help the clients to document the type properly (i.e. treat it as if the type was anonymously defined whenever is used, rather than reachable by id/name from anywhere)
|
45
|
+
|
46
|
+
- Built advanced attribute requirements for `Struct`,`Model` and `Hash` types. Those requirements allow you to define things like:
|
47
|
+
- A list of attributes that are required (equivalent to defining the required: true bit at each of the attributes)
|
48
|
+
- At most (n) attributes from a group can be passed in
|
49
|
+
- At least (n) attributes from a group are required
|
50
|
+
- Exactly (n) attributes from a group are required
|
51
|
+
- Example:
|
49
52
|
```
|
50
53
|
requires ‘id’, ‘name’
|
51
54
|
requires.all ‘id’, ‘name’ # Equivalent to above
|
@@ -54,7 +57,7 @@ will respond to the `.dump` method, as a way to convert their internal substruct
|
|
54
57
|
requires.at_least(1).of ‘rock’, ‘pop’
|
55
58
|
requires.exactly(2).of ‘one’, ‘two’, ’three’
|
56
59
|
```
|
57
|
-
|
60
|
+
- Same example expressed inside a block if so desired
|
58
61
|
```
|
59
62
|
requires do
|
60
63
|
all 'id', 'name
|
@@ -66,167 +69,158 @@ will respond to the `.dump` method, as a way to convert their internal substruct
|
|
66
69
|
|
67
70
|
## 4.1.0
|
68
71
|
|
69
|
-
|
70
|
-
|
72
|
+
- Added a `Class` type (useful to avoid demodulization coercions etc...)
|
73
|
+
- Added `Attributor::FieldSelector` type for parsing hierarchical field
|
71
74
|
selection hashes from a string. This is similar to the partial `fields`
|
72
75
|
parameter in Google APIs, or the `fields` parameter in the Facebook's Graph
|
73
76
|
API.
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
- For example: the string `'one,two(a,b)'` would select two top-level fields
|
78
|
+
named 'one' and 'two', retrieving the entire contents of 'one', and only
|
79
|
+
the 'a' and 'b' sub-fields for 'two'. The type will parse the above string
|
80
|
+
into the hash: `{one: true, two: {a: true, b: true}}`.
|
81
|
+
- This type is not automatically required by Attributor. To require it use:
|
82
|
+
`require 'attributor/extras/field_selector'.
|
83
|
+
- This type also depends upon the 'parslet' gem.
|
81
84
|
|
82
85
|
## 4.0.1
|
83
86
|
|
84
|
-
|
85
|
-
|
87
|
+
- `Attribute#check_option!` now calls `load` on any provided value.
|
86
88
|
|
87
89
|
## 4.0.0
|
88
90
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
91
|
+
- Changed the expectation of the value for an `:example` option of an attribute:
|
92
|
+
- Before, passing an array of values would indicate that those were a few possible examples for it.
|
93
|
+
- Now, any value (except the already existing special regexp or a proc) for an example will need to be of a native type (or coercible to it). This means that an attribute of type `Collection` can take an array example (and be taken as the whole thing)
|
94
|
+
- If anybody wants to provide multiple examples for an attribute they can write a proc, and make it return the different ones.
|
93
95
|
|
94
96
|
## 3.0.1
|
95
97
|
|
96
|
-
|
97
|
-
|
98
|
-
|
98
|
+
- Fixed bug with example Hashes where `[]` with a key not in the hash would throw a `NoMethodError`.
|
99
|
+
- Fixed bug in `Hash#get` for Hashes without predefined keys. It would throw an error if given a key not present in the hash's contents.
|
99
100
|
|
100
101
|
## 3.0.0
|
101
102
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
103
|
+
- Small enhancements on `describe` for types
|
104
|
+
- avoid creating empty `:attributes` key for `Model`
|
105
|
+
- ensure embedding `key_type` in `Hash` using `shallow` mode
|
106
|
+
- Added `Hash#delete`.
|
107
|
+
- Changed the schema for describing `Hash` to use `attributes` instead of `keys`
|
108
|
+
- It makes more sense, and it is compatible with Model and Structs too.
|
109
|
+
- Undefine JRuby package helper methods in `Model` (org, java...)
|
110
|
+
- Added support to `Collection.load` for any value that responds to `to_a`
|
111
|
+
- Fixed `Collection.validate` to complain when value object is not a valida type
|
112
|
+
- Fixed bug where defining an attribute that references a `Collection` would not properly support defining sub-attributes in a provided block.
|
113
|
+
- Enhanced the type/attribute `describe` methods of types so that they generate an example if an `example` argument is passed in.
|
114
|
+
- Complex (sub-structured) types will not output examples, only 'leaf' ones.
|
115
|
+
- Improved handling of exceptions during attribute definitions for `Hash`/`Model` that would previously leave the set of attributes in an undefined state. Now, any attempts to use the type will throw an `InvalidDefinition` exception and include the original exception. (#127)
|
116
|
+
- Removed `undef :empty?` from `Model`
|
117
|
+
- Made `Collection` a subclass of Array, and `load` create new instances of it.
|
118
|
+
- Built in proper loading and validation of any `Attribute#example` when the `:example` option is used.
|
119
119
|
|
120
120
|
## 2.6.1
|
121
121
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
122
|
+
- Add the `:custom_data` option for attributes. This is a hash that is passed through to `describe` - Attributor does no processing or handling of this option.
|
123
|
+
- Added `Type.family` which returns a more-generic "family name". It's defined for all built-in types, and is included in `Type.describe`.
|
124
|
+
- Cleanup and bug fixes around example generation for `Model`, `Struct` and `Hash`.
|
125
|
+
- Avoid creating method accessors for true `Hash` types (only `[]` accessors)
|
126
|
+
- Fix common hash methods created for example instances (to play well with lazy attributes)
|
127
|
+
- Avoid storing the `Hash#insensitive_map` unless insensitivity enabled
|
128
128
|
|
129
129
|
## 2.6.0
|
130
130
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
131
|
+
- Fixed bug in `example_mixin` where lazy_attributes were not evaluated.
|
132
|
+
- Fixed bug in `Hash` where the class would refuse to load from another `Attributor::Hash` when there were no keys defined and they were seemingly compatible.
|
133
|
+
- Fixed a `Hash.dump` bug where nil attribute values would transitively be `dumpe`d therefore causing a nil dereference.
|
134
|
+
- Hardened the `dump`ing of types to support nil values.
|
135
|
+
- Fix `attribute.example` to actually accept native types (that are not only Strings)
|
136
|
+
- Fixed bug where `Hash#get` would insert a nil value if asked for a key that was not present in the hash.
|
137
|
+
- Fixed bug in `Hash.from_hash` where it would add nil values for keys that are defined on the type but not present in the input.
|
138
|
+
- Added `Hash#merge` that works with two identically-typed hashes
|
139
|
+
- Added `Hash#each_pair` for better duck-type compatibility with ::Hash.
|
141
140
|
|
142
141
|
## 2.5.0
|
143
142
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
143
|
+
- Partial support for defining `:default` values through Procs.
|
144
|
+
- Note: this is only "partially" supported the `parent` argument of the Proc will NOT contain the correct attribute parent yet. It will contain a fake class, that will loudly complain about any attempt to use any of its methods.
|
145
|
+
- Fixed `Model.example` to properly handle the case when no attributes are defined on the class.
|
146
|
+
- `Model#dump` now issues a warning if its contents have keys for attributes not present on the class. The unknown contents are not dumped.
|
147
|
+
- `Hash.load` now supports loading any value that responds to `to_hash`.
|
148
|
+
- `Time`, `DateTime`, and `Date` now all return ISO 8601 formatted values from `.dump` (via calling `iso8601` on the value).
|
149
|
+
- Added `Type.id`, a unique value based on the type's class name.
|
152
150
|
|
153
151
|
## 2.4.0
|
154
152
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
153
|
+
- `Model` is now a subclass of `Hash`.
|
154
|
+
- The interface for `Model` instances is almost entirely unchanged, except for the addition of `Hash`-like methods (i.e., you can now do `some_model[:key]` to access attributes).
|
155
|
+
- This fixes numerous incompatabilities between models and hashes, as well as confusing differences between the behavior when loading a model vs a hash.
|
156
|
+
- `String.load` now raises `IncompatibleTypeError` for `Enumerable` values.
|
157
|
+
- Added `Symbol` type, use with caution as it will automatically call `#to_sym` on anything loaded.
|
160
158
|
|
161
159
|
## 2.3.0
|
162
160
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
161
|
+
- Added `recurse` option to `Type.load` that is used by `Model` and `Hash` to force the loading of values (specifically, so that default values are assigned) even if the loaded value is `nil`.
|
162
|
+
- Fix `Attributor::CSV` to dump `String` values and generate `String` examples.
|
163
|
+
- Default values of `false` now work correctly.
|
164
|
+
- Added `BigDecimal`, `Date` and `Time` types
|
165
|
+
- `DateTime.load` now raises `CoercionError` (instead of returning `nil`) if given values that can not coerced properly.
|
166
|
+
- `Hash.dump` now first calls `Hash.load`, and correctly uses defined value types for dumping.
|
167
|
+
- Added `Hash#get`, for retrieving keys using the same logic the `case_insensitive_load` and `allow_extra` with defined `extra` key.
|
171
168
|
|
172
169
|
## 2.2.1
|
173
170
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
171
|
+
- Dumping attributes will now load the values if they're not in the native type.
|
172
|
+
- `Model.valid_type?` now accepts hashes.
|
173
|
+
- `Hash`:
|
174
|
+
- Added `:has_key?` to delegation
|
179
175
|
|
180
176
|
## 2.2.0
|
181
177
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
178
|
+
- Fix example generation for Hash and Collection to handle a non-Array context parameter.
|
179
|
+
- Hash:
|
180
|
+
- Added additional options:
|
181
|
+
- `:case_insensitive_load` for string-keyed hashes. This allows loading hashes with keys that do not exactly match the case defined in the hash.
|
182
|
+
- Added `:allow_extras` option to allow handling of undefined keys when loading.
|
183
|
+
- Added `Hash#set` to encapsulate the above options and attribute loading.
|
184
|
+
- Added `extra` command in the `keys` DSL, which lets you define a key (whose value should be a Hash), to group any unspecified keys during load.
|
190
185
|
|
191
186
|
## 2.1.0
|
192
187
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
188
|
+
- Structs now inherit type-level options from their reference.
|
189
|
+
- Add Collection subclasses for CSVs and Ids
|
190
|
+
- CSV type for Collection of values serialized as comma-separated strings.
|
191
|
+
- Ids type. A helper for creating CSVs with members matching a given a type's :identity option.
|
192
|
+
- Allow instances of Models to be initialized with initial data.
|
193
|
+
- Supported formats for the data are equivalent to the loading formats (i.e. ruby Hash, a JSON string or another instance of the same model type).
|
194
|
+
- Improved context reporting in errors
|
195
|
+
- Added contextual information while loading and dumping attributes.
|
196
|
+
- `load` takes a new `context` argument (defaulting to a system-wide root) in the form of an array of parent segments.
|
197
|
+
- `validate` takes a `context` argument that (instead of a string) is now an array of parent segments.
|
198
|
+
- `dump` takes a `context:` option parameter of the same type
|
199
|
+
- Enhanced error messages to report the correct context scope.
|
200
|
+
- Make Attribute assignments in models to report a special context (not the attributor root)
|
201
|
+
- Instead of reporting "\$." as the context , when doing model.field_name=value, they'll now report "assignment.of(field_name)" instead
|
202
|
+
- Truncate the length of values when reporting loading errors when they're long (i.e. >500 chars)
|
203
|
+
- `Model.attributes` may now be called more than once to set add or replace attributes. The exact behavior depends upon the types of the attributes being added or replaced. See [model_spec.rb](spec/types/model_spec.rb) for examples.
|
204
|
+
- Greately enhanced Hash type with individual key specification (rather than
|
210
205
|
simply defining the types of keys)
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
206
|
+
- Loaded Hash types now return instances of the class rather than a simple Ruby Hash.
|
207
|
+
- Introduced a new FileUpload type. This can be easily used in Web servers to map incoming multipart file uploads.
|
208
|
+
- Introduced a new Tempfile type.
|
215
209
|
|
216
210
|
## 2.0.0
|
217
211
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
212
|
+
- Added new exception subtypes (load methods return more precise errors now)
|
213
|
+
- Changed `Attributor::Model` to be a class instead of module.
|
214
|
+
- Improved handling of `Attributor::Model` examples:
|
215
|
+
- Support creating examples with specific values. i.e.:
|
222
216
|
```ruby
|
223
217
|
person = Person.example(name: "Bob")
|
224
218
|
person.name # => "Bob"
|
225
219
|
```
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
220
|
+
- Example values are now lazily initialized when used.
|
221
|
+
- Terminate sub-attribute generation after `Attributor::Model::MAX_EXAMPLE_DEPTH` levels to prevent infinite generation.
|
222
|
+
- Added additional options for Attribute :example values:
|
223
|
+
- explicit nil values
|
224
|
+
- procs that take 2 arguments now receive the context as the second argument.
|
225
|
+
- Circular references are now detected and handled in validation and dumping.
|
226
|
+
- Fixed bug with Model attribute accessors when using false values.
|
data/attributor.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
|
26
26
|
spec.add_development_dependency 'rspec', '~> 3'
|
27
27
|
spec.add_development_dependency 'rspec-its'
|
28
|
-
spec.add_development_dependency 'rspec-collection_matchers'
|
28
|
+
spec.add_development_dependency 'rspec-collection_matchers'
|
29
29
|
spec.add_development_dependency('yard')
|
30
30
|
spec.add_development_dependency('backports', ['~> 3'])
|
31
31
|
spec.add_development_dependency('yardstick', ['~> 0'])
|
@@ -34,10 +34,10 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_development_dependency('coveralls')
|
35
35
|
spec.add_development_dependency('guard', ['~> 2'])
|
36
36
|
spec.add_development_dependency('guard-rspec', ['~> 4'])
|
37
|
-
spec.add_development_dependency('pry'
|
37
|
+
spec.add_development_dependency('pry')
|
38
38
|
if RUBY_PLATFORM !~ /java/
|
39
|
-
spec.add_development_dependency('pry-byebug'
|
40
|
-
spec.add_development_dependency('pry-stack_explorer'
|
39
|
+
spec.add_development_dependency('pry-byebug')
|
40
|
+
spec.add_development_dependency('pry-stack_explorer')
|
41
41
|
end
|
42
42
|
spec.add_development_dependency 'fuubar'
|
43
43
|
spec.add_development_dependency 'rubocop'
|
data/lib/attributor.rb
CHANGED
@@ -29,7 +29,7 @@ module Attributor
|
|
29
29
|
def self.resolve_type(attr_type, options = {}, constructor_block = nil)
|
30
30
|
klass = self.find_type(attr_type)
|
31
31
|
|
32
|
-
return klass.construct(constructor_block, options) if klass.constructable?
|
32
|
+
return klass.construct(constructor_block, **options) if klass.constructable?
|
33
33
|
raise AttributorException, "Type: #{attr_type} does not support anonymous generation" if constructor_block
|
34
34
|
|
35
35
|
klass
|
data/lib/attributor/attribute.rb
CHANGED
@@ -89,31 +89,31 @@ module Attributor
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def all(*attr_names, **opts)
|
92
|
-
req = Requirement.new(options.merge(opts).merge(all: attr_names))
|
92
|
+
req = Requirement.new(**options.merge(opts).merge(all: attr_names))
|
93
93
|
target.add_requirement req
|
94
94
|
req
|
95
95
|
end
|
96
96
|
|
97
97
|
def at_most(number)
|
98
|
-
req = Requirement.new(options.merge(at_most: number))
|
98
|
+
req = Requirement.new(**options.merge(at_most: number))
|
99
99
|
target.add_requirement req
|
100
100
|
req
|
101
101
|
end
|
102
102
|
|
103
103
|
def at_least(number)
|
104
|
-
req = Requirement.new(options.merge(at_least: number))
|
104
|
+
req = Requirement.new(**options.merge(at_least: number))
|
105
105
|
target.add_requirement req
|
106
106
|
req
|
107
107
|
end
|
108
108
|
|
109
109
|
def exactly(number)
|
110
|
-
req = Requirement.new(options.merge(exactly: number))
|
110
|
+
req = Requirement.new(**options.merge(exactly: number))
|
111
111
|
target.add_requirement req
|
112
112
|
req
|
113
113
|
end
|
114
114
|
|
115
115
|
def exclusive(*attr_names, **opts)
|
116
|
-
req = Requirement.new(options.merge(opts).merge(exclusive: attr_names))
|
116
|
+
req = Requirement.new(**options.merge(opts).merge(exclusive: attr_names))
|
117
117
|
target.add_requirement req
|
118
118
|
req
|
119
119
|
end
|
@@ -132,7 +132,7 @@ module Attributor
|
|
132
132
|
_requirements_dsl
|
133
133
|
end
|
134
134
|
else
|
135
|
-
_requirements_dsl.all(*spec, opts)
|
135
|
+
_requirements_dsl.all(*spec, **opts)
|
136
136
|
end
|
137
137
|
end
|
138
138
|
end
|
data/lib/attributor/type.rb
CHANGED
@@ -29,7 +29,7 @@ module Attributor
|
|
29
29
|
def load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
|
30
30
|
return nil if value.nil?
|
31
31
|
unless value.is_a?(native_type)
|
32
|
-
raise Attributor::IncompatibleTypeError
|
32
|
+
raise Attributor::IncompatibleTypeError.new(context: context, value_type: value.class, type: self)
|
33
33
|
end
|
34
34
|
|
35
35
|
value
|
@@ -17,10 +17,10 @@ module Attributor
|
|
17
17
|
def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **_options)
|
18
18
|
return nil if value.nil?
|
19
19
|
|
20
|
-
raise CoercionError
|
20
|
+
raise CoercionError.new(context: context, from: value.class, to: self, value: value) if value.is_a?(::Float)
|
21
21
|
return false if [false, 'false', 'FALSE', '0', 0, 'f', 'F'].include?(value)
|
22
22
|
return true if [true, 'true', 'TRUE', '1', 1, 't', 'T'].include?(value)
|
23
|
-
raise CoercionError
|
23
|
+
raise CoercionError.new(context: context, from: value.class, to: self)
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.family
|
@@ -16,7 +16,7 @@ module Attributor
|
|
16
16
|
|
17
17
|
# Must be given a String object or nil
|
18
18
|
unless value.is_a?(::String) || value.nil?
|
19
|
-
raise IncompatibleTypeError
|
19
|
+
raise IncompatibleTypeError.new(context: context, value_type: value.class, type: self)
|
20
20
|
end
|
21
21
|
|
22
22
|
value = '::' + value if value[0..1] != '::'
|
@@ -51,7 +51,7 @@ module Attributor
|
|
51
51
|
|
52
52
|
def self.member_attribute
|
53
53
|
@member_attribute ||= begin
|
54
|
-
construct(nil
|
54
|
+
construct(nil)
|
55
55
|
|
56
56
|
@member_attribute
|
57
57
|
end
|
@@ -91,7 +91,7 @@ module Attributor
|
|
91
91
|
elsif value.respond_to?(:to_a)
|
92
92
|
loaded_value = value.to_a
|
93
93
|
else
|
94
|
-
raise Attributor::IncompatibleTypeError
|
94
|
+
raise Attributor::IncompatibleTypeError.new(context: context, value_type: value.class, type: self)
|
95
95
|
end
|
96
96
|
|
97
97
|
new(loaded_value.collect { |member| member_attribute.load(member, context) })
|
@@ -103,7 +103,7 @@ module Attributor
|
|
103
103
|
|
104
104
|
def self.dump(values, **opts)
|
105
105
|
return nil if values.nil?
|
106
|
-
values.collect { |value| member_attribute.dump(value, opts) }
|
106
|
+
values.collect { |value| member_attribute.dump(value, **opts) }
|
107
107
|
end
|
108
108
|
|
109
109
|
def self.describe(shallow = false, example: nil)
|
@@ -121,7 +121,7 @@ module Attributor
|
|
121
121
|
true
|
122
122
|
end
|
123
123
|
|
124
|
-
def self.construct(constructor_block, options)
|
124
|
+
def self.construct(constructor_block, **options)
|
125
125
|
member_options = (options[:member_options] || {}).clone
|
126
126
|
if options.key?(:reference) && !member_options.key?(:reference)
|
127
127
|
member_options[:reference] = options[:reference]
|
@@ -173,7 +173,7 @@ module Attributor
|
|
173
173
|
end
|
174
174
|
|
175
175
|
def dump(**opts)
|
176
|
-
collect { |value| self.class.member_attribute.dump(value, opts) }
|
176
|
+
collect { |value| self.class.member_attribute.dump(value, **opts) }
|
177
177
|
end
|
178
178
|
end
|
179
179
|
end
|
@@ -19,17 +19,17 @@ module Attributor
|
|
19
19
|
# @return [Array] a normal Ruby Array
|
20
20
|
#
|
21
21
|
def decode_json(value, context = Attributor::DEFAULT_ROOT_CONTEXT)
|
22
|
-
raise Attributor::DeserializationError
|
22
|
+
raise Attributor::DeserializationError.new(context: context, from: value.class, encoding: 'JSON', value: value) unless value.is_a? ::String
|
23
23
|
|
24
24
|
# attempt to parse as JSON
|
25
25
|
parsed_value = JSON.parse(value)
|
26
26
|
unless valid_type?(parsed_value)
|
27
|
-
raise Attributor::CoercionError
|
27
|
+
raise Attributor::CoercionError.new(context: context, from: parsed_value.class, to: name, value: parsed_value)
|
28
28
|
end
|
29
29
|
|
30
30
|
parsed_value
|
31
31
|
rescue JSON::JSONError
|
32
|
-
raise Attributor::DeserializationError
|
32
|
+
raise Attributor::DeserializationError.new(context: context, from: value.class, encoding: 'JSON', value: value)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
data/lib/attributor/types/csv.rb
CHANGED
@@ -21,10 +21,10 @@ module Attributor
|
|
21
21
|
begin
|
22
22
|
return ::Date.parse(value)
|
23
23
|
rescue ArgumentError
|
24
|
-
raise Attributor::DeserializationError
|
24
|
+
raise Attributor::DeserializationError.new(context: context, from: value.class, encoding: 'Date', value: value)
|
25
25
|
end
|
26
26
|
else
|
27
|
-
raise CoercionError
|
27
|
+
raise CoercionError.new(context: context, from: value.class, to: self, value: value)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -24,7 +24,7 @@ module Attributor
|
|
24
24
|
begin
|
25
25
|
return ::DateTime.parse(value)
|
26
26
|
rescue ArgumentError
|
27
|
-
raise Attributor::DeserializationError
|
27
|
+
raise Attributor::DeserializationError.new(context: context, from: value.class, encoding: 'DateTime', value: value)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -82,7 +82,7 @@ module Attributor
|
|
82
82
|
def self.attributes(**options, &key_spec)
|
83
83
|
raise @error if @error
|
84
84
|
|
85
|
-
keys(options, &key_spec)
|
85
|
+
keys(**options, &key_spec)
|
86
86
|
end
|
87
87
|
|
88
88
|
def self.keys(**options, &key_spec)
|
@@ -111,7 +111,7 @@ module Attributor
|
|
111
111
|
}.merge(@options)
|
112
112
|
|
113
113
|
blocks = @saved_blocks.shift(@saved_blocks.size)
|
114
|
-
compiler = dsl_class.new(self, opts)
|
114
|
+
compiler = dsl_class.new(self, **opts)
|
115
115
|
compiler.parse(*blocks)
|
116
116
|
|
117
117
|
if opts[:case_insensitive_load] == true
|
@@ -171,7 +171,7 @@ module Attributor
|
|
171
171
|
raise Attributor::AttributorException, ":case_insensitive_load may not be used with keys of type #{key_type.name}"
|
172
172
|
end
|
173
173
|
|
174
|
-
keys(options, &constructor_block)
|
174
|
+
keys(**options, &constructor_block)
|
175
175
|
self
|
176
176
|
end
|
177
177
|
|
@@ -221,7 +221,7 @@ module Attributor
|
|
221
221
|
result = new
|
222
222
|
result.extend(ExampleMixin)
|
223
223
|
|
224
|
-
result.lazy_attributes = example_contents(context, result, values)
|
224
|
+
result.lazy_attributes = example_contents(context, result, **values)
|
225
225
|
else
|
226
226
|
hash = ::Hash.new
|
227
227
|
|
@@ -285,7 +285,7 @@ module Attributor
|
|
285
285
|
elsif value.respond_to?(:to_hash)
|
286
286
|
value.to_hash
|
287
287
|
else
|
288
|
-
raise Attributor::IncompatibleTypeError
|
288
|
+
raise Attributor::IncompatibleTypeError.new(context: context, value_type: value.class, type: self)
|
289
289
|
end
|
290
290
|
end
|
291
291
|
|
@@ -607,12 +607,12 @@ module Attributor
|
|
607
607
|
@dumping = true
|
608
608
|
|
609
609
|
contents.each_with_object({}) do |(k, v), hash|
|
610
|
-
k = key_attribute.dump(k, opts)
|
610
|
+
k = key_attribute.dump(k, **opts)
|
611
611
|
|
612
612
|
v = if (attribute_for_value = self.class.keys[k])
|
613
|
-
attribute_for_value.dump(v, opts)
|
613
|
+
attribute_for_value.dump(v, **opts)
|
614
614
|
else
|
615
|
-
value_attribute.dump(v, opts)
|
615
|
+
value_attribute.dump(v, **opts)
|
616
616
|
end
|
617
617
|
|
618
618
|
hash[k] = v
|
@@ -8,7 +8,7 @@ module Attributor
|
|
8
8
|
|
9
9
|
def self.load(value, context = Attributor::DEFAULT_ROOT_CONTEXT, **options)
|
10
10
|
if value.is_a?(Enumerable)
|
11
|
-
raise IncompatibleTypeError
|
11
|
+
raise IncompatibleTypeError.new(context: context, value_type: value.class, type: self)
|
12
12
|
end
|
13
13
|
|
14
14
|
value && String(value)
|
@@ -29,7 +29,7 @@ module Attributor
|
|
29
29
|
begin
|
30
30
|
return ::Time.parse(value)
|
31
31
|
rescue ArgumentError
|
32
|
-
raise Attributor::DeserializationError
|
32
|
+
raise Attributor::DeserializationError.new(context: context, from: value.class, encoding: 'Time', value: value)
|
33
33
|
end
|
34
34
|
else
|
35
35
|
raise CoercionError, context: context, from: value.class, to: self, value: value
|
data/lib/attributor/types/uri.rb
CHANGED
data/lib/attributor/version.rb
CHANGED
data/spec/attribute_spec.rb
CHANGED
@@ -313,7 +313,11 @@ describe Attributor::Attribute do
|
|
313
313
|
let(:value) { '1' }
|
314
314
|
|
315
315
|
it 'delegates to type.load' do
|
316
|
-
|
316
|
+
# Need to add the "anything" of the 3rd element, as in ruby < 2.7 it comes as an empty hash
|
317
|
+
expect(type).to receive(:load) do |v, c, _other|
|
318
|
+
expect(v).to eq(value)
|
319
|
+
expect(c).to eq(context)
|
320
|
+
end
|
317
321
|
attribute.load(value, context)
|
318
322
|
end
|
319
323
|
|
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
|
@@ -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
|
data/spec/types/hash_spec.rb
CHANGED
@@ -359,7 +359,7 @@ describe Attributor::Hash do
|
|
359
359
|
context 'with unknown keys in input' do
|
360
360
|
it 'raises an error' do
|
361
361
|
expect do
|
362
|
-
type.load('other_key' => :value)
|
362
|
+
type.load({'other_key' => :value})
|
363
363
|
end.to raise_error(Attributor::AttributorException)
|
364
364
|
end
|
365
365
|
end
|
@@ -453,7 +453,7 @@ describe Attributor::Hash do
|
|
453
453
|
|
454
454
|
context 'for a simple (untyped) hash' do
|
455
455
|
it 'returns the untouched hash value' do
|
456
|
-
expect(type.dump(value, opts)).to eq(value)
|
456
|
+
expect(type.dump(value, **opts)).to eq(value)
|
457
457
|
end
|
458
458
|
end
|
459
459
|
|
@@ -475,7 +475,7 @@ describe Attributor::Hash do
|
|
475
475
|
let(:type) { Attributor::Hash.of(key: String, value: subtype) }
|
476
476
|
|
477
477
|
it 'returns a hash with the dumped values and keys' do
|
478
|
-
dumped_value = type.dump(value, opts)
|
478
|
+
dumped_value = type.dump(value, **opts)
|
479
479
|
expect(dumped_value).to be_kind_of(::Hash)
|
480
480
|
expect(dumped_value.keys).to match_array %w(id1 id2)
|
481
481
|
expect(dumped_value.values).to have(2).items
|
@@ -487,7 +487,7 @@ describe Attributor::Hash do
|
|
487
487
|
let(:value) { { id1: nil, id2: subtype.new(value2) } }
|
488
488
|
|
489
489
|
it 'correctly returns nil rather than trying to dump their contents' do
|
490
|
-
dumped_value = type.dump(value, opts)
|
490
|
+
dumped_value = type.dump(value, **opts)
|
491
491
|
expect(dumped_value).to be_kind_of(::Hash)
|
492
492
|
expect(dumped_value.keys).to match_array %w(id1 id2)
|
493
493
|
expect(dumped_value['id1']).to be nil
|
@@ -706,7 +706,7 @@ describe Attributor::Hash do
|
|
706
706
|
expect(ex.keys).to match([:req1, :req2, :exc3, :least1, :least2, :most1])
|
707
707
|
end
|
708
708
|
it 'it favors picking attributes with data' do
|
709
|
-
ex = type.example(nil,
|
709
|
+
ex = type.example(nil,most2: "data")
|
710
710
|
expect(ex.keys).to match([:req1, :req2, :exc3, :least1, :least2, :most2])
|
711
711
|
end
|
712
712
|
end
|
@@ -1150,10 +1150,10 @@ describe Attributor::Hash do
|
|
1150
1150
|
let(:hash_of_strings) { Attributor::Hash.of(key: String) }
|
1151
1151
|
let(:hash_of_symbols) { Attributor::Hash.of(key: Symbol) }
|
1152
1152
|
|
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) }
|
1153
|
+
let(:merger) { hash_of_strings.load({'a' => 1},nil) }
|
1154
|
+
let(:good_mergee) { hash_of_strings.load({'b' => 2},nil) }
|
1155
|
+
let(:bad_mergee) { hash_of_symbols.load({c: 3}) }
|
1156
|
+
let(:result) { hash_of_strings.load({'a' => 1, 'b' => 2},nil) }
|
1157
1157
|
|
1158
1158
|
it 'validates that the mergee is of like type' do
|
1159
1159
|
expect { merger.merge(bad_mergee) }.to raise_error(ArgumentError)
|
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
|
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
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attributor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: '5.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josep M. Blanquer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-04-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hashie
|
@@ -85,16 +85,16 @@ dependencies:
|
|
85
85
|
name: rspec-collection_matchers
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
87
87
|
requirements:
|
88
|
-
- - "
|
88
|
+
- - ">="
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version: '
|
90
|
+
version: '0'
|
91
91
|
type: :development
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- - "
|
95
|
+
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
97
|
+
version: '0'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: yard
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -211,42 +211,42 @@ dependencies:
|
|
211
211
|
name: pry
|
212
212
|
requirement: !ruby/object:Gem::Requirement
|
213
213
|
requirements:
|
214
|
-
- - "
|
214
|
+
- - ">="
|
215
215
|
- !ruby/object:Gem::Version
|
216
216
|
version: '0'
|
217
217
|
type: :development
|
218
218
|
prerelease: false
|
219
219
|
version_requirements: !ruby/object:Gem::Requirement
|
220
220
|
requirements:
|
221
|
-
- - "
|
221
|
+
- - ">="
|
222
222
|
- !ruby/object:Gem::Version
|
223
223
|
version: '0'
|
224
224
|
- !ruby/object:Gem::Dependency
|
225
225
|
name: pry-byebug
|
226
226
|
requirement: !ruby/object:Gem::Requirement
|
227
227
|
requirements:
|
228
|
-
- - "
|
228
|
+
- - ">="
|
229
229
|
- !ruby/object:Gem::Version
|
230
|
-
version: '
|
230
|
+
version: '0'
|
231
231
|
type: :development
|
232
232
|
prerelease: false
|
233
233
|
version_requirements: !ruby/object:Gem::Requirement
|
234
234
|
requirements:
|
235
|
-
- - "
|
235
|
+
- - ">="
|
236
236
|
- !ruby/object:Gem::Version
|
237
|
-
version: '
|
237
|
+
version: '0'
|
238
238
|
- !ruby/object:Gem::Dependency
|
239
239
|
name: pry-stack_explorer
|
240
240
|
requirement: !ruby/object:Gem::Requirement
|
241
241
|
requirements:
|
242
|
-
- - "
|
242
|
+
- - ">="
|
243
243
|
- !ruby/object:Gem::Version
|
244
244
|
version: '0'
|
245
245
|
type: :development
|
246
246
|
prerelease: false
|
247
247
|
version_requirements: !ruby/object:Gem::Requirement
|
248
248
|
requirements:
|
249
|
-
- - "
|
249
|
+
- - ">="
|
250
250
|
- !ruby/object:Gem::Version
|
251
251
|
version: '0'
|
252
252
|
- !ruby/object:Gem::Dependency
|
@@ -420,8 +420,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
420
420
|
- !ruby/object:Gem::Version
|
421
421
|
version: '0'
|
422
422
|
requirements: []
|
423
|
-
|
424
|
-
rubygems_version: 2.6.14
|
423
|
+
rubygems_version: 3.0.3
|
425
424
|
signing_key:
|
426
425
|
specification_version: 4
|
427
426
|
summary: A powerful attribute and type management library for Ruby
|