Layout multiple inheritance works with operators
The case of using relative operators and multiple inheritance is handled now. Fixes #244dev
parent
3d1f1ff989
commit
248eb2fb91
|
|
@ -169,7 +169,8 @@ If you want to extend multiple parents, it looks like this::
|
||||||
extends:
|
extends:
|
||||||
- socrates
|
- socrates
|
||||||
- plato
|
- 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::
|
If multiple keys override the same keys in a parent, the later ("younger") child in the ``extends`` list takes precedent. Like this::
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,25 +49,37 @@ module Squib
|
||||||
h = {}
|
h = {}
|
||||||
parent_keys.each do |parent_key|
|
parent_keys.each do |parent_key|
|
||||||
from_extends = yml[key].merge(recurse_extends(yml, parent_key, visited)) do |key, child_val, parent_val|
|
from_extends = yml[key].merge(recurse_extends(yml, parent_key, visited)) do |key, child_val, parent_val|
|
||||||
if child_val.to_s.strip.start_with?('+=')
|
handle_relative_operators(parent_val, child_val)
|
||||||
add_parent_child(parent_val, child_val)
|
|
||||||
elsif child_val.to_s.strip.start_with?('-=')
|
|
||||||
sub_parent_child(parent_val, child_val)
|
|
||||||
elsif child_val.to_s.strip.start_with?('*=')
|
|
||||||
mul_parent_child(parent_val, child_val)
|
|
||||||
elsif child_val.to_s.strip.start_with?('/=')
|
|
||||||
div_parent_child(parent_val, child_val)
|
|
||||||
else
|
|
||||||
child_val # child overrides parent when merging, no +=
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
h = h.merge(from_extends) do |key, older_sibling, younger_sibling|
|
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
|
# 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
|
||||||
end
|
end
|
||||||
return h
|
return h
|
||||||
end
|
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?('-=')
|
||||||
|
sub_parent_child(parent_val, child_val)
|
||||||
|
elsif child_val.to_s.strip.start_with?('*=')
|
||||||
|
mul_parent_child(parent_val, child_val)
|
||||||
|
elsif child_val.to_s.strip.start_with?('/=')
|
||||||
|
div_parent_child(parent_val, child_val)
|
||||||
|
else
|
||||||
|
child_val # child overrides parent when merging, no +=
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def add_parent_child(parent, child)
|
def add_parent_child(parent, child)
|
||||||
parent_pixels = Args::UnitConversion.parse(parent, @dpi).to_f
|
parent_pixels = Args::UnitConversion.parse(parent, @dpi).to_f
|
||||||
child_pixels = Args::UnitConversion.parse(child.sub('+=', ''), @dpi).to_f
|
child_pixels = Args::UnitConversion.parse(child.sub('+=', ''), @dpi).to_f
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
socrates:
|
||||||
|
x: 100
|
||||||
|
plato:
|
||||||
|
x: 200
|
||||||
|
aristotle:
|
||||||
|
extends:
|
||||||
|
- socrates
|
||||||
|
- plato
|
||||||
|
x: += 50 # evaluates to 250 from plato
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
socrates:
|
||||||
|
x: 100
|
||||||
|
plato:
|
||||||
|
y: 200
|
||||||
|
aristotle:
|
||||||
|
extends:
|
||||||
|
- socrates
|
||||||
|
- plato
|
||||||
|
x: += 50 # evaluates to 150 from socrates
|
||||||
|
|
@ -92,6 +92,57 @@ describe Squib::LayoutParser do
|
||||||
)
|
)
|
||||||
end
|
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
|
it 'applies multi-level extends' do
|
||||||
layout = subject.load_layout(layout_file('multi-level-extends.yml'))
|
layout = subject.load_layout(layout_file('multi-level-extends.yml'))
|
||||||
expect(layout).to eq({ 'frame' => {
|
expect(layout).to eq({ 'frame' => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
require 'simplecov'
|
require 'simplecov'
|
||||||
require 'coveralls'
|
require 'coveralls'
|
||||||
# require 'byebug'
|
require 'byebug'
|
||||||
|
|
||||||
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
||||||
SimpleCov::Formatter::HTMLFormatter,
|
SimpleCov::Formatter::HTMLFormatter,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue