Browse Source

Handling of multiple extends in a single entry

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

16
lib/squib/deck.rb

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

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

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

46
spec/deck_spec.rb

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

Loading…
Cancel
Save