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.
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
12
12
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
13
  gem.name = "lego"
14
14
  gem.require_paths = ["lib"]
15
- gem.version = '0.0.4'
15
+ gem.version = '0.0.5'
16
16
 
17
17
  gem.add_dependency 'activesupport'
18
18
 
@@ -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
- def initialize(attrs={})
21
- fail ArgumentError, "attrs must be hash: '#{attrs.inspect}'" unless attrs.respond_to?(:key?)
22
- attrs = attrs.dup
23
- @attributes = {}.tap do |h|
24
- self.class.parsers.each do |name, parser|
25
- name = name.to_sym
26
- value = attrs.key?(name) ? attrs.delete(name) : attrs.delete(name.to_s)
27
- begin
28
- h[name] = parser.coerce(value)
29
- rescue Lego::CoerceError => e
30
- fail ArgumentError, ":#{name} => #{e.message}"
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
- end.freeze
34
- fail ArgumentError, "Unknown attributes: #{attrs}" unless attrs.empty?
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.new(as_json.deep_merge(other))
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)
@@ -6,6 +6,8 @@ module Lego
6
6
  end
7
7
  end
8
8
 
9
+ class Boolean; end
10
+
9
11
  require_relative 'value/base'
10
12
  require_relative 'value/set'
11
13
  require_relative 'value/array'
@@ -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
- def coerce(val)
17
- resp = parse(val)
18
- if resp.value?
19
- resp.value
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
- raise Lego::CoerceError, 'missing value'
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
@@ -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.new(name: 'Alice', age: '10')
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.new(name: 'Alice', age: '10', grade: 5) }.to raise_error(ArgumentError, "Unknown attributes: {:grade=>5}")
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.new(name: 'Alice') }.to raise_error(ArgumentError, ":age => missing value")
38
- expect{ Person.new(name: 'Alice', age: Date.today) }.to raise_error(ArgumentError, /invalid integer/)
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.new(nil) }.to raise_error(ArgumentError, "attrs must be hash: 'nil'")
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.new(h)
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.new(name: 'Alice', age: 10).should == Person.new(name: 'Alice', age: '10')
55
- Person.new(name: 'Alice', age: 10).should_not == Person.new(name: 'Bob', age: '10')
56
- Person.new(name: 'Alice', age: 10).should_not == Person.new(name: 'Alice', age: '12')
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.new(name: 'Alice', age: 10).should eql Person.new(name: 'Alice', age: '10')
61
- Person.new(name: 'Alice', age: 10).should_not eql Person.new(name: 'Bob', age: '10')
62
- Person.new(name: 'Alice', age: 10).should_not eql Person.new(name: 'Alice', age: '12')
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.new(name: 'Alice', age: 10).hash.should == Person.new(name: 'Alice', age: '10').hash
67
- Person.new(name: 'Alice', age: 10).hash.should_not == Person.new(name: 'Bob', age: '10').hash
68
- Person.new(name: 'Alice', age: 10).hash.should_not == Person.new(name: 'Alice', age: '12').hash
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.new(last_name: 'Kowalski', father: { name: 'Bob', age: '55' })
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.new(name: 'Bob', age: '55')
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.new(last_name: 'Kowalski', father: Person.new(name: 'Bob', age: '55'))
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.new(name: 'Bob', age: '55')
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.new('last_name' => 'Kowalski', 'father' => Person.new('name' => 'Bob', 'age' => '55'))
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.new(name: 'Bob', age: '55')
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.new(last_name: 'Kowalski', father: { name: 'Bob', age: '55' })
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.new(last_name: 'Kowalski', father: { name: 'Bob', age: '55' }) }
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.new(last_name: 'Kowalski', father: { name: 'Bob', age: '55' })
122
- two.should == Family.new(last_name: 'Tesla', father: { name: 'Nikola', age: '55' })
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
- specify { subject.parse(nil).should be_nothing }
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 be_nothing }
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
- specify { subject.parse(nil).should be_nothing }
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
- specify { subject.parse(nil).should be_nothing }
8
- specify { subject.parse('').should be_nothing }
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
- specify { subject.parse(nil).should be_nothing }
10
- specify { subject.parse('').should be_nothing }
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
- specify { subject.parse(nil).should be_nothing }
12
- specify { subject.parse('').should be_nothing }
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
- specify { subject.parse(nil).should be_nothing }
12
- specify { subject.parse('').should be_nothing }
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
@@ -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 be_nothing }
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 be_nothing }
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 be_nothing }
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 be_nothing }
50
- specify { subject.parse(' ').should be_nothing }
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 be_nothing }
56
- specify { subject.parse(' ').should be_nothing }
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 be_nothing }
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
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-18 00:00:00.000000000 Z
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: 3608539237903599197
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: 3608539237903599197
125
+ hash: 3624199644753223561
126
126
  requirements: []
127
127
  rubyforge_project:
128
128
  rubygems_version: 1.8.23