Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/lego/value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ class Boolean; end
require_relative 'value/integer'
require_relative 'value/float'
require_relative 'value/boolean'
require_relative 'value/hash'
2 changes: 1 addition & 1 deletion lib/lego/value/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Lego::Value
class Array < Base

def initialize(type, opts={})
@_item_parser = Lego.value_parser(type)
@_item_parser = Lego.value_parser(type, opts[:children_opts] || {} )
super(opts)
end

Expand Down
16 changes: 16 additions & 0 deletions lib/lego/value/hash.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Lego::Value
class Hash < Base
def parsers
[
->(v) { v.respond_to?(:to_hash) ? Lego.just(v.to_hash.freeze) : Lego.fail("invalid hash: #{v.inspect}") },
->(v) { (not allow_empty? and v.empty?) ? Lego.none : Lego.just(v) }
]
end

private

def allow_empty?
@opts.fetch(:allow_empty, false)
end
end
end
5 changes: 5 additions & 0 deletions spec/lego/value/array_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
specify { subject.parse([1, 2, 3]).should be_error("length not 2: '[1, 2, 3]'") }
specify { subject.parse([42, 24]).should be_just([42, 24]) }
end

context 'passess children_opts to children parser' do
subject { Lego::Value::Array.new(String, children_opts: { allow_blank: true, default: -> { 'default' }} )}
specify { subject.parse(["abc", "", nil]).should be_just(["abc", "", "default"])}
end
end

describe '#coerce' do
Expand Down
80 changes: 80 additions & 0 deletions spec/lego/value/hash_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
require 'spec_helper'

describe Lego::Value::Hash do
describe '#parse' do
context 'parses nil' do
subject { Lego::Value::Hash.new(allow_empty:false, default: -> { {key: 'value' } }) }
specify { subject.parse(nil).should be_just({ key: 'value' }) }
end

context 'allow empty' do
subject { Lego::Value::Hash.new(allow_empty: true) }

it 'parses empty hash' do
subject.parse({}).should be_just({})
end
end

context 'disallow empty' do
subject { Lego::Value::Hash.new(allow_empty:false, default: -> { {key: 'value' } }) }
specify { subject.parse({}).should be_just({key: 'value' }) }
end

let(:hash) {{
key: 'value',
key2: 3,
key3: {
nested_key: Object.new,
nested_key2: 'nested value'
}
}}

it 'parses non-empty hash' do
result = subject.parse(hash)
result.should be_just(hash)
result.value.should be_frozen
end

context 'returns error when invalid hash' do
specify { subject.parse('').should be_error('invalid hash: ""') }
specify { subject.parse([]).should be_error('invalid hash: []') }
specify { subject.parse(6).should be_error('invalid hash: 6') }
end
end

describe '#coerce' do
context 'missing' do
it 'raises error' do
expect{ subject.coerce(nil) }.to raise_error(Lego::CoerceError, 'missing value')
expect{ subject.coerce({}) }.to raise_error(Lego::CoerceError, 'missing value')
end
end

context 'with :default handler' do
subject { Lego::Value::Hash.new(default: handler) }

context 'nil handler' do
let(:handler) { -> { nil } }
specify { subject.coerce(nil).should be_nil }
end

context 'lambda handler' do
let(:default_hash) { { key: 'value'} }
let(:handler) { -> { default_hash } }
specify { subject.coerce(nil).should == default_hash }
end
end

context 'failure' do
it 'raises error' do
expect { subject.coerce(nil) }.to raise_error(Lego::CoerceError, 'missing value')
end
end

context 'success' do
it 'returns hash' do
subject.coerce({key: 'value' }).should == { key: 'value' }
end
end
end
end