attributor 5.0.1 → 5.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/attributor.rb +2 -0
- data/lib/attributor/dumpable.rb +11 -0
- data/lib/attributor/hash_dsl_compiler.rb +9 -8
- data/lib/attributor/types/collection.rb +1 -0
- data/lib/attributor/types/hash.rb +17 -10
- data/lib/attributor/types/model.rb +13 -6
- data/lib/attributor/version.rb +1 -1
- data/spec/dumpable_spec.rb +30 -0
- data/spec/hash_dsl_compiler_spec.rb +6 -6
- data/spec/types/bigdecimal_spec.rb +7 -3
- data/spec/types/boolean_spec.rb +4 -0
- data/spec/types/class_spec.rb +4 -0
- data/spec/types/collection_spec.rb +4 -0
- data/spec/types/date_spec.rb +9 -5
- data/spec/types/date_time_spec.rb +9 -5
- data/spec/types/float_spec.rb +4 -0
- data/spec/types/hash_spec.rb +4 -0
- data/spec/types/integer_spec.rb +4 -0
- data/spec/types/regexp_spec.rb +4 -0
- data/spec/types/string_spec.rb +4 -0
- data/spec/types/time_spec.rb +9 -5
- data/spec/types/uri_spec.rb +4 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b19e77ce8b1772454840886e1a1bda5bc248c63
|
4
|
+
data.tar.gz: 32f9bca389ef6c112a7d8edf81cf8adc001ca2fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc0fadeddc769124b2b60e717c48d435d88caf15cb6779b0784840c0bdcbbb4efce092fe4648dc8fd14a7b18958c0142dc8e6b52318b44f0b80b0c6f516e4a92
|
7
|
+
data.tar.gz: 6bfe838ad696d85db73ee1893a1d4f7739958180cb4f0f1a35ca5e8ff5ebb1a11bdde7bd10c23645623390cde56a6b95e72321ec819579068bac7b56037281c6
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
## next
|
4
4
|
|
5
|
+
## 5.0.2
|
6
|
+
|
7
|
+
* Introduce the `Dumpable` (empty) module as an interface to indicate that instances of types that include it
|
8
|
+
will respond to the `.dump` method, as a way to convert their internal substructure to primitive Ruby objects. * 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...)
|
9
|
+
* The rest of types have `native_types` that are already Ruby primitive Objects.
|
10
|
+
* Fixed Hash and Model requirements to treat nil values as missing keys (to be compatible with the `required: true` option on an attribute).
|
11
|
+
|
5
12
|
## 5.0.1
|
6
13
|
|
7
14
|
* Fix bug that made Struct/Models skip validation of requirements using the `requires` DSL
|
data/lib/attributor.rb
CHANGED
@@ -0,0 +1,11 @@
|
|
1
|
+
module Attributor
|
2
|
+
module Dumpable
|
3
|
+
# Interface denoting that instances of such type respond to .dump as a way to properly
|
4
|
+
# serialize its contents into primitive ruby objects.
|
5
|
+
# This typically corresponds to non-trivial types that have some sort of substructure
|
6
|
+
def dump
|
7
|
+
raise NotImplementedError, 'Dumpable requires the implementation of #dump'
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
@@ -25,40 +25,41 @@ module Attributor
|
|
25
25
|
@number = spec[type]
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
|
+
def of(*args)
|
29
30
|
@attr_names = args
|
30
31
|
self
|
31
32
|
end
|
32
33
|
|
33
|
-
def validate(
|
34
|
+
def validate(keys,context=Attributor::DEFAULT_ROOT_CONTEXT,_attribute=nil)
|
34
35
|
result = []
|
35
36
|
case type
|
36
37
|
when :all
|
37
|
-
rest = attr_names -
|
38
|
+
rest = attr_names - keys
|
38
39
|
unless rest.empty?
|
39
40
|
rest.each do |attr|
|
40
41
|
result.push "Key #{attr} is required for #{Attributor.humanize_context(context)}."
|
41
42
|
end
|
42
43
|
end
|
43
44
|
when :exactly
|
44
|
-
included = attr_names &
|
45
|
+
included = attr_names & keys
|
45
46
|
unless included.size == number
|
46
47
|
result.push "Exactly #{number} of the following keys #{attr_names} are required for #{Attributor.humanize_context(context)}. Found #{included.size} instead: #{included.inspect}"
|
47
48
|
end
|
48
49
|
when :at_most
|
49
|
-
rest = attr_names &
|
50
|
+
rest = attr_names & keys
|
50
51
|
if rest.size > number
|
51
52
|
found = rest.empty? ? "none" : rest.inspect
|
52
53
|
result.push "At most #{number} keys out of #{attr_names} can be passed in for #{Attributor.humanize_context(context)}. Found #{found}"
|
53
54
|
end
|
54
55
|
when :at_least
|
55
|
-
rest = attr_names &
|
56
|
+
rest = attr_names & keys
|
56
57
|
if rest.size < number
|
57
58
|
found = rest.empty? ? "none" : rest.inspect
|
58
59
|
result.push "At least #{number} keys out of #{attr_names} are required to be passed in for #{Attributor.humanize_context(context)}. Found #{found}"
|
59
60
|
end
|
60
61
|
when :exclusive
|
61
|
-
intersection = attr_names &
|
62
|
+
intersection = attr_names & keys
|
62
63
|
if intersection.size > 1
|
63
64
|
result.push "keys #{intersection.inspect} are mutually exclusive for #{Attributor.humanize_context(context)}."
|
64
65
|
end
|
@@ -138,4 +139,4 @@ module Attributor
|
|
138
139
|
|
139
140
|
|
140
141
|
end
|
141
|
-
end
|
142
|
+
end
|
@@ -22,6 +22,7 @@ module Attributor
|
|
22
22
|
|
23
23
|
include Container
|
24
24
|
include Enumerable
|
25
|
+
include Dumpable
|
25
26
|
|
26
27
|
class << self
|
27
28
|
attr_reader :key_type, :value_type, :options
|
@@ -556,6 +557,7 @@ module Attributor
|
|
556
557
|
|
557
558
|
def validate(context=Attributor::DEFAULT_ROOT_CONTEXT)
|
558
559
|
context = [context] if context.is_a? ::String
|
560
|
+
errors = []
|
559
561
|
|
560
562
|
if self.class.keys.any?
|
561
563
|
extra_keys = @contents.keys - self.class.keys.keys
|
@@ -565,36 +567,41 @@ module Attributor
|
|
565
567
|
end
|
566
568
|
end
|
567
569
|
|
568
|
-
|
570
|
+
keys_with_values = Array.new
|
571
|
+
|
572
|
+
self.class.keys.each do |key, attribute|
|
569
573
|
sub_context = self.class.generate_subcontext(context,key)
|
570
574
|
|
571
575
|
value = @contents[key]
|
576
|
+
unless value.nil?
|
577
|
+
keys_with_values << key
|
578
|
+
end
|
572
579
|
|
573
580
|
if value.respond_to?(:validating) # really, it's a thing with sub-attributes
|
574
581
|
next if value.validating
|
575
582
|
end
|
576
583
|
|
577
|
-
errors.push
|
584
|
+
errors.push(*attribute.validate(value, sub_context))
|
585
|
+
end
|
586
|
+
self.class.requirements.each do |req|
|
587
|
+
validation_errors = req.validate(keys_with_values, context)
|
588
|
+
errors.push(*validation_errors) unless validation_errors.empty?
|
578
589
|
end
|
579
590
|
else
|
580
|
-
|
591
|
+
@contents.each do |key, value|
|
581
592
|
# FIXME: the sub contexts and error messages don't really make sense here
|
582
593
|
unless key_type == Attributor::Object
|
583
594
|
sub_context = context + ["key(#{key.inspect})"]
|
584
|
-
errors.push
|
595
|
+
errors.push(*key_attribute.validate(key, sub_context))
|
585
596
|
end
|
586
597
|
|
587
598
|
unless value_type == Attributor::Object
|
588
599
|
sub_context = context + ["value(#{value.inspect})"]
|
589
|
-
errors.push
|
600
|
+
errors.push(*value_attribute.validate(value, sub_context))
|
590
601
|
end
|
591
602
|
end
|
592
603
|
end
|
593
|
-
|
594
|
-
validation_errors = req.validate( @contents , context)
|
595
|
-
errors.push *validation_errors unless validation_errors.empty?
|
596
|
-
end
|
597
|
-
ret
|
604
|
+
errors
|
598
605
|
end
|
599
606
|
|
600
607
|
|
@@ -130,22 +130,29 @@ module Attributor
|
|
130
130
|
@validating = true
|
131
131
|
|
132
132
|
context = [context] if context.is_a? ::String
|
133
|
+
keys_with_values = []
|
134
|
+
errors = []
|
133
135
|
|
134
|
-
|
136
|
+
self.class.attributes.each do |sub_attribute_name, sub_attribute|
|
135
137
|
sub_context = self.class.generate_subcontext(context,sub_attribute_name)
|
136
138
|
|
137
139
|
value = self.__send__(sub_attribute_name)
|
140
|
+
unless value.nil?
|
141
|
+
keys_with_values << sub_attribute_name
|
142
|
+
end
|
143
|
+
|
138
144
|
if value.respond_to?(:validating) # really, it's a thing with sub-attributes
|
139
145
|
next if value.validating
|
140
146
|
end
|
141
147
|
|
142
|
-
errors.push
|
148
|
+
errors.push(*sub_attribute.validate(value, sub_context))
|
143
149
|
end
|
144
|
-
self.class.requirements.
|
145
|
-
validation_errors = req.validate(
|
146
|
-
errors.push
|
150
|
+
self.class.requirements.each do |req|
|
151
|
+
validation_errors = req.validate(keys_with_values, context)
|
152
|
+
errors.push(*validation_errors) unless validation_errors.empty?
|
147
153
|
end
|
148
|
-
|
154
|
+
|
155
|
+
errors
|
149
156
|
ensure
|
150
157
|
@validating = false
|
151
158
|
end
|
data/lib/attributor/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper.rb')
|
2
|
+
|
3
|
+
describe 'Dumpable' do
|
4
|
+
|
5
|
+
context 'for classes forgetting to implement #dump' do
|
6
|
+
let(:type) {
|
7
|
+
Class.new do
|
8
|
+
include Attributor::Dumpable
|
9
|
+
end
|
10
|
+
}
|
11
|
+
|
12
|
+
it 'gets an exception' do
|
13
|
+
expect{ type.new.dump }.to raise_exception(NotImplementedError)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'for classes properly implementing #dump' do
|
18
|
+
let(:type) {
|
19
|
+
Class.new do
|
20
|
+
include Attributor::Dumpable
|
21
|
+
def dump
|
22
|
+
end
|
23
|
+
end
|
24
|
+
}
|
25
|
+
|
26
|
+
it 'do not get the base exception' do
|
27
|
+
expect{ type.new.dump }.to_not raise_exception
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -116,31 +116,31 @@ describe Attributor::HashDSLCompiler do
|
|
116
116
|
|
117
117
|
context 'for :all' do
|
118
118
|
let(:arguments){ { all: [:one, :two, :three] } }
|
119
|
-
let(:value){
|
119
|
+
let(:value){ [:one] }
|
120
120
|
let(:validation_error){ ["Key two is required for $.", "Key three is required for $."] }
|
121
121
|
it { subject.should include(*validation_error) }
|
122
122
|
end
|
123
123
|
context 'for :exactly' do
|
124
124
|
let(:requirement) { req_class.new(exactly: 1).of(:one,:two) }
|
125
|
-
let(:value){
|
125
|
+
let(:value){ [:one, :two] }
|
126
126
|
let(:validation_error){ "Exactly 1 of the following keys [:one, :two] are required for $. Found 2 instead: [:one, :two]" }
|
127
127
|
it { subject.should include(validation_error) }
|
128
128
|
end
|
129
129
|
context 'for :at_least' do
|
130
130
|
let(:requirement) { req_class.new(at_least: 2).of(:one,:two,:three) }
|
131
|
-
let(:value){
|
131
|
+
let(:value){ [:one] }
|
132
132
|
let(:validation_error){ "At least 2 keys out of [:one, :two, :three] are required to be passed in for $. Found [:one]" }
|
133
133
|
it { subject.should include(validation_error) }
|
134
134
|
end
|
135
135
|
context 'for :at_most' do
|
136
136
|
let(:requirement) { req_class.new(at_most: 1).of(:one,:two,:three) }
|
137
|
-
let(:value){
|
137
|
+
let(:value){ [:one, :two] }
|
138
138
|
let(:validation_error){ "At most 1 keys out of [:one, :two, :three] can be passed in for $. Found [:one, :two]" }
|
139
139
|
it { subject.should include(validation_error) }
|
140
140
|
end
|
141
141
|
context 'for :exclusive' do
|
142
142
|
let(:arguments){ { exclusive: [:one, :two] } }
|
143
|
-
let(:value){
|
143
|
+
let(:value){ [:one, :two] }
|
144
144
|
let(:validation_error){ "keys [:one, :two] are mutually exclusive for $." }
|
145
145
|
it { subject.should include(validation_error) }
|
146
146
|
end
|
@@ -174,4 +174,4 @@ describe Attributor::HashDSLCompiler do
|
|
174
174
|
end
|
175
175
|
end
|
176
176
|
end
|
177
|
-
end
|
177
|
+
end
|
@@ -3,13 +3,17 @@ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
|
|
3
3
|
describe Attributor::BigDecimal do
|
4
4
|
subject(:type) { Attributor::BigDecimal }
|
5
5
|
|
6
|
+
it 'it is not Dumpable' do
|
7
|
+
type.new.is_a?(Attributor::Dumpable).should_not be(true)
|
8
|
+
end
|
9
|
+
|
6
10
|
context '.native_type' do
|
7
11
|
its(:native_type) { should be(::BigDecimal) }
|
8
12
|
end
|
9
13
|
|
10
14
|
context '.example' do
|
11
15
|
its(:example) { should be_a(::BigDecimal) }
|
12
|
-
it do
|
16
|
+
it do
|
13
17
|
ex = type.example
|
14
18
|
end
|
15
19
|
end
|
@@ -19,7 +23,7 @@ describe Attributor::BigDecimal do
|
|
19
23
|
it 'returns nil for nil' do
|
20
24
|
type.load(nil).should be(nil)
|
21
25
|
end
|
22
|
-
|
26
|
+
|
23
27
|
context 'for incoming Float values' do
|
24
28
|
it 'returns the incoming value' do
|
25
29
|
[0.0, -1.0, 1.0, 1e-10, 0.25135].each do |value|
|
@@ -36,7 +40,7 @@ describe Attributor::BigDecimal do
|
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
39
|
-
context 'for incoming String values' do
|
43
|
+
context 'for incoming String values' do
|
40
44
|
it 'should equal the value' do
|
41
45
|
type.load('0').should eq(0)
|
42
46
|
type.load('100').should eq(100)
|
data/spec/types/boolean_spec.rb
CHANGED
data/spec/types/class_spec.rb
CHANGED
@@ -341,6 +341,10 @@ describe Attributor::Collection do
|
|
341
341
|
context 'dumping' do
|
342
342
|
let(:type) { Attributor::Collection.of(Cormorant) }
|
343
343
|
|
344
|
+
it 'it is Dumpable' do
|
345
|
+
type.new.is_a?(Attributor::Dumpable).should be(true)
|
346
|
+
end
|
347
|
+
|
344
348
|
subject(:example) { type.example }
|
345
349
|
it 'dumps' do
|
346
350
|
expect {
|
data/spec/types/date_spec.rb
CHANGED
@@ -4,6 +4,10 @@ describe Attributor::Date do
|
|
4
4
|
|
5
5
|
subject(:type) { Attributor::Date }
|
6
6
|
|
7
|
+
it 'it is not Dumpable' do
|
8
|
+
type.new.is_a?(Attributor::Dumpable).should_not be(true)
|
9
|
+
end
|
10
|
+
|
7
11
|
context '.native_type' do
|
8
12
|
its(:native_type) { should be(::Date) }
|
9
13
|
end
|
@@ -20,7 +24,7 @@ describe Attributor::Date do
|
|
20
24
|
end
|
21
25
|
context 'nil values' do
|
22
26
|
it 'should be nil' do
|
23
|
-
type.dump(nil).should be_nil
|
27
|
+
type.dump(nil).should be_nil
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -33,14 +37,14 @@ describe Attributor::Date do
|
|
33
37
|
end
|
34
38
|
|
35
39
|
context 'for incoming objects' do
|
36
|
-
|
40
|
+
|
37
41
|
it "returns correct Date for Time objects" do
|
38
42
|
object = Time.now
|
39
43
|
loaded = type.load(object)
|
40
44
|
loaded.should be_a(::Date)
|
41
45
|
loaded.to_date.should == object.to_date
|
42
46
|
end
|
43
|
-
|
47
|
+
|
44
48
|
it "returns correct Date for DateTime objects" do
|
45
49
|
object = DateTime.now
|
46
50
|
loaded = type.load(object)
|
@@ -48,8 +52,8 @@ describe Attributor::Date do
|
|
48
52
|
loaded.should be(object)
|
49
53
|
end
|
50
54
|
|
51
|
-
end
|
52
|
-
|
55
|
+
end
|
56
|
+
|
53
57
|
context 'for incoming strings' do
|
54
58
|
|
55
59
|
[
|
@@ -4,6 +4,10 @@ describe Attributor::DateTime do
|
|
4
4
|
|
5
5
|
subject(:type) { Attributor::DateTime }
|
6
6
|
|
7
|
+
it 'it is not Dumpable' do
|
8
|
+
type.new.is_a?(Attributor::Dumpable).should_not be(true)
|
9
|
+
end
|
10
|
+
|
7
11
|
context '.native_type' do
|
8
12
|
its(:native_type) { should be(::DateTime) }
|
9
13
|
end
|
@@ -20,7 +24,7 @@ describe Attributor::DateTime do
|
|
20
24
|
end
|
21
25
|
context 'nil values' do
|
22
26
|
it 'should be nil' do
|
23
|
-
type.dump(nil).should be_nil
|
27
|
+
type.dump(nil).should be_nil
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -33,14 +37,14 @@ describe Attributor::DateTime do
|
|
33
37
|
end
|
34
38
|
|
35
39
|
context 'for incoming objects' do
|
36
|
-
|
40
|
+
|
37
41
|
it "returns correct DateTime for Time objects" do
|
38
42
|
object = Time.now
|
39
43
|
loaded = type.load(object)
|
40
44
|
loaded.should be_a(::DateTime)
|
41
45
|
loaded.to_time.should == object
|
42
46
|
end
|
43
|
-
|
47
|
+
|
44
48
|
it "returns correct DateTime for DateTime objects" do
|
45
49
|
object = DateTime.now
|
46
50
|
loaded = type.load(object)
|
@@ -48,8 +52,8 @@ describe Attributor::DateTime do
|
|
48
52
|
loaded.should be( object )
|
49
53
|
end
|
50
54
|
|
51
|
-
end
|
52
|
-
|
55
|
+
end
|
56
|
+
|
53
57
|
context 'for incoming strings' do
|
54
58
|
|
55
59
|
[
|
data/spec/types/float_spec.rb
CHANGED
data/spec/types/hash_spec.rb
CHANGED
@@ -439,6 +439,10 @@ describe Attributor::Hash do
|
|
439
439
|
let(:value) { {one: 1, two: 2} }
|
440
440
|
let(:opts) { {} }
|
441
441
|
|
442
|
+
it 'it is Dumpable' do
|
443
|
+
type.new.is_a?(Attributor::Dumpable).should be(true)
|
444
|
+
end
|
445
|
+
|
442
446
|
context 'for a simple (untyped) hash' do
|
443
447
|
it 'returns the untouched hash value' do
|
444
448
|
type.dump(value, opts).should eq(value)
|
data/spec/types/integer_spec.rb
CHANGED
data/spec/types/regexp_spec.rb
CHANGED
@@ -4,6 +4,10 @@ describe Attributor::Regexp do
|
|
4
4
|
|
5
5
|
subject(:type) { Attributor::Regexp }
|
6
6
|
|
7
|
+
it 'it is not Dumpable' do
|
8
|
+
type.new.is_a?(Attributor::Dumpable).should_not be(true)
|
9
|
+
end
|
10
|
+
|
7
11
|
its(:native_type) { should be(::Regexp) }
|
8
12
|
its(:example) { should be_a(::String) }
|
9
13
|
its(:family) { should == 'string' }
|
data/spec/types/string_spec.rb
CHANGED
@@ -4,6 +4,10 @@ describe Attributor::String do
|
|
4
4
|
|
5
5
|
subject(:type) { Attributor::String }
|
6
6
|
|
7
|
+
it 'it is not Dumpable' do
|
8
|
+
type.new.is_a?(Attributor::Dumpable).should_not be(true)
|
9
|
+
end
|
10
|
+
|
7
11
|
context '.native_type' do
|
8
12
|
it "returns String" do
|
9
13
|
type.native_type.should be(::String)
|
data/spec/types/time_spec.rb
CHANGED
@@ -4,6 +4,10 @@ describe Attributor::Time do
|
|
4
4
|
|
5
5
|
subject(:type) { Attributor::Time }
|
6
6
|
|
7
|
+
it 'it is not Dumpable' do
|
8
|
+
type.new.is_a?(Attributor::Dumpable).should_not be(true)
|
9
|
+
end
|
10
|
+
|
7
11
|
context '.native_type' do
|
8
12
|
its(:native_type) { should be(::Time) }
|
9
13
|
end
|
@@ -20,7 +24,7 @@ describe Attributor::Time do
|
|
20
24
|
end
|
21
25
|
context 'nil values' do
|
22
26
|
it 'should be nil' do
|
23
|
-
type.dump(nil).should be_nil
|
27
|
+
type.dump(nil).should be_nil
|
24
28
|
end
|
25
29
|
end
|
26
30
|
end
|
@@ -33,14 +37,14 @@ describe Attributor::Time do
|
|
33
37
|
end
|
34
38
|
|
35
39
|
context 'for incoming objects' do
|
36
|
-
|
40
|
+
|
37
41
|
it "returns correct Time for DateTime objects" do
|
38
42
|
object = Time.now
|
39
43
|
loaded = type.load(object)
|
40
44
|
loaded.should be_a(::Time)
|
41
45
|
loaded.to_time.should == object
|
42
46
|
end
|
43
|
-
|
47
|
+
|
44
48
|
it "returns correct Time for DateTime objects" do
|
45
49
|
object = DateTime.now
|
46
50
|
loaded = type.load(object)
|
@@ -48,8 +52,8 @@ describe Attributor::Time do
|
|
48
52
|
loaded.should eq(object.to_time)
|
49
53
|
end
|
50
54
|
|
51
|
-
end
|
52
|
-
|
55
|
+
end
|
56
|
+
|
53
57
|
context 'for incoming strings' do
|
54
58
|
|
55
59
|
[
|
data/spec/types/uri_spec.rb
CHANGED
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.0.
|
4
|
+
version: 5.0.2
|
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: 2016-02-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hashie
|
@@ -285,6 +285,7 @@ files:
|
|
285
285
|
- lib/attributor/attribute.rb
|
286
286
|
- lib/attributor/attribute_resolver.rb
|
287
287
|
- lib/attributor/dsl_compiler.rb
|
288
|
+
- lib/attributor/dumpable.rb
|
288
289
|
- lib/attributor/example_mixin.rb
|
289
290
|
- lib/attributor/exceptions.rb
|
290
291
|
- lib/attributor/extensions/randexp.rb
|
@@ -322,6 +323,7 @@ files:
|
|
322
323
|
- spec/attribute_spec.rb
|
323
324
|
- spec/attributor_spec.rb
|
324
325
|
- spec/dsl_compiler_spec.rb
|
326
|
+
- spec/dumpable_spec.rb
|
325
327
|
- spec/extras/field_selector/field_selector_spec.rb
|
326
328
|
- spec/families_spec.rb
|
327
329
|
- spec/hash_dsl_compiler_spec.rb
|
@@ -369,7 +371,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
369
371
|
version: '0'
|
370
372
|
requirements: []
|
371
373
|
rubyforge_project:
|
372
|
-
rubygems_version: 2.4.5
|
374
|
+
rubygems_version: 2.4.5
|
373
375
|
signing_key:
|
374
376
|
specification_version: 4
|
375
377
|
summary: A powerful attribute and type management library for Ruby
|
@@ -378,6 +380,7 @@ test_files:
|
|
378
380
|
- spec/attribute_spec.rb
|
379
381
|
- spec/attributor_spec.rb
|
380
382
|
- spec/dsl_compiler_spec.rb
|
383
|
+
- spec/dumpable_spec.rb
|
381
384
|
- spec/extras/field_selector/field_selector_spec.rb
|
382
385
|
- spec/families_spec.rb
|
383
386
|
- spec/hash_dsl_compiler_spec.rb
|