Browse Source

Handling of multiple extends in a single entry

dev
Andy Meneely 11 years ago
parent
commit
6895e1276b
  1. 18
      lib/squib/deck.rb
  2. 10
      spec/data/multi-extends-single-entry.yml
  3. 46
      spec/deck_spec.rb

18
lib/squib/deck.rb

@ -109,17 +109,24 @@ module Squib
end
end
# Process the extends
# Process the extends recursively
# :nodoc:
# @api private
def recurse_extends(yml, key, visited )
assert_not_visited(key, visited)
return yml[key] unless has_extends?(yml, key)
visited[key] = key
parent_key = yml[key]['extends']
return yml[key].merge(recurse_extends(yml, parent_key, visited)) do |key, child_val, parent_val|
child_val #child overrides parent when merging
parent_keys = [yml[key]['extends']].flatten
h = {}
parent_keys.each do |parent_key|
from_extends = yml[key].merge(recurse_extends(yml, parent_key, visited)) do |key, child_val, parent_val|
child_val #child overrides parent when merging
end
h = h.merge(from_extends) do |key, older_sibling, younger_sibling|
younger_sibling #when two siblings have the same entry, the "younger" (lower one) overrides
end
end
return h
end
# Does this layout entry have an extends field?
@ -130,6 +137,9 @@ module Squib
yml[key].key?('extends')
end
# Safeguard against malformed circular extends
# :nodoc:
# @api private
def assert_not_visited(key, visited)
if visited.key? key
raise "Invalid layout: circular extends with '#{key}'"

10
spec/data/multi-extends-single-entry.yml

@ -1,14 +1,14 @@
base:
aunt:
a: 101
b: 102
c: 103
frame:
uncle:
x: 104
y: 105
b: 106
title:
child:
extends:
- base
- frame
- uncle
- aunt
a: 107
x: 108

46
spec/deck_spec.rb

@ -117,28 +117,30 @@ describe Squib::Deck do
)
end
# it "applies multiple extends in a single rule" do
# d = Squib::Deck.new(layout: test_file('multi-extends-single-entry.yml'))
# expect(d.layout).to \
# eq({'base' => {
# 'x' => 38,
# 'y' => 38,
# },
# 'frame' => {
# 'extends' => 'frame',
# 'x' => 38,
# 'y' => 50,
# 'width' => 100,
# },
# 'title' => {
# 'extends' => 'frame',
# 'x' => 75,
# 'y' => 150,
# 'width' => 150,
# },
# }
# )
# end
it "applies multiple extends in a single rule" do
d = Squib::Deck.new(layout: test_file('multi-extends-single-entry.yml'))
expect(d.layout).to \
eq({'aunt' => {
'a' => 101,
'b' => 102,
'c' => 103,
},
'uncle' => {
'x' => 104,
'y' => 105,
'b' => 106,
},
'child' => {
'extends' => ['uncle','aunt'],
'a' => 107, # my own
'b' => 102, # from the younger aunt
'c' => 103, # from aunt
'x' => 108, # my own
'y' => 105, # from uncle
},
}
)
end
it "applies multi-level extends" do
d = Squib::Deck.new(layout: test_file('multi-level-extends.yml'))

Loading…
Cancel
Save