Fixed #42 (headless mode support with Qt5/-zz)

This commit is contained in:
Matthias Koefferlein
2017-12-27 21:44:14 +01:00
43 changed files with 1471 additions and 602 deletions
+148
View File
@@ -0,0 +1,148 @@
# encoding: UTF-8
# KLayout Layout Viewer
# Copyright (C) 2006-2017 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")
# Tests for the klayout executable
#
# This tests actually runs inside a KLayout/unit_tests instance but
# only for providing the test automation.
class KLayoutMain_TestClass < TestBase
def test_1
# Basic
version = `./klayout -v`
assert_equal(version, "#{RBA::Application.instance.version}\n")
end
def test_2
# Basic Ruby
out = `./klayout -b -rd v1=42 -rd v2=hello -r #{File.join(File.dirname(__FILE__), "test.rb")}`
assert_equal(out, "Variable v1=42 v2=hello\n")
out = `./klayout -b -rd v1=42 -rd v2=hello -r #{File.join(File.dirname(__FILE__), "test.rb")} -rm #{File.join(File.dirname(__FILE__), "test2.rb")} -rm #{File.join(File.dirname(__FILE__), "test3.rb")}`
assert_equal(out, "test2\ntest3\nVariable v1=42 v2=hello\n")
end
def test_3
# Basic Python
out = `./klayout -b -rd v1=42 -rd v2=hello -r #{File.join(File.dirname(__FILE__), "test.py")}`
assert_equal(out, "Variable v1=42 v2=hello\n")
end
def test_4
# Application class
# QCoreApplication for (headless) mode
out = `./klayout -b -r #{File.join(File.dirname(__FILE__), "test_app.rb")}`
assert_equal(out, "RBA::Application superclass RBA::QCoreApplication_Native\nMainWindow is not there\n")
# QApplication for GUI mode
out = `./klayout -z -nc -rx -r #{File.join(File.dirname(__FILE__), "test_app.rb")}`
assert_equal(out, "RBA::Application superclass RBA::QApplication_Native\nMainWindow is there\n")
end
def test_5
# Script variables
out = `./klayout -b -wd tv1=17 -wd tv2=25 -wd tv3 -r #{File.join(File.dirname(__FILE__), "test_script.rb")}`
assert_equal(out, "42\ntrue\n")
end
def test_6
# Editable / Non-editable mode
out = `./klayout -b -ne -r #{File.join(File.dirname(__FILE__), "test_em.rb")}`
assert_equal(out, "false\n")
out = `./klayout -b -e -r #{File.join(File.dirname(__FILE__), "test_em.rb")}`
assert_equal(out, "true\n")
end
def test_7
cfg_file = File.join($ut_testtmp, "config.xml")
File.open(cfg_file, "w") { |file| file.puts("<config/>") }
# Special configuration file
`./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_set_config1.rb")}`
out = `./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_read_config.rb")}`
assert_equal(out, "42\n")
# Update
`./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_set_config2.rb")}`
out = `./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_read_config.rb")}`
assert_equal(out, "17\n")
# Reset
`./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_set_config1.rb")}`
out = `./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_read_config.rb")}`
assert_equal(out, "42\n")
# No update
`./klayout -b -t -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_set_config2.rb")}`
out = `./klayout -b -c #{cfg_file} -r #{File.join(File.dirname(__FILE__), "test_read_config.rb")}`
assert_equal(out, "42\n")
end
def test_8
# Loading layouts
out = `./klayout -z -nc -rx #{File.join(File.dirname(__FILE__), "test1.gds")} -r #{File.join(File.dirname(__FILE__), "test_lay.rb")}`
assert_equal(out, "TOP1\n")
out = `./klayout -z -nc -rx #{File.join(File.dirname(__FILE__), "test1.gds")} #{File.join(File.dirname(__FILE__), "test2.gds")} -r #{File.join(File.dirname(__FILE__), "test_lay2.rb")}`
assert_equal(out, "TOP1\nTOP2\n")
out = `./klayout -z -nc -rx #{File.join(File.dirname(__FILE__), "test1.gds")} #{File.join(File.dirname(__FILE__), "test2.gds")} -s -r #{File.join(File.dirname(__FILE__), "test_lay2.rb")}`
assert_equal(out, "TOP1;TOP2\n")
end
def test_9
# Sessions
out = `./klayout -z -nc -rx -u #{File.join(File.dirname(__FILE__), "session.lys")} -r #{File.join(File.dirname(__FILE__), "test_lay2.rb")}`
assert_equal(out, "TOP2;TOP1\n")
end
end
load("test_epilogue.rb")
+214
View File
@@ -0,0 +1,214 @@
<?xml version="1.0" encoding="utf-8"?>
<session>
<window-width>1392</window-width>
<window-height>912</window-height>
<window-state>AAAA/wAAAAD9AAAAAgAAAAAAAAC5AAADLvwCAAAAAvsAAAAqAG4AYQB2AGkAZwBhAHQAbwByAF8AZABvAGMAawBfAHcAaQBkAGcAZQB0AAAAAAD/////AAAAkgD////7AAAAHABoAHAAXwBkAG8AYwBrAF8AdwBpAGQAZwBlAHQBAAAATAAAAy4AAAAZAP///wAAAAEAAAEdAAADLvwCAAAAAvsAAAAcAGwAcABfAGQAbwBjAGsAXwB3AGkAZABnAGUAdAEAAABMAAACnQAAABkA////+wAAABwAbAB0AF8AZABvAGMAawBfAHcAaQBkAGcAZQB0AQAAAu8AAACLAAAAiwAAAIsAAAOOAAADLgAAAAQAAAAEAAAACAAAAAj8AAAAAQAAAAIAAAABAAAADgB0AG8AbwBsAGIAYQByAQAAAAD/////AAAAAAAAAAA=</window-state>
<window-geometry>AdnQywABAAAAAAEpAAAAFQAABq4AAAPSAAABNAAAADgAAAajAAADxwAAAAAAAA==</window-geometry>
<current-view>0</current-view>
<layout>
<name>test1.gds</name>
<file-path>test1.gds</file-path>
<save-options-valid>false</save-options-valid>
<save-options>
<oasis>
<compression-level>2</compression-level>
<write-cblocks>false</write-cblocks>
<strict-mode>false</strict-mode>
<write-std-properties>1</write-std-properties>
<subst-char>*</subst-char>
<permissive>false</permissive>
</oasis>
<gds2>
<write-timestamps>true</write-timestamps>
<write-cell-properties>false</write-cell-properties>
<write-file-properties>false</write-file-properties>
<no-zero-length-paths>false</no-zero-length-paths>
<multi-xy-records>false</multi-xy-records>
<max-vertex-count>8000</max-vertex-count>
<max-cellname-length>32000</max-cellname-length>
<libname>LIB</libname>
</gds2>
<cif>
<polygon-mode>0</polygon-mode>
</cif>
<cif>
<dummy-calls>false</dummy-calls>
<blank-separator>false</blank-separator>
</cif>
</save-options>
<load-options>
<common>
<create-other-layers>true</create-other-layers>
<layer-map>layer_map()</layer-map>
<enable-properties>true</enable-properties>
<enable-text-objects>true</enable-text-objects>
</common>
<gds2>
<box-mode>1</box-mode>
<allow-big-records>true</allow-big-records>
<allow-multi-xy-records>true</allow-multi-xy-records>
</gds2>
<dxf>
<dbu>0.001</dbu>
<unit>1</unit>
<text-scaling>100</text-scaling>
<circle-points>100</circle-points>
<circle-accuracy>0</circle-accuracy>
<polyline-mode>0</polyline-mode>
<render-texts-as-polygons>false</render-texts-as-polygons>
<keep-other-cells>false</keep-other-cells>
<create-other-layers>true</create-other-layers>
<layer-map>layer_map()</layer-map>
</dxf>
<cif>
<wire-mode>0</wire-mode>
<dbu>0.001</dbu>
<layer-map>layer_map()</layer-map>
<create-other-layers>true</create-other-layers>
</cif>
</load-options>
</layout>
<layout>
<name>test2.gds</name>
<file-path>test2.gds</file-path>
<save-options-valid>true</save-options-valid>
<save-options>
<oasis>
<compression-level>2</compression-level>
<write-cblocks>false</write-cblocks>
<strict-mode>false</strict-mode>
<write-std-properties>1</write-std-properties>
<subst-char>*</subst-char>
<permissive>false</permissive>
</oasis>
<gds2>
<write-timestamps>true</write-timestamps>
<write-cell-properties>false</write-cell-properties>
<write-file-properties>false</write-file-properties>
<no-zero-length-paths>false</no-zero-length-paths>
<multi-xy-records>false</multi-xy-records>
<max-vertex-count>8000</max-vertex-count>
<max-cellname-length>32000</max-cellname-length>
<libname>LIB</libname>
</gds2>
<cif>
<polygon-mode>0</polygon-mode>
</cif>
<cif>
<dummy-calls>false</dummy-calls>
<blank-separator>false</blank-separator>
</cif>
</save-options>
<load-options>
<common>
<create-other-layers>true</create-other-layers>
<layer-map>layer_map()</layer-map>
<enable-properties>true</enable-properties>
<enable-text-objects>true</enable-text-objects>
</common>
<gds2>
<box-mode>1</box-mode>
<allow-big-records>true</allow-big-records>
<allow-multi-xy-records>true</allow-multi-xy-records>
</gds2>
<dxf>
<dbu>0.001</dbu>
<unit>1</unit>
<text-scaling>100</text-scaling>
<circle-points>100</circle-points>
<circle-accuracy>0</circle-accuracy>
<polyline-mode>0</polyline-mode>
<render-texts-as-polygons>false</render-texts-as-polygons>
<keep-other-cells>false</keep-other-cells>
<create-other-layers>true</create-other-layers>
<layer-map>layer_map()</layer-map>
</dxf>
<cif>
<wire-mode>0</wire-mode>
<dbu>0.001</dbu>
<layer-map>layer_map()</layer-map>
<create-other-layers>true</create-other-layers>
</cif>
</load-options>
</layout>
<view>
<title/>
<active-cellview-index>1</active-cellview-index>
<display>
<x-left>-0.892701664533</x-left>
<x-right>8.8947503201</x-right>
<y-bottom>-0.204353393086</y-bottom>
<y-top>8.19564660691</y-top>
<min-hier>0</min-hier>
<max-hier>1</max-hier>
<cellpaths>
<cellpath>
<cellname>TOP2</cellname>
</cellpath>
<cellpath>
<cellname>TOP1</cellname>
</cellpath>
</cellpaths>
</display>
<cellviews>
<cellview>
<layout-ref>test2.gds</layout-ref>
<tech-name/>
<hidden-cells>
</hidden-cells>
</cellview>
<cellview>
<layout-ref>test1.gds</layout-ref>
<tech-name/>
<hidden-cells>
</hidden-cells>
</cellview>
</cellviews>
<bookmarks>
</bookmarks>
<rdb-files>
</rdb-files>
<current-layer-property-tab>0</current-layer-property-tab>
<layer-properties-tabs>
<layer-properties>
<properties>
<frame-color>#ff80a8</frame-color>
<fill-color>#ff80a8</fill-color>
<frame-brightness>0</frame-brightness>
<fill-brightness>0</fill-brightness>
<dither-pattern>I9</dither-pattern>
<line-style/>
<valid>true</valid>
<visible>true</visible>
<transparent>false</transparent>
<width>1</width>
<marked>false</marked>
<xfill>false</xfill>
<animation>0</animation>
<name/>
<source>2/0@1</source>
</properties>
<properties>
<frame-color>#ff80a8</frame-color>
<fill-color>#ff80a8</fill-color>
<frame-brightness>0</frame-brightness>
<fill-brightness>0</fill-brightness>
<dither-pattern>I9</dither-pattern>
<line-style/>
<valid>true</valid>
<visible>true</visible>
<transparent>false</transparent>
<width/>
<marked>false</marked>
<xfill>false</xfill>
<animation>0</animation>
<name/>
<source>1/0@2</source>
</properties>
<name/>
</layer-properties>
</layer-properties-tabs>
<annotations>
</annotations>
</view>
</session>
+3
View File
@@ -0,0 +1,3 @@
print("Variable v1="+str(v1)+" v2="+str(v2))
+3
View File
@@ -0,0 +1,3 @@
puts "Variable v1=#{$v1} v2=#{$v2}"
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
puts "test2"
+3
View File
@@ -0,0 +1,3 @@
puts "test3"
+4
View File
@@ -0,0 +1,4 @@
puts "RBA::Application superclass " + RBA::Application.instance.class.superclass.to_s
puts "MainWindow is " + (RBA::Application.instance.main_window ? "there" : "not there")
+3
View File
@@ -0,0 +1,3 @@
puts RBA::Application.instance.is_editable?.inspect
+36
View File
@@ -0,0 +1,36 @@
# In the test environment, we cannot make sure that we destroy the ruby interpreter before the RBA
# environment is shut down. Therefore we must release all RBA objects by explicitly calling the GC
# and start the test suite manually.
err = 0
any = nil
repeat = (ENV["TESTREPEAT"] || "1").to_i
class MyTestRunner < Test::Unit::UI::Console::TestRunner
def initialize(suite, *args)
super(suite, *args)
end
def test_started(name)
super
end
end
Object.constants.each do |c|
if c.to_s =~ /_TestClass$/
repeat.times do
r = MyTestRunner::new(Object.const_get(c)).start
err += r.error_count + r.failure_count
end
any = true
end
end
if !any
raise("No test class defined (any ending with _TestClass)")
end
if err > 0
raise("Tests failed (#{err} Errors + Failures)")
end
+3
View File
@@ -0,0 +1,3 @@
puts RBA::LayoutView::current.active_cellview.layout.top_cell.name
+8
View File
@@ -0,0 +1,8 @@
RBA::Application::instance.main_window.views.times do |v|
view = RBA::Application::instance.main_window.view(v)
tc = []
view.cellviews.times { |cv| tc << view.cellview(cv).layout.top_cell.name }
puts tc.join(";")
end
+37
View File
@@ -0,0 +1,37 @@
# in MSVC environment:
if ENV["RUBY"]
ruby_libs = "#{ENV["RUBY"]}/lib/ruby/#{RUBY_VERSION}"
if !$:.member?(ruby_libs)
$:.push(ruby_libs)
end
end
# Set this to true to disable some tests involving exceptions
$leak_check = ENV["TEST_LEAK_CHECK"]
# Fetch location of source files and the temp files
$ut_testsrc = ENV["TESTSRC"] || raise("Environment variable $TESTSRC not set")
$ut_testtmp = ENV["TESTTMP_WITH_NAME"] || ENV["TESTTMP"] || raise("Environment variable $TESTTMP not set")
# Pull packages from vendor drop-in
vendor = File.join($ut_testsrc, "testdata", "vendor", "ruby")
if !$:.member?(vendor)
$:.unshift(vendor)
end
# Require Test::Unit
require 'test/unit/ui/console/testrunner'
# TestBase is an alias for "TestCase"
Object.const_defined?(:TestBase) && Object.send(:remove_const, :TestBase)
TestBase = Test::Unit::TestCase
# undefine existing classes
Object.constants.each do |c|
if c.to_s =~ /_TestClass$/
Object.send(:remove_const, c)
end
end
+3
View File
@@ -0,0 +1,3 @@
puts RBA::Application.instance.get_config("key4test")
+4
View File
@@ -0,0 +1,4 @@
puts RBA::Expression::new("to_i(tv1)+to_i(tv2)").eval
puts RBA::Expression::new("tv3").eval
+3
View File
@@ -0,0 +1,3 @@
RBA::Application.instance.set_config("key4test", "42")
+3
View File
@@ -0,0 +1,3 @@
RBA::Application.instance.set_config("key4test", "17")
+3 -76
View File
@@ -1,81 +1,8 @@
# encoding: UTF-8
# extend A
class RBA::A
alias_method :org_initialize, :initialize
def initialize(*args)
org_initialize(*args)
@offset = nil
end
def s( o )
@offset = o
end
def g
return @offset
end
def m
return @offset+a1
end
def call_a10_prot(f)
a10_prot(f)
end
def inspect
if @offset
@offset.to_s
else
"a1=" + self.a1.to_s
end
end
private
@offset
end
class MyException < RuntimeError
def initialize(s)
super(s)
end
end
class XEdge < RBA::Edge
def initialize
super(RBA::Point.new(1,2), RBA::Point.new(3,4))
end
end
class RBA::E
def m
@m
end
def m=(x)
@m = x
end
@m = nil
end
class RBAGObject < RBA::GObject
def initialize(z)
super()
@z = z
end
# reimplementation of "virtual int g()"
def g
return @z*2
end
end
class RBAGFactory < RBA::GFactory
def initialize
super()
end
# reimplementation of "virtual GObject *f(int)"
def f(z)
return RBAGObject::new(z)
end
end
# NOTE: we need to do a "require" here since basic_testcore_defs.rb is not
# safe in multiple inclusions
require File.expand_path('../basic_testcore_defs', __FILE__)
class Basic_TestClass < TestBase
+78
View File
@@ -0,0 +1,78 @@
# extend A
class RBA::A
alias_method :org_initialize, :initialize
def initialize(*args)
org_initialize(*args)
@offset = nil
end
def s( o )
@offset = o
end
def g
return @offset
end
def m
return @offset+a1
end
def call_a10_prot(f)
a10_prot(f)
end
def inspect
if @offset
@offset.to_s
else
"a1=" + self.a1.to_s
end
end
private
@offset
end
class MyException < RuntimeError
def initialize(s)
super(s)
end
end
class XEdge < RBA::Edge
def initialize
super(RBA::Point.new(1,2), RBA::Point.new(3,4))
end
end
class RBA::E
def m
@m
end
def m=(x)
@m = x
end
@m = nil
end
class RBAGObject < RBA::GObject
def initialize(z)
super()
@z = z
end
# reimplementation of "virtual int g()"
def g
return @z*2
end
end
class RBAGFactory < RBA::GFactory
def initialize
super()
end
# reimplementation of "virtual GObject *f(int)"
def f(z)
return RBAGObject::new(z)
end
end