lego 0.0.4 → 0.0.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.
- data/lego.gemspec +1 -1
- data/lib/lego/model.rb +87 -25
- data/lib/lego/value.rb +2 -0
- data/lib/lego/value/base.rb +11 -11
- data/spec/lego/model_spec.rb +109 -25
- data/spec/lego/value/array_spec.rb +4 -3
- data/spec/lego/value/base_spec.rb +10 -2
- data/spec/lego/value/boolean_spec.rb +4 -2
- data/spec/lego/value/date_spec.rb +4 -2
- data/spec/lego/value/float_spec.rb +4 -2
- data/spec/lego/value/integer_spec.rb +4 -2
- data/spec/lego/value/set_spec.rb +6 -4
- data/spec/lego/value/string_spec.rb +8 -7
- metadata +4 -4
data/lego.gemspec
CHANGED
data/lib/lego/model.rb
CHANGED
@@ -2,6 +2,17 @@ require 'active_support/core_ext/hash/deep_merge'
|
|
2
2
|
|
3
3
|
module Lego
|
4
4
|
class Model
|
5
|
+
class ParseError < StandardError
|
6
|
+
def initialize(errors={})
|
7
|
+
@errors = errors
|
8
|
+
super(errors.inspect)
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :errors
|
12
|
+
end
|
13
|
+
|
14
|
+
private_class_method :new
|
15
|
+
|
5
16
|
class << self
|
6
17
|
|
7
18
|
def attribute(attr, type, *args)
|
@@ -12,48 +23,99 @@ module Lego
|
|
12
23
|
@_parsers ||= {}
|
13
24
|
end
|
14
25
|
|
26
|
+
def validations
|
27
|
+
@_validations ||= Hash.new { |h,k| h[k] = [] }
|
28
|
+
end
|
29
|
+
|
15
30
|
def attribute_names
|
16
31
|
parsers.keys
|
17
32
|
end
|
18
|
-
end
|
19
33
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
34
|
+
def validates(attr, callable=nil, &block)
|
35
|
+
attr = attr.to_sym
|
36
|
+
if callable && callable.is_a?(Symbol)
|
37
|
+
validations[attr] << callable
|
38
|
+
else
|
39
|
+
validations[attr] << block
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def coerce(hash)
|
44
|
+
res = parse(hash)
|
45
|
+
res.value? ? res.value : fail(ParseError.new(res.error))
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse(hash)
|
49
|
+
return Lego.just(hash) if hash.instance_of?(self)
|
50
|
+
|
51
|
+
fail ArgumentError, "attrs must be hash: '#{hash.inspect}'" unless hash.respond_to?(:key?)
|
52
|
+
|
53
|
+
result = _parse(hash)
|
54
|
+
|
55
|
+
if result.value?
|
56
|
+
model = new(result.value)
|
57
|
+
_validate(model)
|
58
|
+
else
|
59
|
+
result
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def _validate(obj)
|
64
|
+
attrs = {}
|
65
|
+
validations.each do |name, attr_validations|
|
66
|
+
attrs[name] = Lego.just(obj)
|
67
|
+
attr_validations.each do |validation|
|
68
|
+
if validation.is_a?(Symbol)
|
69
|
+
callable_method_name = validation.to_sym
|
70
|
+
validation = ->(o){ o.method(callable_method_name).call }
|
71
|
+
end
|
72
|
+
attrs[name] = attrs[name].next(validation)
|
31
73
|
end
|
32
74
|
end
|
33
|
-
|
34
|
-
|
75
|
+
|
76
|
+
if attrs.all?{ |k,v| v.value? }
|
77
|
+
Lego.just(obj)
|
78
|
+
else
|
79
|
+
Lego.fail(Hash[*attrs.map{ |k,v| [k, v.error] if v.error? }.compact.flatten(1)])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def _parse(data)
|
84
|
+
data = data.dup
|
85
|
+
|
86
|
+
attrs = {}
|
87
|
+
|
88
|
+
parsers.each do |name, parser|
|
89
|
+
name = name.to_sym
|
90
|
+
value = data.key?(name) ? data.delete(name) : data.delete(name.to_s)
|
91
|
+
|
92
|
+
attrs[name] = parser.parse(value)
|
93
|
+
end
|
94
|
+
|
95
|
+
fail ArgumentError, "Unknown attributes: #{data}" unless data.empty?
|
96
|
+
|
97
|
+
if attrs.all?{ |k,v| v.value? }
|
98
|
+
Lego.just(Hash[*attrs.map{ |k,v| [k, v.value] }.flatten(1)])
|
99
|
+
else
|
100
|
+
Lego.fail(Hash[*attrs.map{ |k,v| [k, v.error] if v.error? }.compact.flatten(1)])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def initialize(attrs={})
|
106
|
+
@attributes = attrs.freeze
|
35
107
|
end
|
36
108
|
|
37
109
|
attr_reader :attributes
|
38
110
|
|
39
111
|
def merge(other)
|
40
|
-
self.class.
|
112
|
+
self.class.coerce(as_json.deep_merge(other))
|
41
113
|
end
|
42
114
|
|
43
115
|
def method_missing(name, *args, &block)
|
44
116
|
attributes.fetch(name.to_sym) { super }
|
45
117
|
end
|
46
118
|
|
47
|
-
def self.coerce(hash)
|
48
|
-
hash.instance_of?(self) ? hash : self.new(hash)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.parse(hash)
|
52
|
-
Lego.just(self.coerce(hash))
|
53
|
-
rescue Lego::CoerceError => e
|
54
|
-
Lego.fail(e.message)
|
55
|
-
end
|
56
|
-
|
57
119
|
# Equality
|
58
120
|
|
59
121
|
def ==(o)
|
data/lib/lego/value.rb
CHANGED
data/lib/lego/value/base.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Lego::Value
|
2
2
|
class Base
|
3
|
+
|
3
4
|
def initialize(opts={})
|
4
5
|
@opts = opts
|
5
6
|
end
|
@@ -10,22 +11,21 @@ module Lego::Value
|
|
10
11
|
parsers.each do |callable|
|
11
12
|
val = val.next(callable)
|
12
13
|
end
|
13
|
-
val
|
14
|
-
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
if
|
19
|
-
|
20
|
-
elsif resp.error?
|
21
|
-
raise Lego::CoerceError, resp.error
|
22
|
-
elsif @opts[:default]
|
23
|
-
@opts[:default].call
|
15
|
+
return val unless val.none?
|
16
|
+
|
17
|
+
if @opts[:default]
|
18
|
+
Lego.just(@opts[:default].call)
|
24
19
|
else
|
25
|
-
|
20
|
+
Lego.fail('missing value')
|
26
21
|
end
|
27
22
|
end
|
28
23
|
|
24
|
+
def coerce(val)
|
25
|
+
res = parse(val)
|
26
|
+
res.value? ? res.value : fail(Lego::CoerceError, res.error)
|
27
|
+
end
|
28
|
+
|
29
29
|
def parsers
|
30
30
|
[]
|
31
31
|
end
|
data/spec/lego/model_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'date'
|
2
3
|
|
3
4
|
describe Lego::Model do
|
4
5
|
|
@@ -14,7 +15,7 @@ describe Lego::Model do
|
|
14
15
|
|
15
16
|
context 'Person' do
|
16
17
|
subject do
|
17
|
-
Person.
|
18
|
+
Person.coerce(name: 'Alice', age: '10')
|
18
19
|
end
|
19
20
|
|
20
21
|
it '::attributes' do
|
@@ -30,72 +31,80 @@ describe Lego::Model do
|
|
30
31
|
end
|
31
32
|
|
32
33
|
it 'raises error on unknown attribute' do
|
33
|
-
expect{ Person.
|
34
|
+
expect{ Person.coerce(name: 'Alice', age: '10', grade: 5) }.to raise_error(ArgumentError, "Unknown attributes: {:grade=>5}")
|
34
35
|
end
|
35
36
|
|
36
37
|
it 'fails on validation' do
|
37
|
-
expect{ Person.
|
38
|
-
expect{ Person.
|
38
|
+
expect{ Person.coerce(name: 'Alice') }.to raise_error(Lego::Model::ParseError, '{:age=>"missing value"}')
|
39
|
+
expect{ Person.coerce(name: 'Alice', age: Date.today) }.to raise_error(Lego::Model::ParseError, /invalid integer/)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'stores errors as hash' do
|
43
|
+
begin
|
44
|
+
Person.coerce(name: 'Alice')
|
45
|
+
rescue => e
|
46
|
+
e.errors.should == { age: 'missing value' }
|
47
|
+
end
|
39
48
|
end
|
40
49
|
|
41
50
|
it 'fails on non-hash initialize' do
|
42
|
-
expect{ Person.
|
51
|
+
expect{ Person.coerce(nil) }.to raise_error(ArgumentError, "attrs must be hash: 'nil'")
|
43
52
|
end
|
44
53
|
|
45
54
|
it 'dupes attributes' do
|
46
55
|
h = { name: 'Alice', age: 10 }
|
47
|
-
Person.
|
56
|
+
Person.coerce(h)
|
48
57
|
h.should == { name: 'Alice', age: 10 }
|
49
58
|
end
|
50
59
|
end
|
51
60
|
|
52
61
|
context 'equality' do
|
53
62
|
it '#==' do
|
54
|
-
Person.
|
55
|
-
Person.
|
56
|
-
Person.
|
63
|
+
Person.coerce(name: 'Alice', age: 10).should == Person.coerce(name: 'Alice', age: '10')
|
64
|
+
Person.coerce(name: 'Alice', age: 10).should_not == Person.coerce(name: 'Bob', age: '10')
|
65
|
+
Person.coerce(name: 'Alice', age: 10).should_not == Person.coerce(name: 'Alice', age: '12')
|
57
66
|
end
|
58
67
|
|
59
68
|
it '#eql?' do
|
60
|
-
Person.
|
61
|
-
Person.
|
62
|
-
Person.
|
69
|
+
Person.coerce(name: 'Alice', age: 10).should eql Person.coerce(name: 'Alice', age: '10')
|
70
|
+
Person.coerce(name: 'Alice', age: 10).should_not eql Person.coerce(name: 'Bob', age: '10')
|
71
|
+
Person.coerce(name: 'Alice', age: 10).should_not eql Person.coerce(name: 'Alice', age: '12')
|
63
72
|
end
|
64
73
|
|
65
74
|
it '#hash' do
|
66
|
-
Person.
|
67
|
-
Person.
|
68
|
-
Person.
|
75
|
+
Person.coerce(name: 'Alice', age: 10).hash.should == Person.coerce(name: 'Alice', age: '10').hash
|
76
|
+
Person.coerce(name: 'Alice', age: 10).hash.should_not == Person.coerce(name: 'Bob', age: '10').hash
|
77
|
+
Person.coerce(name: 'Alice', age: 10).hash.should_not == Person.coerce(name: 'Alice', age: '12').hash
|
69
78
|
end
|
70
79
|
end
|
71
80
|
|
72
81
|
context 'Family' do
|
73
82
|
it 'creates recursively from hash' do
|
74
|
-
family = Family.
|
83
|
+
family = Family.coerce(last_name: 'Kowalski', father: { name: 'Bob', age: '55' })
|
75
84
|
family.should be_instance_of(Family)
|
76
85
|
family.last_name.should == 'Kowalski'
|
77
|
-
family.father.should == Person.
|
86
|
+
family.father.should == Person.coerce(name: 'Bob', age: '55')
|
78
87
|
end
|
79
88
|
|
80
89
|
it 'creates from partial hash' do
|
81
|
-
family = Family.
|
90
|
+
family = Family.coerce(last_name: 'Kowalski', father: Person.coerce(name: 'Bob', age: '55'))
|
82
91
|
family.should be_instance_of(Family)
|
83
92
|
family.last_name.should == 'Kowalski'
|
84
|
-
family.father.should == Person.
|
93
|
+
family.father.should == Person.coerce(name: 'Bob', age: '55')
|
85
94
|
end
|
86
95
|
|
87
96
|
it 'initializes from string keys' do
|
88
|
-
family = Family.
|
97
|
+
family = Family.coerce('last_name' => 'Kowalski', 'father' => Person.coerce('name' => 'Bob', 'age' => '55'))
|
89
98
|
family.should be_instance_of(Family)
|
90
99
|
family.last_name.should == 'Kowalski'
|
91
|
-
family.father.should == Person.
|
100
|
+
family.father.should == Person.coerce(name: 'Bob', age: '55')
|
92
101
|
end
|
93
102
|
end
|
94
103
|
|
95
104
|
|
96
105
|
describe '#as_json' do
|
97
106
|
it 'serializes Family' do
|
98
|
-
family = Family.
|
107
|
+
family = Family.coerce(last_name: 'Kowalski', father: { name: 'Bob', age: '55' })
|
99
108
|
family.as_json.should == {
|
100
109
|
:last_name => "Kowalski",
|
101
110
|
:father => {
|
@@ -107,7 +116,7 @@ describe Lego::Model do
|
|
107
116
|
end
|
108
117
|
|
109
118
|
describe '#merge' do
|
110
|
-
let(:one) { Family.
|
119
|
+
let(:one) { Family.coerce(last_name: 'Kowalski', father: { name: 'Bob', age: '55' }) }
|
111
120
|
|
112
121
|
it 'returns new object' do
|
113
122
|
two = one.merge({})
|
@@ -118,9 +127,84 @@ describe Lego::Model do
|
|
118
127
|
it 'merges changes' do
|
119
128
|
two = one.merge(last_name: 'Tesla', father: { name: 'Nikola' })
|
120
129
|
|
121
|
-
one.should == Family.
|
122
|
-
two.should == Family.
|
130
|
+
one.should == Family.coerce(last_name: 'Kowalski', father: { name: 'Bob', age: '55' })
|
131
|
+
two.should == Family.coerce(last_name: 'Tesla', father: { name: 'Nikola', age: '55' })
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '::validates' do
|
136
|
+
let(:today) { Date.today }
|
137
|
+
|
138
|
+
it 'runs validations after coercions' do
|
139
|
+
klass = Class.new(Lego::Model) do
|
140
|
+
attribute :start, Date
|
141
|
+
attribute :stop, Date
|
142
|
+
|
143
|
+
validates :start do |o| o.start < o.stop ? Lego.just(o) : Lego.fail('must start before end') end
|
144
|
+
end
|
145
|
+
|
146
|
+
klass.parse(start: today.to_s, stop: today).should be_error({start: 'must start before end'})
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'validates via block' do
|
150
|
+
klass = Class.new(Lego::Model) do
|
151
|
+
attribute :start, Date
|
152
|
+
attribute :stop, Date
|
153
|
+
|
154
|
+
validates :start do |o| o.start < o.stop ? Lego.just(o) : Lego.fail('must start before end') end
|
155
|
+
validates :start do |o| (o.start + 2) < o.stop ? Lego.just(o) : Lego.fail('at least 3 days after') end
|
156
|
+
end
|
157
|
+
|
158
|
+
klass.parse(start: today.to_s, stop: today.to_s).should be_error(start: 'must start before end')
|
159
|
+
klass.parse(start: today.to_s, stop: (today + 2).to_s).should be_error(start: 'at least 3 days after')
|
160
|
+
klass.parse(start: today.to_s, stop: (today + 3).to_s).should be_value
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
it 'validates until first error in each attribute' do
|
165
|
+
klass = Class.new(Lego::Model) do
|
166
|
+
attribute :start, Date
|
167
|
+
attribute :stop, Date
|
168
|
+
|
169
|
+
validates :start do |o| o.start < o.stop ? Lego.just(o) : Lego.fail('must start before end') end
|
170
|
+
validates :start do |o| fail 'Should NOT EXECUTE' end
|
171
|
+
validates :stop do |o| o.stop > o.start + 1 ? Lego.just(o) : Lego.fail('must stop after at least 3 days') end
|
172
|
+
end
|
173
|
+
|
174
|
+
klass.parse(start: today, stop: today).should be_error(start: 'must start before end', stop: 'must stop after at least 3 days')
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
it 'validates via instance method' do
|
179
|
+
klass = Class.new(Lego::Model) do
|
180
|
+
attribute :start, Date
|
181
|
+
attribute :stop, Date
|
182
|
+
|
183
|
+
validates :start, :check_start_before_end
|
184
|
+
validates :start, :check_at_least_3_days
|
185
|
+
|
186
|
+
def check_start_before_end
|
187
|
+
start < stop ? Lego.just(self) : Lego.fail('must start before end')
|
188
|
+
end
|
189
|
+
|
190
|
+
def check_at_least_3_days
|
191
|
+
(start + 2) < stop ? Lego.just(self) : Lego.fail('at least 3 days after')
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
klass.parse(start: today.to_s, stop: today.to_s).should be_error(start: 'must start before end')
|
196
|
+
klass.parse(start: today.to_s, stop: (today + 2).to_s).should be_error(start: 'at least 3 days after')
|
197
|
+
klass.parse(start: today.to_s, stop: (today + 3).to_s).should be_value
|
123
198
|
end
|
124
199
|
end
|
125
200
|
|
201
|
+
it 'correctly handles array values' do
|
202
|
+
klass = Class.new(Lego::Model) do
|
203
|
+
attribute :nums, Array, Integer, length: 2
|
204
|
+
end
|
205
|
+
|
206
|
+
klass.parse(nums: [1,2]).should be_value
|
207
|
+
klass.parse(nums: [1,2,3,4]).should be_error(nums: "length not 2: '[1, 2, 3, 4]'")
|
208
|
+
end
|
209
|
+
|
126
210
|
end
|
@@ -6,7 +6,8 @@ describe Lego::Value::Array do
|
|
6
6
|
|
7
7
|
describe '#parse' do
|
8
8
|
context 'nil' do
|
9
|
-
|
9
|
+
subject { Lego::Value::Array.new(String, allow_empty: false, default: ->{ 'DEFAULT' }) }
|
10
|
+
specify { subject.parse(nil).should be_just('DEFAULT') }
|
10
11
|
end
|
11
12
|
|
12
13
|
context 'invalid array or item' do
|
@@ -25,8 +26,8 @@ describe Lego::Value::Array do
|
|
25
26
|
end
|
26
27
|
|
27
28
|
context 'disallow empty' do
|
28
|
-
subject { Lego::Value::Array.new(String, allow_empty: false) }
|
29
|
-
specify { subject.parse([]).should
|
29
|
+
subject { Lego::Value::Array.new(String, allow_empty: false, default: ->{ 'DEFAULT' }) }
|
30
|
+
specify { subject.parse([]).should be_just('DEFAULT') }
|
30
31
|
end
|
31
32
|
|
32
33
|
context 'check length' do
|
@@ -6,9 +6,17 @@ describe Lego::Value::Base do
|
|
6
6
|
subject { Lego::Value::Base.new(opts) }
|
7
7
|
|
8
8
|
describe '#parse' do
|
9
|
-
context 'nil' do
|
10
|
-
|
9
|
+
context 'nil is missing' do
|
10
|
+
context 'with default handler' do
|
11
|
+
let(:opts) { { default: ->{ 'default' } } }
|
12
|
+
specify { subject.parse(nil).should be_just('default') }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'without default handler' do
|
16
|
+
specify { subject.parse(nil).should be_error('missing value') }
|
17
|
+
end
|
11
18
|
end
|
19
|
+
|
12
20
|
end
|
13
21
|
|
14
22
|
end
|
@@ -4,8 +4,10 @@ describe Lego::Value::Boolean do
|
|
4
4
|
|
5
5
|
describe '#parse' do
|
6
6
|
context 'nil' do
|
7
|
-
|
8
|
-
|
7
|
+
subject { Lego::Value::Boolean.new(default: ->{ 'DEFAULT' }) }
|
8
|
+
|
9
|
+
specify { subject.parse(nil).should be_just('DEFAULT') }
|
10
|
+
specify { subject.parse('').should be_just('DEFAULT') }
|
9
11
|
end
|
10
12
|
|
11
13
|
context 'boolean string' do
|
@@ -6,8 +6,10 @@ describe Lego::Value::Date do
|
|
6
6
|
subject { Lego::Value::Date.new }
|
7
7
|
|
8
8
|
context 'nil' do
|
9
|
-
|
10
|
-
|
9
|
+
subject { Lego::Value::Date.new(default: ->{ 'DEFAULT' }) }
|
10
|
+
|
11
|
+
specify { subject.parse(nil).should be_just('DEFAULT') }
|
12
|
+
specify { subject.parse('').should be_just('DEFAULT') }
|
11
13
|
end
|
12
14
|
|
13
15
|
context 'invalid date' do
|
@@ -8,8 +8,10 @@ describe Lego::Value::Float do
|
|
8
8
|
let(:opts){ {} }
|
9
9
|
|
10
10
|
context 'nil' do
|
11
|
-
|
12
|
-
|
11
|
+
let(:opts){ {default: ->{ 42.0 } } }
|
12
|
+
|
13
|
+
specify { subject.parse(nil).should be_just(42.0) }
|
14
|
+
specify { subject.parse('').should be_just(42.0) }
|
13
15
|
end
|
14
16
|
|
15
17
|
context 'invalid float' do
|
@@ -8,8 +8,10 @@ describe Lego::Value::Integer do
|
|
8
8
|
let(:opts){ {} }
|
9
9
|
|
10
10
|
context 'nil' do
|
11
|
-
|
12
|
-
|
11
|
+
let(:opts){ {default: ->{ 42 } } }
|
12
|
+
|
13
|
+
specify { subject.parse(nil).should be_just(42) }
|
14
|
+
specify { subject.parse('').should be_just(42) }
|
13
15
|
end
|
14
16
|
|
15
17
|
context 'invalid integer' do
|
data/spec/lego/value/set_spec.rb
CHANGED
@@ -6,11 +6,11 @@ describe Lego::Value::Set do
|
|
6
6
|
Array(elem).to_set
|
7
7
|
end
|
8
8
|
|
9
|
-
subject { Lego::Value::Set.new(String) }
|
9
|
+
subject { Lego::Value::Set.new(String, default: ->{ 'DEFAULT' } ) }
|
10
10
|
|
11
11
|
describe '#parse' do
|
12
12
|
context 'nil' do
|
13
|
-
specify { subject.parse(nil).should
|
13
|
+
specify { subject.parse(nil).should be_just('DEFAULT') }
|
14
14
|
end
|
15
15
|
|
16
16
|
context 'invalid set or item' do
|
@@ -33,12 +33,14 @@ describe Lego::Value::Set do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
context 'disallow empty' do
|
36
|
-
subject { Lego::Value::Set.new(String, allow_empty: false) }
|
37
|
-
specify { subject.parse([]).should
|
36
|
+
subject { Lego::Value::Set.new(String, allow_empty: false, default: ->{ 'DEFAULT' }) }
|
37
|
+
specify { subject.parse([]).should be_just('DEFAULT') }
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
describe '#coerce' do
|
42
|
+
subject { Lego::Value::Set.new(String) }
|
43
|
+
|
42
44
|
context 'missing' do
|
43
45
|
it 'raises error' do
|
44
46
|
expect{ subject.coerce(nil) }.to raise_error(Lego::CoerceError, 'missing value')
|
@@ -11,12 +11,13 @@ describe Lego::Value::String do
|
|
11
11
|
let(:opts) do
|
12
12
|
{
|
13
13
|
allow_blank: allow_blank,
|
14
|
-
strip: strip
|
14
|
+
strip: strip,
|
15
|
+
default: ->{ 'DEFAULT' }
|
15
16
|
}
|
16
17
|
end
|
17
18
|
|
18
19
|
context 'nil' do
|
19
|
-
specify { subject.parse(nil).should
|
20
|
+
specify { subject.parse(nil).should be_just('DEFAULT') }
|
20
21
|
end
|
21
22
|
|
22
23
|
context 'not a string' do
|
@@ -46,21 +47,21 @@ describe Lego::Value::String do
|
|
46
47
|
|
47
48
|
context 'strip' do
|
48
49
|
let(:strip) { true }
|
49
|
-
specify { subject.parse('').should
|
50
|
-
specify { subject.parse(' ').should
|
50
|
+
specify { subject.parse('').should be_just('DEFAULT') }
|
51
|
+
specify { subject.parse(' ').should be_just('DEFAULT') }
|
51
52
|
end
|
52
53
|
|
53
54
|
context 'no strip' do
|
54
55
|
let(:strip) { false }
|
55
|
-
specify { subject.parse('').should
|
56
|
-
specify { subject.parse(' ').should
|
56
|
+
specify { subject.parse('').should be_just('DEFAULT') }
|
57
|
+
specify { subject.parse(' ').should be_just('DEFAULT') }
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
60
61
|
context 'matches' do
|
61
62
|
subject { Lego::Value::String.new(opts.merge(matches: /^[A-Z]{3}$/)) }
|
62
63
|
|
63
|
-
specify { subject.parse(nil).should
|
64
|
+
specify { subject.parse(nil).should be_just('DEFAULT') }
|
64
65
|
specify { subject.parse(123).should be_error("invalid string: '123'") }
|
65
66
|
|
66
67
|
specify { subject.parse('abc').should be_error("does not match (/^[A-Z]{3}$/): 'abc'") }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lego
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -113,7 +113,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
113
|
version: '0'
|
114
114
|
segments:
|
115
115
|
- 0
|
116
|
-
hash:
|
116
|
+
hash: 3624199644753223561
|
117
117
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
118
|
none: false
|
119
119
|
requirements:
|
@@ -122,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
122
|
version: '0'
|
123
123
|
segments:
|
124
124
|
- 0
|
125
|
-
hash:
|
125
|
+
hash: 3624199644753223561
|
126
126
|
requirements: []
|
127
127
|
rubyforge_project:
|
128
128
|
rubygems_version: 1.8.23
|