Fixed #276 (Layer properties name cannot be updated)

In addition, this fix includes Python-related fixes: because
of the short lifetime of Python references, the functionality
was not as expected sometimes. Keeping copies of LayerPropertiesIterators
helped. Some tweaks were required to maintain the delete() semantics.
This commit is contained in:
Matthias Koefferlein 2019-06-16 21:42:07 +02:00
parent f59e49d678
commit 56c622053f
7 changed files with 1033 additions and 68 deletions

View File

@ -1388,9 +1388,9 @@ Class<lay::LayerPropertiesNodeRef> decl_LayerPropertiesNodeRef (
"This class has been introduced in version 0.25.\n"
);
static lay::LayerPropertiesNodeRef current (lay::LayerPropertiesConstIterator *iter)
static lay::LayerPropertiesNodeRef current (const lay::LayerPropertiesConstIterator *iter)
{
return lay::LayerPropertiesNodeRef (iter);
return lay::LayerPropertiesNodeRef (*iter);
}
Class<lay::LayerPropertiesConstIterator> decl_LayerPropertiesIterator (

View File

@ -339,7 +339,7 @@ namespace {
reference operator* () const
{
return lay::LayerPropertiesNodeRef (&const_cast<LayerPropertiesConstIteratorWrapper *> (this)->m_iter);
return lay::LayerPropertiesNodeRef (m_iter);
}
bool at_end () const

View File

@ -197,12 +197,15 @@ LayerProperties::operator= (const LayerProperties &d)
flags += nr_source;
}
if (m_name != d.m_name) {
m_name = d.m_name;
flags += nr_meta;
}
if (flags) {
need_realize (flags, true /*force on children*/);
}
m_name = d.m_name;
}
return *this;
}
@ -806,13 +809,13 @@ LayerPropertiesNode::add_child (const LayerPropertiesNode &child)
// LayerPropertiesConstIterator implementation
LayerPropertiesConstIterator::LayerPropertiesConstIterator ()
: m_uint (0), m_list (), mp_obj (0)
: m_uint (0), m_list ()
{
// .. nothing yet ..
}
LayerPropertiesConstIterator::LayerPropertiesConstIterator (const lay::LayerPropertiesNode *node)
: m_uint (0), m_list (), mp_obj (0)
: m_uint (0), m_list ()
{
if (!node) {
return;
@ -874,7 +877,7 @@ LayerPropertiesConstIterator::LayerPropertiesConstIterator (const lay::LayerProp
LayerPropertiesConstIterator::LayerPropertiesConstIterator (const LayerPropertiesList &list, bool last)
// NOTE: there should be some "const_weak_ptr"
: m_uint (0), m_list (const_cast<LayerPropertiesList *> (&list)), mp_obj (0)
: m_uint (0), m_list (const_cast<LayerPropertiesList *> (&list))
{
if (last) {
m_uint = (list.end_const () - list.begin_const ()) + 1;
@ -885,7 +888,7 @@ LayerPropertiesConstIterator::LayerPropertiesConstIterator (const LayerPropertie
LayerPropertiesConstIterator::LayerPropertiesConstIterator (const LayerPropertiesList &list, size_t uint)
// NOTE: there should be some "const_weak_ptr"
: m_uint (uint), m_list (const_cast<LayerPropertiesList *> (&list)), mp_obj (0)
: m_uint (uint), m_list (const_cast<LayerPropertiesList *> (&list))
{
// .. nothing yet ..
}
@ -991,7 +994,7 @@ LayerPropertiesConstIterator &
LayerPropertiesConstIterator::up ()
{
m_uint %= factor ().first;
mp_obj = 0;
mp_obj.reset (0);
return *this;
}
@ -999,7 +1002,7 @@ LayerPropertiesConstIterator &
LayerPropertiesConstIterator::next_sibling (ptrdiff_t n)
{
m_uint += factor ().first * n;
mp_obj = 0;
mp_obj.reset (0);
return *this;
}
@ -1008,7 +1011,7 @@ LayerPropertiesConstIterator::to_sibling (size_t n)
{
std::pair <size_t, size_t> f = factor ();
m_uint = (m_uint % f.first) + (1 + n) * f.first;
mp_obj = 0;
mp_obj.reset (0);
return *this;
}
@ -1024,7 +1027,7 @@ LayerPropertiesConstIterator::down_first_child ()
{
std::pair <size_t, size_t> f = factor ();
m_uint += f.first * f.second;
mp_obj = 0;
mp_obj.reset (0);
return *this;
}
@ -1034,7 +1037,7 @@ LayerPropertiesConstIterator::down_last_child ()
std::pair <size_t, size_t> f = factor ();
const LayerPropertiesNode *o = obj ();
m_uint += f.first * f.second * ((o->end_children () - o->begin_children ()) + 1);
mp_obj = 0;
mp_obj.reset (0);
return *this;
}
@ -1067,8 +1070,8 @@ LayerPropertiesConstIterator::parent_obj () const
void
LayerPropertiesConstIterator::invalidate ()
{
mp_obj = 0;
mp_obj.reset (0);
// the iterator may be parked at a position behind the last element.
// Move one step further in this case.
std::pair <size_t, size_t> f = factor ();
@ -1083,7 +1086,7 @@ LayerPropertiesConstIterator::set_obj () const
{
if (is_null () || !m_list) {
mp_obj = 0;
mp_obj.reset (0);
} else {
@ -1104,7 +1107,7 @@ LayerPropertiesConstIterator::set_obj () const
iter = iter[rem - 1].begin_children ();
}
mp_obj = &iter[uint - 1];
mp_obj.reset (const_cast<lay::LayerPropertiesNode *> (&iter[uint - 1]));
}
}
@ -1122,7 +1125,7 @@ LayerPropertiesConstIterator::inc (unsigned int d)
while (true) {
std::pair <size_t, size_t> f = factor ();
m_uint += f.first;
mp_obj = 0;
mp_obj.reset (0);
if (m_uint / f.first < f.second - 1) {
break;
} else if (at_top ()) {
@ -1908,32 +1911,11 @@ LayerPropertiesNodeRef::LayerPropertiesNodeRef (LayerPropertiesNode *node)
attach_view (node->view (), node->list_index ());
set_parent (node->parent ());
mp_iter.reset (&m_iter);
mp_node.reset (node);
}
}
LayerPropertiesNodeRef::LayerPropertiesNodeRef (LayerPropertiesConstIterator *iter)
{
if (iter && !iter->at_end () && !iter->is_null ()) {
const lay::LayerPropertiesNode *node = (*iter).operator-> ();
// NOTE: we do assignment before we set the iterator reference - hence there won't be
// updates triggered.
LayerPropertiesNode::operator= (*node);
// Makes ourself a perfect copy of the original (including reference into the view)
attach_view (node->view (), node->list_index ());
set_parent (node->parent ());
mp_iter.reset (iter);
mp_node.reset (const_cast<lay::LayerPropertiesNode *> (node));
}
}
LayerPropertiesNodeRef::LayerPropertiesNodeRef (const LayerPropertiesConstIterator &iter)
: m_iter (iter)
{
@ -1949,7 +1931,6 @@ LayerPropertiesNodeRef::LayerPropertiesNodeRef (const LayerPropertiesConstIterat
attach_view (node->view (), node->list_index ());
set_parent (node->parent ());
mp_iter.reset (&m_iter);
mp_node.reset (const_cast<lay::LayerPropertiesNode *> (node));
}
@ -1961,7 +1942,7 @@ LayerPropertiesNodeRef::LayerPropertiesNodeRef ()
}
LayerPropertiesNodeRef::LayerPropertiesNodeRef (const LayerPropertiesNodeRef &other)
: LayerPropertiesNode (other), m_iter (other.m_iter), mp_iter (other.mp_iter), mp_node (other.mp_node)
: LayerPropertiesNode (other), m_iter (other.m_iter), mp_node (other.mp_node)
{
attach_view (other.view (), other.list_index ());
set_parent (other.parent ());
@ -1971,7 +1952,6 @@ LayerPropertiesNodeRef &LayerPropertiesNodeRef::operator= (const LayerProperties
{
if (this != &other) {
mp_iter = other.mp_iter;
mp_node = other.mp_node;
m_iter = other.m_iter;
attach_view (other.view (), other.list_index ());
@ -1988,25 +1968,20 @@ void
LayerPropertiesNodeRef::erase ()
{
if (is_valid ()) {
view ()->delete_layer ((unsigned int) list_index (), *mp_iter);
view ()->delete_layer ((unsigned int) list_index (), m_iter);
}
}
const lay::LayerPropertiesConstIterator &
LayerPropertiesNodeRef::iter () const
{
if (mp_iter) {
return *mp_iter;
} else {
static lay::LayerPropertiesConstIterator null_iter;
return null_iter;
}
return m_iter;
}
bool
LayerPropertiesNodeRef::is_valid () const
{
return mp_iter && !mp_iter->at_end () && !mp_iter->is_null () && view ();
return !m_iter.is_null () && !m_iter.at_end () && view ();
}
void
@ -2015,11 +1990,11 @@ LayerPropertiesNodeRef::need_realize (unsigned int flags, bool force)
LayerPropertiesNode::need_realize (flags, force);
if (is_valid ()) {
if ((flags & (nr_visual + nr_source)) != 0) {
view ()->set_properties ((unsigned int) list_index (), *mp_iter, *this);
if ((flags & (nr_visual + nr_source + nr_meta)) != 0) {
view ()->set_properties ((unsigned int) list_index (), m_iter, *this);
}
if ((flags & nr_hierarchy) != 0) {
view ()->replace_layer_node ((unsigned int) list_index (), *mp_iter, *this);
view ()->replace_layer_node ((unsigned int) list_index (), m_iter, *this);
}
} else if (mp_node) {

View File

@ -637,7 +637,10 @@ public:
*/
void set_name (const std::string &n)
{
m_name = n;
if (m_name != n) {
m_name = n;
need_realize (nr_meta);
}
}
/**
@ -916,7 +919,8 @@ protected:
enum {
nr_visual = 1,
nr_source = 2,
nr_hierarchy = 4
nr_meta = 4,
nr_hierarchy = 8
};
mutable bool m_realize_needed_source : 1;
@ -1407,7 +1411,7 @@ public:
if (! mp_obj) {
set_obj ();
}
return mp_obj;
return mp_obj.get ();
}
/**
@ -1423,7 +1427,7 @@ private:
size_t m_uint;
tl::weak_ptr<LayerPropertiesList> m_list;
mutable const LayerPropertiesNode *mp_obj;
mutable tl::weak_ptr<LayerPropertiesNode> mp_obj;
void inc (unsigned int d);
std::pair <size_t, size_t> factor () const;
@ -1888,14 +1892,6 @@ public:
*/
LayerPropertiesNodeRef (LayerPropertiesNode *node);
/**
* @brief Constructor from an iterator
* The iterator is a pointer since the erase implementation requires us to
* modify the iterator. Hence with this version, the original iterator will
* follow up after the erase.
*/
LayerPropertiesNodeRef (LayerPropertiesConstIterator *iter);
/**
* @brief Constructor from an iterator with an iterator copy
*/
@ -1919,7 +1915,7 @@ public:
/**
* @brief Deletes the current node
* After this operation, the reference will point to the
* After this operation, the reference will point to the next element.
*/
void erase ();
@ -1947,7 +1943,6 @@ public:
private:
LayerPropertiesConstIterator m_iter;
tl::weak_ptr<LayerPropertiesConstIterator> mp_iter;
tl::weak_ptr<LayerPropertiesNode> mp_node;
void need_realize (unsigned int flags, bool force);

View File

@ -102,6 +102,7 @@ PYTHONTEST (dbReaders, "dbReaders.py")
PYTHONTEST (dbPCellsTest, "dbPCells.py")
PYTHONTEST (dbPolygonTest, "dbPolygonTest.py")
PYTHONTEST (dbTransTest, "dbTransTest.py")
PYTHONTEST (layLayers, "layLayers.py")
PYTHONTEST (tlTest, "tlTest.py")
#if defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
PYTHONTEST (qtbinding, "qtbinding.py")

956
testdata/python/layLayers.py vendored Normal file
View File

@ -0,0 +1,956 @@
# 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
import pya
import unittest
import os
import sys
class LAYLayersTest(unittest.TestCase):
def lnode_str(self, space, l):
return space + l.current().source_(True) + "\n";
def lnodes_str(self, space, l):
res = ""
while not l.at_end():
res += self.lnode_str(space, l)
if l.current().has_children():
l.down_first_child()
res += self.lnodes_str(" " + space, l)
l.up()
l.next_sibling(1)
return res
def lnodes_str2(self, v):
res = []
for c in v.each_layer():
res.append(c.source_(True))
return "\n".join(res)
def lnodes_str3(self, v, index):
res = []
for c in v.each_layer(index):
res.append(c.source_(True))
return "\n".join(res)
def test_1(self):
app = pya.Application.instance()
mw = app.main_window()
mw.close_all()
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t10.gds", 2)
cv = mw.current_view()
cv.clear_layers()
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
pos = cv.end_layers()
self.assertEqual(pos.parent().is_null(), True)
p = pos.dup()
p.up()
self.assertEqual(p.is_null(), True)
self.assertEqual(pos.is_null(), False)
self.assertEqual(pos == cv.begin_layers(), True)
self.assertEqual(pos != cv.begin_layers(), False)
l1 = cv.insert_layer(pos, pya.LayerProperties())
self.assertEqual(pos == cv.begin_layers(), True)
self.assertEqual(pos != cv.begin_layers(), False)
self.assertEqual(pos == cv.end_layers(), False)
self.assertEqual(pos != cv.end_layers(), True)
self.assertEqual(pos < cv.end_layers(), True)
self.assertEqual(cv.end_layers() < pos, False)
self.assertEqual(pos < cv.begin_layers(), False)
self.assertEqual(cv.begin_layers() < pos, False)
self.assertEqual(pos.at_top(), True)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n")
new_p = pya.LayerProperties()
new_p.source = "1/0@1"
l11 = cv.insert_layer(pos.last_child(), new_p)
p12 = pos.last_child()
self.assertEqual(p12.parent().is_null(), False)
self.assertEqual(p12.parent() == pos, True)
pp = pos.dup()
pp.down_last_child()
self.assertEqual(pp == p12, True)
self.assertEqual(pp == pos, False)
self.assertEqual(pp.parent() == pos, True)
pp.up()
self.assertEqual(pp == pos, True)
self.assertEqual(p12.at_top(), False)
p12.to_sibling(0)
self.assertEqual(p12 == pos.first_child(), True)
self.assertEqual(p12.child_index(), 0)
p12.to_sibling(1)
self.assertEqual(p12.child_index(), 1)
self.assertEqual(p12 == pos.last_child(), True)
self.assertEqual(p12.num_siblings(), 1)
l12 = cv.insert_layer(p12, pya.LayerProperties())
l12_new = pya.LayerProperties()
l12_new.source = "1/0@2"
cv.set_layer_properties(p12, l12_new)
self.assertEqual(p12.current().cellview(), 1)
self.assertEqual(p12.current().has_upper_hier_level(True), False)
self.assertEqual(p12.current().has_lower_hier_level(True), False)
l12_new.source = "@* #1..2"
cv.set_layer_properties(p12, l12_new)
self.assertEqual(p12.current().cellview(), 0)
self.assertEqual(p12.current().has_upper_hier_level(True), True)
self.assertEqual(p12.current().has_upper_hier_level(), True)
self.assertEqual(p12.current().upper_hier_level_(True), 2)
self.assertEqual(p12.current().upper_hier_level, 2)
self.assertEqual(p12.current().has_lower_hier_level(True), True)
self.assertEqual(p12.current().has_lower_hier_level(), True)
self.assertEqual(p12.current().lower_hier_level_(True), 1)
self.assertEqual(p12.current().lower_hier_level, 1)
l12_new.source = "@* (0,0 *0.5) (0,5 r45 *2.5)"
cv.set_layer_properties(p12, l12_new)
trans = p12.current().trans_(True)
self.assertEqual(str(trans), str(p12.current().trans))
self.assertEqual(len(trans), 2)
self.assertEqual(str(trans [0]), "r0 *0.5 0,0")
self.assertEqual(str(trans [1]), "r45 *2.5 0,5")
l12_new.source = "1/0@2"
cv.set_layer_properties(p12, l12_new)
self.assertEqual(p12.num_siblings(), 2)
pos = cv.end_layers()
new_p = pya.LayerProperties()
new_p.source = "@1"
l2 = cv.insert_layer(pos, new_p)
new_p = pya.LayerProperties()
new_p.source = "7/0@*"
l21 = cv.insert_layer(pos.first_child(), new_p)
p22 = pos.last_child()
new_p = pya.LayerProperties()
l22 = cv.insert_layer(pos.last_child(), new_p)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@1\n 7/0@1\n */*@1\n")
new_p = l2.dup()
new_p.source = "@2"
cv.set_layer_properties(pos, new_p)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n */*@2\n")
pos.first_child().current().source = "7/0@1"
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@1\n */*@2\n")
pos.current().source = "@*"
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@*\n 7/0@1\n */*@*\n")
pos.current().source = "@2"
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@1\n */*@2\n")
pos.first_child().current().source = "7/1@*"
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/1@2\n */*@2\n")
pos.first_child().current().source = "7/0@*"
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n */*@2\n")
l22_new = pya.LayerProperties()
l22_new.source = "7/1@*"
cv.replace_layer_node(p22, l22_new)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n 7/1@2\n")
cv.delete_layer(p22)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n")
new_p = l2.dup()
new_p.source = "%5@2"
cv.set_layer_properties(pos, new_p)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n%5@2\n %5@2\n")
mw.close_all()
def test_1a(self):
app = pya.Application.instance()
mw = app.main_window()
mw.close_all()
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t10.gds", 2)
cv = mw.current_view()
cv.clear_layers()
cv.insert_layer_list(1)
cv.rename_layer_list(1, "x")
self.assertEqual(cv.current_layer_list, 1)
cv.set_current_layer_list(0)
self.assertEqual(cv.current_layer_list, 0)
cv.set_current_layer_list(1)
self.assertEqual(cv.current_layer_list, 1)
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "")
self.assertEqual(self.lnodes_str("", cv.begin_layers(1)), "")
pos = cv.end_layers(0)
self.assertEqual(pos.parent().is_null(), True)
p = pos.dup()
p.up()
self.assertEqual(p.is_null(), True)
self.assertEqual(pos.is_null(), False)
self.assertEqual(pos == cv.begin_layers(0), True)
self.assertEqual(pos != cv.begin_layers(0), False)
l1 = cv.insert_layer(0, pos, pya.LayerProperties())
self.assertEqual(pos == cv.begin_layers(0), True)
self.assertEqual(pos != cv.begin_layers(0), False)
self.assertEqual(pos == cv.end_layers(0), False)
self.assertEqual(pos != cv.end_layers(0), True)
self.assertEqual(pos < cv.end_layers(0), True)
self.assertEqual(cv.end_layers(0) < pos, False)
self.assertEqual(pos < cv.begin_layers(0), False)
self.assertEqual(cv.begin_layers(0) < pos, False)
self.assertEqual(pos.at_top(), True)
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n")
self.assertEqual(self.lnodes_str("", cv.begin_layers(1)), "")
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
new_p = pya.LayerProperties()
new_p.source = "1/0@1"
l11 = cv.insert_layer(0, pos.last_child(), new_p)
p12 = pos.last_child()
self.assertEqual(p12.parent().is_null(), False)
self.assertEqual(p12.parent() == pos, True)
pp = pos.dup()
pp.down_last_child()
self.assertEqual(pp == p12, True)
self.assertEqual(pp == pos, False)
self.assertEqual(pp.parent() == pos, True)
pp.up()
self.assertEqual(pp == pos, True)
self.assertEqual(p12.at_top(), False)
p12.to_sibling(0)
self.assertEqual(p12 == pos.first_child(), True)
self.assertEqual(p12.child_index(), 0)
p12.to_sibling(1)
self.assertEqual(p12.child_index(), 1)
self.assertEqual(p12 == pos.last_child(), True)
self.assertEqual(p12.num_siblings(), 1)
l12 = cv.insert_layer(0, p12, pya.LayerProperties())
l12_new = pya.LayerProperties()
l12_new.source = "1/0@2"
cv.set_layer_properties(0, p12, l12_new)
self.assertEqual(p12.current().cellview(), 1)
self.assertEqual(p12.current().has_upper_hier_level(True), False)
self.assertEqual(p12.current().has_upper_hier_level(), False)
self.assertEqual(p12.current().has_lower_hier_level(True), False)
self.assertEqual(p12.current().has_lower_hier_level(), False)
l12_new.source = "@* #1..2"
cv.set_layer_properties(0, p12, l12_new)
self.assertEqual(p12.current().cellview(), 0)
self.assertEqual(p12.current().has_upper_hier_level(True), True)
self.assertEqual(p12.current().has_upper_hier_level(), True)
self.assertEqual(p12.current().upper_hier_level_(True), 2)
self.assertEqual(p12.current().upper_hier_level, 2)
self.assertEqual(p12.current().has_lower_hier_level(True), True)
self.assertEqual(p12.current().has_lower_hier_level(), True)
self.assertEqual(p12.current().lower_hier_level_(True), 1)
self.assertEqual(p12.current().lower_hier_level, 1)
l12_new.source = "@* (0,0 *0.5) (0,5 r45 *2.5)"
cv.set_layer_properties(0, p12, l12_new)
trans = p12.current().trans_(True)
self.assertEqual(len(trans), 2)
self.assertEqual(str(trans [0]), "r0 *0.5 0,0")
self.assertEqual(str(trans [1]), "r45 *2.5 0,5")
l12_new.source = "1/0@2"
cv.set_layer_properties(0, p12, l12_new)
self.assertEqual(p12.num_siblings(), 2)
pos = cv.end_layers(0)
new_p = pya.LayerProperties()
new_p.source = "@1"
l2 = cv.insert_layer(0, pos, new_p)
new_p = pya.LayerProperties()
new_p.source = "7/0@*"
l21 = cv.insert_layer(0, pos.first_child(), new_p)
p22 = pos.last_child()
new_p = pya.LayerProperties()
l22 = cv.insert_layer(0, pos.last_child(), new_p)
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n*/*@1\n 7/0@1\n */*@1\n")
self.assertEqual(self.lnodes_str("", cv.begin_layers(1)), "")
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
new_p = l2.dup()
new_p.source = "@2"
cv.set_layer_properties(0, pos, new_p)
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n */*@2\n")
l22_new = pya.LayerProperties()
l22_new.source = "7/1@*"
cv.replace_layer_node(0, p22, l22_new)
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n 7/1@2\n")
cv.delete_layer(0, p22)
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n*/*@2\n 7/0@2\n")
new_p = l2.dup()
new_p.source = "%5@2"
cv.set_layer_properties(0, pos, new_p)
self.assertEqual(self.lnodes_str("", cv.begin_layers(0)), "*/*@*\n 1/0@1\n 1/0@2\n%5@2\n %5@2\n")
# build a tree by building a separate tree
new_p = pya.LayerPropertiesNode()
self.assertEqual(new_p.has_children(), False)
n1 = new_p.add_child(pya.LayerProperties())
self.assertEqual(n1.has_children(), False)
n1.source = "101/0"
n2 = pya.LayerPropertiesNode()
self.assertEqual(n2.has_children(), False)
n21 = n2.add_child(pya.LayerProperties())
n21.source = "102/0"
self.assertEqual(n2.has_children(), True)
n22 = n2.add_child(pya.LayerProperties())
self.assertEqual(n2.has_children(), True)
n22.source = "103/0"
new_p.add_child(n2)
self.assertEqual(new_p.has_children(), True)
p = pos.last_child()
ll = cv.insert_layer(0, p, new_p)
self.assertEqual(p.current().has_children(), True)
self.assertEqual(p.first_child().current().has_children(), False)
self.assertEqual(p.first_child().current().source_(False), "101/0@1")
self.assertEqual(p.first_child().current().source, "%5@1")
# (test clear_children):
new_p.clear_children()
self.assertEqual(new_p.has_children(), False)
self.assertEqual(ll.has_children(), False)
cv.transaction("Delete")
li = cv.begin_layers(0)
a = []
while not li.at_end():
a.append(li.dup())
li.next()
self.assertEqual(len(a), 10)
cv.delete_layers(0, a)
self.assertEqual(cv.begin_layers(0).at_end(), True)
cv.commit()
mw.cm_undo()
self.assertEqual(cv.begin_layers(0).at_end(), False)
cv.transaction("Delete")
i = 0
while not cv.begin_layers(0).at_end():
cv.delete_layer(0, cv.begin_layers(0))
i += 1
self.assertEqual(i, 2)
self.assertEqual(cv.begin_layers(0).at_end(), True)
cv.commit()
mw.cm_undo()
self.assertEqual(cv.begin_layers(0).at_end(), False)
mw.close_all()
def test_2(self):
p = pya.LayerPropertiesNode()
self.assertEqual(p.source_(False), "*/*@*")
self.assertEqual(p.source, "*/*@*")
self.assertEqual(p.has_source_name(False), False)
self.assertEqual(p.has_source_name(), False)
self.assertEqual(p.has_frame_color(), False)
self.assertEqual(p.has_frame_color(True), False)
self.assertEqual(p.has_fill_color(), False)
self.assertEqual(p.has_fill_color(True), False)
self.assertEqual(p.has_dither_pattern(), False)
self.assertEqual(p.has_dither_pattern(True), False)
self.assertEqual(p.has_line_style(), False)
self.assertEqual(p.has_line_style(True), False)
p.name = "u"
self.assertEqual(p.name, "u")
p.source_name = "x"
self.assertEqual(p.source_name_(False), "x")
self.assertEqual(p.source_name, "x")
self.assertEqual(p.source_(False), "x@*")
self.assertEqual(p.source, "x@*")
self.assertEqual(p.flat().source, "x@*")
self.assertEqual(p.dup().source, "x@*")
self.assertEqual(p.has_source_name(False), True)
self.assertEqual(p.has_source_name(), True)
p.clear_source_name()
self.assertEqual(p.source_(False), "*/*@*")
self.assertEqual(p.has_source_name(False), False)
p.source_layer_index = 6
self.assertEqual(p.source_(False), "%6@*")
self.assertEqual(p.source_layer_index_(False), 6)
self.assertEqual(p.source_layer_index, 6)
p.source_layer = 6
p.source_datatype = 5
self.assertEqual(p.source_(False), "%6@*")
p.source_layer_index = -1
self.assertEqual(p.source_(False), "6/5@*")
self.assertEqual(p.source_layer_index_(False), -1)
self.assertEqual(p.source_layer_index, -1)
self.assertEqual(p.source_layer_(False), 6)
self.assertEqual(p.source_layer, 6)
self.assertEqual(p.source_datatype_(False), 5)
self.assertEqual(p.source_datatype, 5)
arr = [ pya.CplxTrans.new(pya.CplxTrans.M45), pya.CplxTrans.new(pya.CplxTrans.R270) ]
p.trans = arr
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
self.assertEqual(arr == p.trans_(False), True)
p.source_cellview = 1
self.assertEqual(p.source_(False), "6/5@2 (m45 *1 0,0) (r270 *1 0,0)")
self.assertEqual(p.flat().source, "6/5@2 (m45 *1 0,0) (r270 *1 0,0)")
self.assertEqual(p.source_cellview_(False), 1)
self.assertEqual(p.source_cellview, 1)
p.source_cellview = -1
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
p.upper_hier_level = 17
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0) #..17")
self.assertEqual(p.upper_hier_level_(False), 17)
self.assertEqual(p.upper_hier_level, 17)
self.assertEqual(p.has_upper_hier_level(False), True)
self.assertEqual(p.upper_hier_level_relative(), False)
self.assertEqual(p.upper_hier_level_relative(True), False)
p.set_upper_hier_level(11, True)
self.assertEqual(p.upper_hier_level_mode(False), 0)
self.assertEqual(p.upper_hier_level_mode(), 0)
self.assertEqual(p.upper_hier_level, 11)
self.assertEqual(p.upper_hier_level_relative(), True)
self.assertEqual(p.upper_hier_level_relative(True), True)
p.set_upper_hier_level(11, True, 1)
self.assertEqual(p.upper_hier_level, 11)
self.assertEqual(p.upper_hier_level_mode(False), 1)
self.assertEqual(p.upper_hier_level_mode(), 1)
p.set_upper_hier_level(11, True, 2)
self.assertEqual(p.upper_hier_level_mode(False), 2)
self.assertEqual(p.upper_hier_level_mode(), 2)
p.clear_upper_hier_level()
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
self.assertEqual(p.has_upper_hier_level(False), False)
self.assertEqual(p.has_upper_hier_level(), False)
p.lower_hier_level = 17
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0) #17..")
self.assertEqual(p.source, "6/5@* (m45 *1 0,0) (r270 *1 0,0) #17..")
self.assertEqual(p.lower_hier_level_(False), 17)
self.assertEqual(p.lower_hier_level, 17)
self.assertEqual(p.has_lower_hier_level(False), True)
self.assertEqual(p.has_lower_hier_level(), True)
self.assertEqual(p.lower_hier_level_relative(), False)
self.assertEqual(p.lower_hier_level_relative(True), False)
p.set_lower_hier_level(10, True)
self.assertEqual(p.lower_hier_level, 10)
self.assertEqual(p.lower_hier_level_relative(), True)
self.assertEqual(p.lower_hier_level_relative(True), True)
p.set_lower_hier_level(11, True, 1)
self.assertEqual(p.lower_hier_level, 11)
self.assertEqual(p.lower_hier_level_mode(False), 1)
self.assertEqual(p.lower_hier_level_mode(), 1)
p.set_lower_hier_level(11, True, 2)
self.assertEqual(p.lower_hier_level_mode(False), 2)
self.assertEqual(p.lower_hier_level_mode(), 2)
p.clear_lower_hier_level()
self.assertEqual(p.source_(False), "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
self.assertEqual(p.source, "6/5@* (m45 *1 0,0) (r270 *1 0,0)")
self.assertEqual(p.has_lower_hier_level(False), False)
self.assertEqual(p.has_lower_hier_level(), False)
p.dither_pattern = 18
self.assertEqual(p.dither_pattern_(True), 18)
self.assertEqual(p.flat().dither_pattern_(True), 18)
self.assertEqual(p.dither_pattern, 18)
self.assertEqual(p.eff_dither_pattern(), 18)
self.assertEqual(p.eff_dither_pattern(True), 18)
self.assertEqual(p.has_dither_pattern(), True)
self.assertEqual(p.has_dither_pattern(True), True)
p.line_style = 12
self.assertEqual(p.line_style_(True), 12)
self.assertEqual(p.flat().line_style_(True), 12)
self.assertEqual(p.line_style, 12)
self.assertEqual(p.eff_line_style(), 12)
self.assertEqual(p.eff_line_style(True), 12)
self.assertEqual(p.has_line_style(), True)
self.assertEqual(p.has_line_style(True), True)
p.animation = 2
self.assertEqual(p.animation_(True), 2)
self.assertEqual(p.flat().animation_(True), 2)
self.assertEqual(p.animation, 2)
p.marked = True
self.assertEqual(p.marked_(True), True)
self.assertEqual(p.flat().marked_(True), True)
self.assertEqual(p.marked, True)
p.marked = False
self.assertEqual(p.marked_(False), False)
self.assertEqual(p.flat().marked_(False), False)
self.assertEqual(p.marked, False)
p.transparent = True
self.assertEqual(p.transparent_(True), True)
self.assertEqual(p.flat().transparent_(True), True)
self.assertEqual(p.transparent, True)
p.transparent = False
self.assertEqual(p.transparent_(False), False)
self.assertEqual(p.flat().transparent_(False), False)
self.assertEqual(p.transparent, False)
p.visible = True
self.assertEqual(p.visible_(True), True)
self.assertEqual(p.flat().visible_(True), True)
self.assertEqual(p.visible, True)
p.visible = False
self.assertEqual(p.visible_(False), False)
self.assertEqual(p.flat().visible_(False), False)
self.assertEqual(p.visible, False)
p.valid = True
self.assertEqual(p.valid_(True), True)
self.assertEqual(p.flat().valid_(True), True)
self.assertEqual(p.valid, True)
p.valid = False
self.assertEqual(p.valid_(False), False)
self.assertEqual(p.flat().valid_(False), False)
self.assertEqual(p.valid, False)
p.xfill = True
self.assertEqual(p.xfill_(True), True)
self.assertEqual(p.flat().xfill_(True), True)
self.assertEqual(p.xfill, True)
p.xfill = False
self.assertEqual(p.xfill_(False), False)
self.assertEqual(p.flat().xfill_(False), False)
self.assertEqual(p.xfill, False)
p.width = 3
self.assertEqual(p.width_(True), 3)
self.assertEqual(p.flat().width_(True), 3)
self.assertEqual(p.width, 3)
p.frame_color = 0xff000031
self.assertEqual(p.frame_color_(True), 0xff000031)
self.assertEqual(p.flat().frame_color_(True), 0xff000031)
self.assertEqual(p.frame_color, 0xff000031)
self.assertEqual(p.has_frame_color(), True)
self.assertEqual(p.has_frame_color(True), True)
self.assertEqual(p.has_fill_color(), False)
self.assertEqual(p.has_fill_color(True), False)
p.fill_color = 0xff000032
self.assertEqual(p.fill_color_(True), 0xff000032)
self.assertEqual(p.flat().fill_color_(True), 0xff000032)
self.assertEqual(p.fill_color, 0xff000032)
self.assertEqual(p.has_frame_color(), True)
self.assertEqual(p.has_fill_color(), True)
p.frame_brightness = 41
self.assertEqual(p.frame_brightness_(True), 41)
self.assertEqual(p.flat().frame_brightness_(True), 41)
self.assertEqual(p.frame_brightness, 41)
p.fill_brightness = 42
self.assertEqual(p.fill_brightness_(True), 42)
self.assertEqual(p.flat().fill_brightness_(True), 42)
self.assertEqual(p.fill_brightness, 42)
self.assertEqual("#%06x" % p.eff_frame_color(), "#33335b")
self.assertEqual("#%06x" % p.eff_fill_color(), "#34345c")
self.assertEqual("#%06x" % p.eff_frame_color(True), "#33335b")
self.assertEqual("#%06x" % p.eff_fill_color(True), "#34345c")
p.clear_fill_color()
self.assertEqual(p.has_fill_color(), False)
p.clear_frame_color()
self.assertEqual(p.has_frame_color(), False)
p.clear_dither_pattern()
self.assertEqual(p.has_dither_pattern(), False)
p.clear_line_style()
self.assertEqual(p.has_line_style(), False)
pp = pya.LayerPropertiesNode()
self.assertEqual(pp == p, False)
self.assertEqual(pp != p, True)
pp = p.dup()
self.assertEqual(pp == p, True)
self.assertEqual(pp != p, False)
# direct replacement of objects and attributes
def test_3(self):
app = pya.Application.instance()
mw = app.main_window()
mw.close_all()
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", pya.LoadLayoutOptions(), "", 1)
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t10.gds", pya.LoadLayoutOptions(), "", 2)
cv = mw.current_view()
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "1/0@1\n2/0@1\n1/0@2\n2/0@2\n3/0@2\n3/1@2\n4/0@2\n5/0@2\n6/0@2\n6/1@2\n7/0@2\n8/0@2\n8/1@2\n")
cv.clear_layers()
pos = cv.end_layers()
self.assertEqual(pos.current().is_valid(), False)
cv.insert_layer(pos, pya.LayerProperties())
self.assertEqual(pos.current().is_valid(), True)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n")
self.assertEqual(self.lnodes_str2(cv), "*/*@*")
self.assertEqual(cv.begin_layers().current().name, "")
self.assertEqual(cv.begin_layers().current().visible, True)
self.assertEqual(cv.begin_layers().current().dither_pattern, -1)
self.assertEqual(cv.begin_layers().current().line_style, -1)
self.assertEqual(cv.begin_layers().current().valid, True)
self.assertEqual(cv.begin_layers().current().transparent, False)
# test LayerPropertiesNodeRef
pos.current().name = "NAME"
pos.current().visible = False
pos.current().fill_color = 0xff012345
pos.current().frame_color = 0xff123456
pos.current().fill_brightness = 42
pos.current().frame_brightness = 17
pos.current().dither_pattern = 4
pos.current().line_style = 3
pos.current().valid = False
pos.current().transparent = True
pos.current().marked = False
pos.current().xfill = False
pos.current().width = 2
pos.current().animation = 2
self.assertEqual(cv.begin_layers().current().name, "NAME")
self.assertEqual(cv.begin_layers().current().visible, False)
self.assertEqual(cv.begin_layers().current().fill_color, 0xff012345)
self.assertEqual(cv.begin_layers().current().frame_color, 0xff123456)
self.assertEqual(cv.begin_layers().current().fill_brightness, 42)
self.assertEqual(cv.begin_layers().current().frame_brightness, 17)
self.assertEqual(cv.begin_layers().current().dither_pattern, 4)
self.assertEqual(cv.begin_layers().current().line_style, 3)
self.assertEqual(cv.begin_layers().current().valid, False)
self.assertEqual(cv.begin_layers().current().transparent, True)
self.assertEqual(cv.begin_layers().current().marked, False)
self.assertEqual(cv.begin_layers().current().xfill, False)
self.assertEqual(cv.begin_layers().current().width, 2)
self.assertEqual(cv.begin_layers().current().animation, 2)
pos.current().valid = True
new_p = pya.LayerProperties()
new_p.source = "1/0@1"
self.assertEqual(new_p.flat().source, "1/0@1")
self.assertEqual(new_p == new_p.flat(), True)
self.assertEqual(new_p != new_p.flat(), False)
new_p_ref = pos.current().add_child(new_p)
self.assertEqual(new_p_ref.layer_index(), cv.cellview(0).layout().layer(1, 0))
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n")
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1")
p = pos.current().add_child()
p.source = "1/0@2"
self.assertEqual(p.is_valid(), True)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n 1/0@2\n")
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1\n1/0@2")
self.assertEqual(p.layer_index(), cv.cellview(1).layout().layer(1, 0))
self.assertEqual(str(p.bbox()), "(-1.4,1.8;25.16,3.8)")
self.assertEqual(p.view() == cv, True)
self.assertEqual(p.list_index(), 0)
l12_new = pya.LayerProperties()
l12_new.source = "@* #1..2"
self.assertEqual(l12_new.flat().source, "*/*@* #1..2")
self.assertEqual(pos.first_child().current().source, "1/0@1")
self.assertEqual(pos.first_child().current().is_valid(), True)
self.assertEqual(pos.last_child().current().is_valid(), False)
pos.first_child().next().current().assign(l12_new)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n */*@* #1..2\n")
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1\n*/*@* #1..2")
pos.first_child().next_sibling(1).current().source = "@* #3..4"
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 1/0@1\n */*@* #3..4\n")
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n1/0@1\n*/*@* #3..4")
pos.first_child().to_sibling(1).next_sibling(-1).current().source = "7/0"
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "*/*@*\n 7/0@1\n */*@* #3..4\n")
self.assertEqual(self.lnodes_str2(cv), "*/*@*\n7/0@1\n*/*@* #3..4")
self.assertEqual(self.lnodes_str3(cv, 0), "*/*@*\n7/0@1\n*/*@* #3..4")
self.assertEqual(self.lnodes_str3(cv, 1), "")
nn = pya.LayerPropertiesNode()
nn.source = "TOP"
nn1 = pya.LayerPropertiesNode()
nn1.source = "nn1"
nn2 = pya.LayerProperties()
nn2.source = "nn1"
nn1.add_child(nn2)
nn.add_child(nn1)
pos.current().assign(nn)
self.assertEqual(pos.current().id(), nn.id())
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "TOP@1\n nn1@1\n nn1@1\n")
self.assertEqual(self.lnodes_str2(cv), "TOP@1\nnn1@1\nnn1@1")
mw.close_all()
# propagation of "real" attributes through the hierarchy
def test_4(self):
app = pya.Application.instance()
mw = app.main_window()
mw.close_all()
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t10.gds", 2)
cv = mw.current_view()
cv.clear_layers()
pos = cv.end_layers()
self.assertEqual(pos.current().is_valid(), False)
cv.insert_layer(pos, pya.LayerProperties())
new_p = pya.LayerProperties()
new_p.source = "1/0@1"
pos.current().add_child(new_p)
self.assertEqual(pos.current().visible_(True), True)
self.assertEqual(pos.current().visible_(False), True)
self.assertEqual(pos.first_child().current().visible_(True), True)
self.assertEqual(pos.first_child().current().visible_(False), True)
pos.current().visible = False
self.assertEqual(pos.current().visible_(True), False)
self.assertEqual(pos.current().visible_(False), False)
self.assertEqual(pos.first_child().current().visible_(True), False)
self.assertEqual(pos.first_child().current().visible_(False), True)
mw.close_all()
# delete method of iterator
def test_5(self):
app = pya.Application.instance()
mw = app.main_window()
mw.close_all()
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
cv = mw.current_view()
cv.clear_layers()
new_p = pya.LayerProperties()
new_p.source = "1/0@1"
cv.insert_layer(0, cv.end_layers(), new_p)
new_p = pya.LayerProperties()
new_p.source = "2/0@1"
cv.insert_layer(0, cv.end_layers(), new_p)
pos = cv.begin_layers()
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "1/0@1\n2/0@1\n")
self.assertEqual(pos.at_end(), False)
self.assertEqual(pos.current().source, "1/0@1")
self.assertEqual(pos.current().is_valid(), True)
pos.current().delete()
self.assertEqual(pos.current().source, "2/0@1")
self.assertEqual(pos.current().is_valid(), True)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "2/0@1\n")
self.assertEqual(pos.at_end(), False)
pos.current().delete()
self.assertEqual(pos.current().is_valid(), False)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
self.assertEqual(pos.at_end(), True)
pos.current().delete()
self.assertEqual(pos.current().is_valid(), False)
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "")
self.assertEqual(pos.at_end(), True)
# With hierarchy
cv.clear_layers()
new_p = pya.LayerProperties()
new_p.source = "1/0@1"
cv.insert_layer(0, cv.end_layers(), new_p)
new_p = pya.LayerProperties()
new_p.source = "2/0@1"
cv.insert_layer(0, cv.end_layers(), new_p)
new_p = pya.LayerProperties()
new_p.source = "3/0@1"
cv.insert_layer(0, cv.end_layers(), new_p)
pos = cv.begin_layers()
pos.next_sibling(1)
c1 = pos.current().add_child()
c1.source = "21/0@1"
c2 = pos.current().add_child()
c2.source = "22/0@1"
posn = cv.begin_layers()
posn.next_sibling(2)
c3 = posn.current().add_child()
c3.source = "31/0@1"
self.assertEqual(self.lnodes_str("", cv.begin_layers()), "1/0@1\n2/0@1\n 21/0@1\n 22/0@1\n3/0@1\n 31/0@1\n")
pc = pos.first_child()
self.assertEqual(pc.current().source, "21/0@1")
self.assertEqual(pc.current().is_valid(), True)
self.assertEqual(pc.at_end(), False)
pc.current().delete()
self.assertEqual(pc.current().source, "22/0@1")
self.assertEqual(pc.current().is_valid(), True)
self.assertEqual(pc.at_end(), False)
pc.current().delete()
self.assertEqual(pc.at_end(), True)
self.assertEqual(pc.current().is_valid(), False)
mw.close_all()
# custom stipples and line styles
def test_6(self):
app = pya.Application.instance()
mw = app.main_window()
mw.close_all()
mw.load_layout(os.getenv("TESTSRC") + "/testdata/gds/t11.gds", 1)
cv = mw.current_view()
cv.clear_stipples()
self.assertEqual(cv.get_stipple(0), "*\n")
index = cv.add_stipple("something", [ 0x1, 0x2, 0x4, 0x8 ], 4)
self.assertEqual(cv.get_stipple(index), "...*\n..*.\n.*..\n*...\n")
cv.remove_stipple(index)
self.assertEqual(cv.get_stipple(index), "*\n")
index = cv.add_stipple("something", ".**.\n*..*\n.*.*\n*.*.")
self.assertEqual(cv.get_stipple(index), ".**.\n*..*\n.*.*\n*.*.\n")
cv.clear_stipples()
self.assertEqual(cv.get_stipple(index), "*\n")
cv.clear_line_styles()
self.assertEqual(cv.get_line_style(0), "")
index = cv.add_line_style("something", 0x5, 4)
self.assertEqual(cv.get_line_style(index), "*.*.")
cv.remove_line_style(index)
self.assertEqual(cv.get_line_style(index), "")
index = cv.add_line_style("something", ".**.*..*")
self.assertEqual(cv.get_line_style(index), ".**.*..*")
cv.clear_line_styles()
self.assertEqual(cv.get_line_style(index), "")
mw.close_all()
# run unit tests
if __name__ == '__main__':
suite = unittest.TestSuite()
# NOTE: Use this instead of loadTestsfromTestCase to select a specific test:
# suite.addTest(BasicTest("test_26"))
suite = unittest.TestLoader().loadTestsFromTestCase(LAYLayersTest)
# Only runs with Application available
if "Application" in pya.__all__ and not unittest.TextTestRunner(verbosity = 1).run(suite).wasSuccessful():
sys.exit(1)

View File

@ -703,6 +703,44 @@ class LAYLayers_TestClass < TestBase
assert_equal( lnodes_str( "", cv.begin_layers ), "*/*@*\n" )
assert_equal( lnodes_str2(cv), "*/*@*" )
assert_equal( cv.begin_layers.current.name, "" )
assert_equal( cv.begin_layers.current.visible?, true )
assert_equal( cv.begin_layers.current.dither_pattern, -1 )
assert_equal( cv.begin_layers.current.line_style, -1 )
assert_equal( cv.begin_layers.current.valid?, true )
assert_equal( cv.begin_layers.current.transparent?, false )
# test LayerPropertiesNodeRef
pos.current.name = "NAME"
pos.current.visible = false
pos.current.fill_color = 0xff012345
pos.current.frame_color = 0xff123456
pos.current.fill_brightness = 42
pos.current.frame_brightness = 17
pos.current.dither_pattern = 4
pos.current.line_style = 3
pos.current.valid = false
pos.current.transparent = true
pos.current.marked = false
pos.current.xfill = false
pos.current.width = 2
pos.current.animation = 2
assert_equal( cv.begin_layers.current.name, "NAME" )
assert_equal( cv.begin_layers.current.visible?, false )
assert_equal( cv.begin_layers.current.fill_color, 0xff012345 )
assert_equal( cv.begin_layers.current.frame_color, 0xff123456 )
assert_equal( cv.begin_layers.current.fill_brightness, 42 )
assert_equal( cv.begin_layers.current.frame_brightness, 17 )
assert_equal( cv.begin_layers.current.dither_pattern, 4 )
assert_equal( cv.begin_layers.current.line_style, 3 )
assert_equal( cv.begin_layers.current.valid?, false )
assert_equal( cv.begin_layers.current.transparent?, true )
assert_equal( cv.begin_layers.current.marked?, false )
assert_equal( cv.begin_layers.current.xfill?, false )
assert_equal( cv.begin_layers.current.width, 2 )
assert_equal( cv.begin_layers.current.animation, 2 )
new_p = RBA::LayerProperties::new
new_p.source = "1/0@1"
assert_equal( new_p.flat.source, "1/0@1" )