# encoding: UTF-8 # KLayout Layout Viewer # Copyright (C) 2006-2019 Matthias Koefferlein # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA if !$:.member?(File::dirname($0)) $:.push(File::dirname($0)) end load("test_prologue.rb") class Tl_TestClass < TestBase # Expression basics def test_1_Expression expr = RBA::Expression::new res = expr.eval assert_equal(res.class.to_s, "NilClass") assert_equal(res.to_s, "") expr = RBA::Expression.eval("1+2") assert_equal(expr.class.to_s, "Float") assert_equal(expr.to_s, "3.0") expr = RBA::Expression::new expr.text = "1+2" res = expr.eval assert_equal(res.class.to_s, "Float") assert_equal(res.to_s, "3.0") expr = RBA::Expression::new expr.var("a", 5) expr.text = "a+to_i(2)" res = expr.eval assert_equal(res.class.to_s == "Fixnum" || res.class.to_s == "Integer", true) assert_equal(res.to_s, "7") expr.var("a", 7) res = expr.eval assert_equal(res.to_s, "9") RBA::Expression::global_var("xxx", 17.5) expr = RBA::Expression::new("xxx+1") res = expr.eval assert_equal(res.class.to_s, "Float") assert_equal(res.to_s, "18.5") expr = RBA::Expression::new("a+b*2", { "a" => 18, "b" => 2.5 }) res = expr.eval assert_equal(res.class.to_s, "Float") assert_equal(res.to_s, "23.0") expr = RBA::Expression::new("[a[1],a[2],a[0],a[4],a[3]]", { "a" => [ 17, "a", nil, [ 2, 7 ], { 8 => "x", "u" => 42 } ] }) res = expr.eval assert_equal(res.class.to_s, "Array") assert_equal(res.inspect, ["a", nil, 17, {8=>"x", "u"=>42}, [2, 7]].inspect) expr = RBA::Expression::new("a[1]", { "a" => [ 17, "a", nil, [ 2, 7 ], { 8 => "x", "u" => 42 } ] }) res = expr.eval assert_equal(res.class.to_s, "String") assert_equal(res.to_s, "a") expr = RBA::Expression::new("a[4]", { "a" => [ 17, "a", nil, [ 2, 7 ], { 8 => "x", "u" => 42 } ] }) res = expr.eval assert_equal(res.class.to_s, "Hash") assert_equal(res.inspect, {8=>"x", "u"=>42}.inspect) end # Advanced expressions def test_2_Expression box1 = RBA::Box::new(0, 100, 200, 300) box2 = RBA::Box::new(50, 150, 250, 350) expr = RBA::Expression::new("a", { "a" => box1, "b" => box2 }) res = expr.eval assert_equal(res.to_s, "(0,100;200,300)") # boxes are non-managed objects -> passing the object through the expression does not persist their ID assert_not_equal(res.object_id, box1.object_id) assert_not_equal(res.object_id, box2.object_id) # ------------------------------------------------- box1 = RBA::Box::new(0, 100, 200, 300) box2 = RBA::Box::new(50, 150, 250, 350) expr = RBA::Expression::new("a&b", { "a" => box1, "b" => box2 }) res = expr.eval assert_equal(res.to_s, "(50,150;200,300)") # computed objects are entirely new ones assert_not_equal(res.object_id, box1.object_id) assert_not_equal(res.object_id, box2.object_id) # ------------------------------------------------- box1 = RBA::Box::new(0, 100, 200, 300) box2 = RBA::Box::new(50, 150, 250, 350) expr = RBA::Expression::new("x=a&b; y=x; z=y; [x,y,z]", { "a" => box1, "b" => box2, "x" => nil, "y" => nil, "z" => nil }) res = expr.eval assert_equal(res.inspect, "[(50,150;200,300), (50,150;200,300), (50,150;200,300)]") # all objects are individual copies assert_not_equal(res[0].object_id, box1.object_id) assert_not_equal(res[0].object_id, box2.object_id) assert_not_equal(res[1].object_id, res[0].object_id) assert_not_equal(res[2].object_id, res[0].object_id) # ------------------------------------------------- box1 = RBA::Box::new(0, 100, 200, 300) box2 = RBA::Box::new(50, 150, 250, 350) expr = RBA::Expression::new("var x=a&b; var y=x; var z=y; [x,y,z]", { "a" => box1, "b" => box2 }) res = expr.eval assert_equal(res.inspect, "[(50,150;200,300), (50,150;200,300), (50,150;200,300)]") # all objects are individual copies assert_not_equal(res[0].object_id, box1.object_id) assert_not_equal(res[0].object_id, box2.object_id) assert_not_equal(res[1].object_id, res[0].object_id) assert_not_equal(res[2].object_id, res[0].object_id) # destruction of the expression's object space does not matter since we have copies expr._destroy assert_equal(res.inspect, "[(50,150;200,300), (50,150;200,300), (50,150;200,300)]") # ------------------------------------------------- region1 = RBA::Region::new region1 |= RBA::Box::new(0, 100, 200, 300) region2 = RBA::Region::new region2 |= RBA::Box::new(50, 150, 250, 350) expr = RBA::Expression::new("a", { "a" => region1, "b" => region2 }) res = expr.eval # regions are managed objects -> passing the object through the expression persists it's object ID assert_equal(res.object_id, region1.object_id) assert_not_equal(res.object_id, region2.object_id) # ------------------------------------------------- region1 = RBA::Region::new region1 |= RBA::Box::new(0, 100, 200, 300) region2 = RBA::Region::new region2 |= RBA::Box::new(50, 150, 250, 350) expr = RBA::Expression::new("a&b", { "a" => region1, "b" => region2, "x" => nil, "y" => nil, "z" => nil }) res = expr.eval assert_equal(res.to_s, "(50,150;50,300;200,300;200,150)") # The returned object (as a new one) is an entirely fresh one assert_not_equal(res.object_id, region1.object_id) assert_not_equal(res.object_id, region2.object_id) # ------------------------------------------------- region1 = RBA::Region::new region1 |= RBA::Box::new(0, 100, 200, 300) region2 = RBA::Region::new region2 |= RBA::Box::new(50, 150, 250, 350) expr = RBA::Expression::new("x=a&b; y=x; z=y; [x,y,z]", { "a" => region1, "b" => region2, "x" => nil, "y" => nil, "z" => nil }) res = expr.eval assert_equal(res.inspect, "[(50,150;50,300;200,300;200,150), (50,150;50,300;200,300;200,150), (50,150;50,300;200,300;200,150)]") # regions are managed objects -> passing the object through the expression persists it's object ID assert_not_equal(res[0].object_id, region1.object_id) assert_not_equal(res[0].object_id, region2.object_id) assert_equal(res[1].object_id, res[0].object_id) assert_equal(res[2].object_id, res[0].object_id) # ------------------------------------------------- region1 = RBA::Region::new region1 |= RBA::Box::new(0, 100, 200, 300) region2 = RBA::Region::new region2 |= RBA::Box::new(50, 150, 250, 350) expr = RBA::Expression::new("var x=a&b; var y=x; var z=y; [x,y,z]", { "a" => region1, "b" => region2 }) res = expr.eval assert_equal(res.inspect, "[(50,150;50,300;200,300;200,150), (50,150;50,300;200,300;200,150), (50,150;50,300;200,300;200,150)]") # regions are managed objects -> passing the object through the expression persists it's object ID assert_not_equal(res[0].object_id, region1.object_id) assert_not_equal(res[0].object_id, region2.object_id) assert_equal(res[1].object_id, res[0].object_id) assert_equal(res[2].object_id, res[0].object_id) # the result objects live in the expression object space and are destroyed with the expression expr._destroy assert_equal(res.size, 3) assert_equal(res[0].destroyed?, true) assert_equal(res[1].destroyed?, true) assert_equal(res[2].destroyed?, true) end end load("test_epilogue.rb")