Browse Source

Layout multiple inheritance works with operators

The case of using relative operators and multiple inheritance is handled now.

Fixes #244
dev
Andy Meneely 7 years ago
parent
commit
248eb2fb91
  1. 3
      docs/layouts.rst
  2. 24
      lib/squib/layout_parser.rb
  3. 12
      spec/data/layouts/multi-extends-operators-complex.yml
  4. 9
      spec/data/layouts/multi-extends-operators-same.yml
  5. 9
      spec/data/layouts/multi-extends-operators.yml
  6. 51
      spec/layout_parser_spec.rb
  7. 2
      spec/spec_helper.rb

3
docs/layouts.rst

@ -169,7 +169,8 @@ If you want to extend multiple parents, it looks like this::
extends:
- socrates
- plato
x: += 50 # evaluates to 250 from plato
x: += 50 # evaluates to 150 from socrates
# y is going to be 200 too from Plato
If multiple keys override the same keys in a parent, the later ("younger") child in the ``extends`` list takes precedent. Like this::

24
lib/squib/layout_parser.rb

@ -49,6 +49,24 @@ module Squib
h = {}
parent_keys.each do |parent_key|
from_extends = yml[key].merge(recurse_extends(yml, parent_key, visited)) do |key, child_val, parent_val|
handle_relative_operators(parent_val, child_val)
end
h = h.merge(from_extends) do |key, older_sibling, younger_sibling|
# In general, go with the younger sibling.
# UNLESS that younger sibling had a relative operator, in which use the
# (already computed) relative operator applied, which lands in older_sibling
# See bug 244.
sibling = younger_sibling
%w(+= -= *= /=).each do |op|
sibling = older_sibling if younger_sibling.to_s.strip.start_with? op
end
sibling
end
end
return h
end
def handle_relative_operators(parent_val, child_val)
if child_val.to_s.strip.start_with?('+=')
add_parent_child(parent_val, child_val)
elsif child_val.to_s.strip.start_with?('-=')
@ -61,12 +79,6 @@ module Squib
child_val # child overrides parent when merging, no +=
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
def add_parent_child(parent, child)
parent_pixels = Args::UnitConversion.parse(parent, @dpi).to_f

12
spec/data/layouts/multi-extends-operators-complex.yml

@ -0,0 +1,12 @@
# Here's a complex test case inspired by bug 244
socrates:
x: 100
y: 1000
plato:
y: 2000
aristotle:
extends:
- socrates
- plato
x: += 0.1in # 0.1in -> 30.0, so 100 + 30 = 130.0
y: += 18 # From Plato, 2000 + 18

9
spec/data/layouts/multi-extends-operators-same.yml

@ -0,0 +1,9 @@
socrates:
x: 100
plato:
x: 200
aristotle:
extends:
- socrates
- plato
x: += 50 # evaluates to 250 from plato

9
spec/data/layouts/multi-extends-operators.yml

@ -0,0 +1,9 @@
socrates:
x: 100
plato:
y: 200
aristotle:
extends:
- socrates
- plato
x: += 50 # evaluates to 150 from socrates

51
spec/layout_parser_spec.rb

@ -92,6 +92,57 @@ describe Squib::LayoutParser do
)
end
it 'applies multiple extends with relative operators' do
layout = subject.load_layout(layout_file('multi-extends-operators.yml'))
expect(layout).to eq({
'socrates' => {
'x' => 100,
},
'plato' => {
'y' => 200,
},
'aristotle' => {
'extends' => ['socrates', 'plato'],
'x' => 150.0, # do the += 50 on socrates
'y' => 200,
},
})
end
it 'applies multiple extends with relative operators on same key' do
layout = subject.load_layout(layout_file('multi-extends-operators-same.yml'))
expect(layout).to eq({
'socrates' => {
'x' => 100,
},
'plato' => {
'x' => 200,
},
'aristotle' => {
'extends' => ['socrates', 'plato'],
'x' => 250, # do the += 50 from plato, NOT socrates
},
})
end
it 'applies multiple extends with relative operators with ' do
layout = subject.load_layout(layout_file('multi-extends-operators-complex.yml'))
expect(layout).to eq({
'socrates' => {
'x' => 100,
'y' => 1000,
},
'plato' => {
'y' => 2000,
},
'aristotle' => {
'extends' => ['socrates', 'plato'],
'x' => 130.0, # 0.1in -> 30.0, so 100 + 30 = 130.0
'y' => 2018.0, # From Plato, 2000 + 18
},
})
end
it 'applies multi-level extends' do
layout = subject.load_layout(layout_file('multi-level-extends.yml'))
expect(layout).to eq({ 'frame' => {

2
spec/spec_helper.rb

@ -1,6 +1,6 @@
require 'simplecov'
require 'coveralls'
# require 'byebug'
require 'byebug'
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::HTMLFormatter,

Loading…
Cancel
Save