aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/pyunit/Current.vhdl30
-rw-r--r--testsuite/pyunit/dom/AllSources.py23
-rw-r--r--testsuite/pyunit/dom/Expressions.py46
-rw-r--r--testsuite/pyunit/dom/Literals.py46
-rw-r--r--testsuite/pyunit/dom/Sanity.py50
-rw-r--r--testsuite/pyunit/dom/SimpleEntity.py90
-rw-r--r--testsuite/pyunit/dom/SimplePackage.py70
-rw-r--r--testsuite/pyunit/dom/__init__.py32
-rw-r--r--testsuite/pyunit/libghdl/Initialize.py122
-rw-r--r--testsuite/pyunit/lsp/LanguageServer.py315
10 files changed, 532 insertions, 292 deletions
diff --git a/testsuite/pyunit/Current.vhdl b/testsuite/pyunit/Current.vhdl
index 8653cb088..ff03e1d04 100644
--- a/testsuite/pyunit/Current.vhdl
+++ b/testsuite/pyunit/Current.vhdl
@@ -20,16 +20,36 @@ end entity entity_1;
architecture behav of entity_1 is
constant MAX : positive := -25;
- signal rst : std_logic := foo'('U');
+ signal rst : std_logic := foo('U');
+-- signal vec : bit_vector(pack.input'bar'range);
type newInt is range -4 to 3;
+ type newFp is range 4.3 downto -3.9;
+ type arr is array(natural range <>, enum range <>) of integer(3 downto 0);
+ type rec is record
+ elem1 : bit;
+ elem2 : boolean;
+ elem3 : integer_vector(3 downto 0);
+ elem4 : natural range 7 to 8;
+ end record;
+ type enum is (e1, e2, e3);
+ type acc is access bar;
subtype uint8 is integer range 0 to 255;
- function foo(a : integer; b : boolean) return bit is
+-- file f : text;
+
+ function func (a : integer; b : boolean) return bit is
begin
end function;
+ shared variable pt_var : lib.pack.prot;
+
+ procedure proc(spam : egg) is
+ begin
+
+ end procedure;
+
alias bar is boolean;
begin
process(Clock)
@@ -46,6 +66,12 @@ end architecture behav;
package package_1 is
constant ghdl : float := (3, 5, 0 to 2 => 5, 3 => 4, name => 10); -- 2.3;
+
+ component comp is
+ port (
+ clk : std
+ );
+ end component;
end package;
package body package_1 is
diff --git a/testsuite/pyunit/dom/AllSources.py b/testsuite/pyunit/dom/AllSources.py
deleted file mode 100644
index 7dabf1b10..000000000
--- a/testsuite/pyunit/dom/AllSources.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from sys import executable
-from subprocess import check_call, STDOUT
-from pathlib import Path
-from glob import glob
-from pytest import mark
-
-if __name__ == "__main__":
- print("ERROR: you called a testcase declaration file as an executable module.")
- print("Use: 'python -m unitest <testcase module>'")
- exit(1)
-
-
-@mark.parametrize(
- "file",
- glob(str(Path(__file__).resolve().parent.parent.parent / 'sanity' / '*' / '*.vhdl'), recursive=True)
-)
-@mark.xfail
-def test_AllVHDLSources(file):
- check_call([
- executable,
- str(Path(__file__).resolve().parent.parent.parent.parent / 'pyGHDL' / 'cli' / 'DOM.py'),
- file
- ], stderr=STDOUT)
diff --git a/testsuite/pyunit/dom/Expressions.py b/testsuite/pyunit/dom/Expressions.py
index a7afb30ba..f9c066f52 100644
--- a/testsuite/pyunit/dom/Expressions.py
+++ b/testsuite/pyunit/dom/Expressions.py
@@ -1,11 +1,43 @@
-from pathlib import Path
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Testsuite: Check libghdl IIR translation to DOM for expressions.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# 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, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pathlib import Path
from textwrap import dedent
from unittest import TestCase
from pyGHDL.dom.DesignUnit import Package
from pyGHDL.dom import Expression
-from pyGHDL.dom.NonStandard import Design, Document
+from pyGHDL.dom.NonStandard import Design, Document
from pyGHDL.dom.Symbol import SimpleObjectOrFunctionCallSymbol
from pyGHDL.dom.Object import Constant
from pyGHDL.dom.Expression import InverseExpression
@@ -20,13 +52,17 @@ class Expressions(TestCase):
_root = Path(__file__).resolve().parent.parent
def test_NotExpression(self):
- self._filename: Path = self._root / "{className}.vhdl".format(className=self.__class__.__name__)
+ self._filename: Path = self._root / "{className}.vhdl".format(
+ className=self.__class__.__name__
+ )
- sourceCode = dedent("""\
+ sourceCode = dedent(
+ """\
package package_1 is
constant c0 : boolean := not true;
end package;
- """)
+ """
+ )
with self._filename.open(mode="w", encoding="utf-8") as file:
file.write(sourceCode)
diff --git a/testsuite/pyunit/dom/Literals.py b/testsuite/pyunit/dom/Literals.py
index c542ebfe5..ebd702f5e 100644
--- a/testsuite/pyunit/dom/Literals.py
+++ b/testsuite/pyunit/dom/Literals.py
@@ -1,8 +1,40 @@
-from pathlib import Path
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Testsuite: Check libghdl IIR translation to DOM for literals.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# 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, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pathlib import Path
from textwrap import dedent
from unittest import TestCase
-from pyGHDL.dom.NonStandard import Design, Document
+from pyGHDL.dom.NonStandard import Design, Document
from pyGHDL.dom.Object import Constant
from pyGHDL.dom.Literal import IntegerLiteral
@@ -17,16 +49,20 @@ class Literals(TestCase):
_root = Path(__file__).resolve().parent.parent
def test_IntegerLiteral(self):
- self._filename: Path = self._root / "{className}.vhdl".format(className=self.__class__.__name__)
+ self._filename: Path = self._root / "{className}.vhdl".format(
+ className=self.__class__.__name__
+ )
- sourceCode = dedent("""\
+ sourceCode = dedent(
+ """\
package package_1 is
constant c0 : integer := 0;
constant c1 : integer := 1;
constant c2 : integer := 1024;
constant c3 : integer := 1048576;
end package;
- """)
+ """
+ )
expected = (0, 1, 1024, 1048576)
with self._filename.open(mode="w", encoding="utf-8") as file:
diff --git a/testsuite/pyunit/dom/Sanity.py b/testsuite/pyunit/dom/Sanity.py
new file mode 100644
index 000000000..10258c38c
--- /dev/null
+++ b/testsuite/pyunit/dom/Sanity.py
@@ -0,0 +1,50 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Unai Martinez-Corral
+#
+# Testsuite: Parse files from sanity checks
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# 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, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from sys import executable
+from subprocess import check_call, STDOUT
+from pathlib import Path
+from pytest import mark
+
+if __name__ == "__main__":
+ print("ERROR: you called a testcase declaration file as an executable module.")
+ print("Use: 'python -m unitest <testcase module>'")
+ exit(1)
+
+_TESTSUITE_ROOT = Path(__file__).parent.parent.parent.resolve()
+_GHDL_ROOT = _TESTSUITE_ROOT.parent
+
+
+@mark.xfail
+@mark.parametrize("file", [str(f) for f in _TESTSUITE_ROOT.glob("sanity/**/*.vhdl")])
+def test_AllVHDLSources(file):
+ check_call([executable, _GHDL_ROOT / "pyGHDL/cli/DOM.py", file], stderr=STDOUT)
diff --git a/testsuite/pyunit/dom/SimpleEntity.py b/testsuite/pyunit/dom/SimpleEntity.py
index 8199fe7cc..9ee55508c 100644
--- a/testsuite/pyunit/dom/SimpleEntity.py
+++ b/testsuite/pyunit/dom/SimpleEntity.py
@@ -1,46 +1,78 @@
-from pathlib import Path
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Testsuite: Check libghdl IIR translation with a simple entity.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# 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, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pathlib import Path
from unittest import TestCase
-from pyGHDL.dom.NonStandard import Design, Document
+from pyGHDL.dom.NonStandard import Design, Document
if __name__ == "__main__":
- print("ERROR: you called a testcase declaration file as an executable module.")
- print("Use: 'python -m unitest <testcase module>'")
- exit(1)
+ print("ERROR: you called a testcase declaration file as an executable module.")
+ print("Use: 'python -m unitest <testcase module>'")
+ exit(1)
class SimpleEntity(TestCase):
- _root = Path(__file__).resolve().parent.parent
- _filename : Path = _root / "SimpleEntity.vhdl"
+ _root = Path(__file__).resolve().parent.parent
+ _filename: Path = _root / "SimpleEntity.vhdl"
- def test_Design(self):
- design = Design()
+ def test_Design(self):
+ design = Design()
- self.assertIsNotNone(design)
+ self.assertIsNotNone(design)
- # def test_Library(self):
- # library = Library()
+ # def test_Library(self):
+ # library = Library()
- def test_Document(self):
- design = Design()
- document = Document(self._filename)
- design.Documents.append(document)
+ def test_Document(self):
+ design = Design()
+ document = Document(self._filename)
+ design.Documents.append(document)
- self.assertTrue(len(design.Documents) == 1)
+ self.assertTrue(len(design.Documents) == 1)
- def test_Entity(self):
- design = Design()
- document = Document(self._filename)
- design.Documents.append(document)
+ def test_Entity(self):
+ design = Design()
+ document = Document(self._filename)
+ design.Documents.append(document)
- self.assertEqual(len(design.Documents[0].Entities), 1)
- self.assertTrue(design.Documents[0].Entities[0].Name == "entity_1")
+ self.assertEqual(len(design.Documents[0].Entities), 1)
+ self.assertTrue(design.Documents[0].Entities[0].Name == "entity_1")
- def test_Architecture(self):
- design = Design()
- document = Document(self._filename)
- design.Documents.append(document)
+ def test_Architecture(self):
+ design = Design()
+ document = Document(self._filename)
+ design.Documents.append(document)
- self.assertEqual(len(design.Documents[0].Architectures), 1)
- self.assertTrue(design.Documents[0].Architectures[0].Name == "behav")
+ self.assertEqual(len(design.Documents[0].Architectures), 1)
+ self.assertTrue(design.Documents[0].Architectures[0].Name == "behav")
diff --git a/testsuite/pyunit/dom/SimplePackage.py b/testsuite/pyunit/dom/SimplePackage.py
index 5b16e74b8..399a676b4 100644
--- a/testsuite/pyunit/dom/SimplePackage.py
+++ b/testsuite/pyunit/dom/SimplePackage.py
@@ -1,31 +1,63 @@
-from pathlib import Path
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Testsuite: Check libghdl IIR translation with a simple package.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# 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, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
+from pathlib import Path
from unittest import TestCase
-from pyGHDL.dom.NonStandard import Design, Document
+from pyGHDL.dom.NonStandard import Design, Document
if __name__ == "__main__":
- print("ERROR: you called a testcase declaration file as an executable module.")
- print("Use: 'python -m unitest <testcase module>'")
- exit(1)
+ print("ERROR: you called a testcase declaration file as an executable module.")
+ print("Use: 'python -m unitest <testcase module>'")
+ exit(1)
class SimplePackage(TestCase):
- _root = Path(__file__).resolve().parent.parent
- _filename : Path = _root / "SimplePackage.vhdl"
+ _root = Path(__file__).resolve().parent.parent
+ _filename: Path = _root / "SimplePackage.vhdl"
- def test_Package(self):
- design = Design()
- document = Document(self._filename)
- design.Documents.append(document)
+ def test_Package(self):
+ design = Design()
+ document = Document(self._filename)
+ design.Documents.append(document)
- self.assertEqual(len(design.Documents[0].Packages), 1)
- self.assertTrue(design.Documents[0].Packages[0].Name == "pack_1")
+ self.assertEqual(len(design.Documents[0].Packages), 1)
+ self.assertTrue(design.Documents[0].Packages[0].Name == "pack_1")
- def test_PackageBody(self):
- design = Design()
- document = Document(self._filename)
- design.Documents.append(document)
+ def test_PackageBody(self):
+ design = Design()
+ document = Document(self._filename)
+ design.Documents.append(document)
- self.assertEqual(len(design.Documents[0].PackageBodies), 1)
- self.assertTrue(design.Documents[0].PackageBodies[0].Name == "pack_1")
+ self.assertEqual(len(design.Documents[0].PackageBodies), 1)
+ self.assertTrue(design.Documents[0].PackageBodies[0].Name == "pack_1")
diff --git a/testsuite/pyunit/dom/__init__.py b/testsuite/pyunit/dom/__init__.py
index e69de29bb..4991df255 100644
--- a/testsuite/pyunit/dom/__init__.py
+++ b/testsuite/pyunit/dom/__init__.py
@@ -0,0 +1,32 @@
+# =============================================================================
+# ____ _ _ ____ _ _
+# _ __ _ _ / ___| | | | _ \| | __| | ___ _ __ ___
+# | '_ \| | | | | _| |_| | | | | | / _` |/ _ \| '_ ` _ \
+# | |_) | |_| | |_| | _ | |_| | |___ | (_| | (_) | | | | | |
+# | .__/ \__, |\____|_| |_|____/|_____(_)__,_|\___/|_| |_| |_|
+# |_| |___/
+# =============================================================================
+# Authors:
+# Patrick Lehmann
+#
+# Testsuite: Check libghdl IIR translation to DOM.
+#
+# License:
+# ============================================================================
+# Copyright (C) 2019-2021 Tristan Gingold
+#
+# 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, see <gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ============================================================================
diff --git a/testsuite/pyunit/libghdl/Initialize.py b/testsuite/pyunit/libghdl/Initialize.py
index 369faee07..2fd09965b 100644
--- a/testsuite/pyunit/libghdl/Initialize.py
+++ b/testsuite/pyunit/libghdl/Initialize.py
@@ -1,63 +1,73 @@
-from pathlib import Path
-from unittest import TestCase
+from pathlib import Path
+from unittest import TestCase
-import pyGHDL.libghdl as libghdl
-from pyGHDL.libghdl import name_table, files_map, errorout_console
-from pyGHDL.libghdl.vhdl import nodes, sem_lib
+import pyGHDL.libghdl as libghdl
+from pyGHDL.libghdl import name_table, files_map, errorout_console
+from pyGHDL.libghdl.vhdl import nodes, sem_lib
if __name__ == "__main__":
- print("ERROR: you called a testcase declaration file as an executable module.")
- print("Use: 'python -m unitest <testcase module>'")
- exit(1)
+ print("ERROR: you called a testcase declaration file as an executable module.")
+ print("Use: 'python -m unitest <testcase module>'")
+ exit(1)
class Instantiate(TestCase):
- _root = Path(__file__).resolve().parent.parent
- _filename : Path = _root / "SimpleEntity.vhdl"
-
- @staticmethod
- def getIdentifier(node):
- """Return the Python string from node :obj:`node` identifier."""
- return name_table.Get_Name_Ptr(nodes.Get_Identifier(node))
-
- def test_InitializeGHDL(self) -> None:
- """Initialization: set options and then load libaries."""
- libghdl.initialize()
-
- # Print error messages on the console.
- errorout_console.Install_Handler()
-
- # Set options. This must be done before analyze_init()
- libghdl.set_option("--std=08")
-
- # Finish initialization. This will load the standard package.
- if libghdl.analyze_init_status() != 0:
- self.fail("libghdl initialization error")
-
- # Load the file
- file_id = name_table.Get_Identifier(str(self._filename))
- sfe = files_map.Read_Source_File(name_table.Null_Identifier, file_id)
- if sfe == files_map.No_Source_File_Entry:
- self.fail("Cannot read file '{!s}'".format(self._filename))
-
- # Parse
- file = sem_lib.Load_File(sfe)
-
- # Display all design units
- designUnit = nodes.Get_First_Design_Unit(file)
- while designUnit != nodes.Null_Iir:
- libraryUnit = nodes.Get_Library_Unit(designUnit)
-
- if nodes.Get_Kind(libraryUnit) == nodes.Iir_Kind.Entity_Declaration:
- entityName = self.getIdentifier(libraryUnit)
- self.assertEqual(entityName, "entity_1", "expected entity name 'e1', got '{}'".format(entityName))
-
- elif nodes.Get_Kind(libraryUnit) == nodes.Iir_Kind.Architecture_Body:
- architectureName = self.getIdentifier(libraryUnit)
- self.assertEqual(architectureName, "behav", "expected architecture name 'behav', got '{}'".format(architectureName))
-
- else:
- self.fail("Unknown unit.")
-
- designUnit = nodes.Get_Chain(designUnit)
+ _root = Path(__file__).resolve().parent.parent
+ _filename: Path = _root / "SimpleEntity.vhdl"
+
+ @staticmethod
+ def getIdentifier(node):
+ """Return the Python string from node :obj:`node` identifier."""
+ return name_table.Get_Name_Ptr(nodes.Get_Identifier(node))
+
+ def test_InitializeGHDL(self) -> None:
+ """Initialization: set options and then load libaries."""
+ libghdl.initialize()
+
+ # Print error messages on the console.
+ errorout_console.Install_Handler()
+
+ # Set options. This must be done before analyze_init()
+ libghdl.set_option("--std=08")
+
+ # Finish initialization. This will load the standard package.
+ if libghdl.analyze_init_status() != 0:
+ self.fail("libghdl initialization error")
+
+ # Load the file
+ file_id = name_table.Get_Identifier(str(self._filename))
+ sfe = files_map.Read_Source_File(name_table.Null_Identifier, file_id)
+ if sfe == files_map.No_Source_File_Entry:
+ self.fail("Cannot read file '{!s}'".format(self._filename))
+
+ # Parse
+ file = sem_lib.Load_File(sfe)
+
+ # Display all design units
+ designUnit = nodes.Get_First_Design_Unit(file)
+ while designUnit != nodes.Null_Iir:
+ libraryUnit = nodes.Get_Library_Unit(designUnit)
+
+ if nodes.Get_Kind(libraryUnit) == nodes.Iir_Kind.Entity_Declaration:
+ entityName = self.getIdentifier(libraryUnit)
+ self.assertEqual(
+ entityName,
+ "entity_1",
+ "expected entity name 'e1', got '{}'".format(entityName),
+ )
+
+ elif nodes.Get_Kind(libraryUnit) == nodes.Iir_Kind.Architecture_Body:
+ architectureName = self.getIdentifier(libraryUnit)
+ self.assertEqual(
+ architectureName,
+ "behav",
+ "expected architecture name 'behav', got '{}'".format(
+ architectureName
+ ),
+ )
+
+ else:
+ self.fail("Unknown unit.")
+
+ designUnit = nodes.Get_Chain(designUnit)
diff --git a/testsuite/pyunit/lsp/LanguageServer.py b/testsuite/pyunit/lsp/LanguageServer.py
index c1bcf1898..a406dce91 100644
--- a/testsuite/pyunit/lsp/LanguageServer.py
+++ b/testsuite/pyunit/lsp/LanguageServer.py
@@ -14,207 +14,216 @@ is_windows = os.name == "nt"
class StrConn:
- __res: str
+ __res: str
- def __init__(self):
- self.__res = ''
+ def __init__(self):
+ self.__res = ""
- def write(self, s):
- self.__res += s
+ def write(self, s):
+ self.__res += s
- @property
- def res(self):
- return self.__res
+ @property
+ def res(self):
+ return self.__res
def show_diffs(name, ref, res):
- if isinstance(ref, dict) and isinstance(res, dict):
- for k in ref:
- if k not in res:
- print('{}.{} not in the result'.format(name, k))
- else:
- show_diffs('{}.{}'.format(name, k), ref[k], res[k])
- for k in res:
- if k not in ref:
- print('{}.{} unexpected in the result'.format(name, k))
- elif isinstance(ref, str) and isinstance(res, str):
- if res != ref:
- print('{}: mismatch (ref: {}, result: {})'.format(name, ref, res))
- elif isinstance(ref, int) and isinstance(res, int):
- if res != ref:
- print('{}: mismatch (ref: {}, result: {})'.format(name, ref, res))
- elif isinstance(ref, list) and isinstance(res, list):
- for i in range(max(len(ref), len(res))):
- if i >= len(ref):
- print('{}[{}]: missing element:'.format(name, i))
- print(' {}'.format(res[i]))
- elif i >= len(res):
- print('{}[{}]: extra elements'.format(name, i))
- else:
- show_diffs('{}[{}]'.format(name, i), ref[i], res[i])
- else:
- print('unhandle type {} in {}'.format(type(ref), name))
+ if isinstance(ref, dict) and isinstance(res, dict):
+ for k in ref:
+ if k not in res:
+ print("{}.{} not in the result".format(name, k))
+ else:
+ show_diffs("{}.{}".format(name, k), ref[k], res[k])
+ for k in res:
+ if k not in ref:
+ print("{}.{} unexpected in the result".format(name, k))
+ elif isinstance(ref, str) and isinstance(res, str):
+ if res != ref:
+ print("{}: mismatch (ref: {}, result: {})".format(name, ref, res))
+ elif isinstance(ref, int) and isinstance(res, int):
+ if res != ref:
+ print("{}: mismatch (ref: {}, result: {})".format(name, ref, res))
+ elif isinstance(ref, list) and isinstance(res, list):
+ for i in range(max(len(ref), len(res))):
+ if i >= len(ref):
+ print("{}[{}]: missing element:".format(name, i))
+ print(" {}".format(res[i]))
+ elif i >= len(res):
+ print("{}[{}]: extra elements".format(name, i))
+ else:
+ show_diffs("{}[{}]".format(name, i), ref[i], res[i])
+ else:
+ print("unhandle type {} in {}".format(type(ref), name))
def root_subst(obj, path, uri):
- """Substitute in all strings of :param obj: @ROOT@ with :param root:
+ """Substitute in all strings of :param obj: @ROOT@ with :param root:
URI in LSP are supposed to contain an absolute path. But putting an
hard absolute path would make the test suite not portable. So we use
the metaname @ROOT@ which should be replaced by the root path of the
test suite. Also we need to deal with the windows particularity
about URI."""
- if isinstance(obj, dict):
- for k, v in obj.items():
- if isinstance(v, str):
- if k in ('rootUri', 'uri'):
- assert v.startswith("file://@ROOT@/")
- obj[k] = "file://" + quote(uri + v[13:])
- elif k in ('rootPath', 'message'):
- obj[k] = v.replace('@ROOT@', path)
- else:
- obj[k] = root_subst(v, path, uri)
- return obj
- elif obj is None or isinstance(obj, (str, int)):
- return obj
- elif isinstance(obj, list):
- res = []
- for v in obj:
- res.append(root_subst(v, path, uri))
- return res
- else:
- raise AssertionError("root_subst: unhandled type {}".format(type(obj)))
+ if isinstance(obj, dict):
+ for k, v in obj.items():
+ if isinstance(v, str):
+ if k in ("rootUri", "uri"):
+ assert v.startswith("file://@ROOT@/")
+ obj[k] = "file://" + quote(uri + v[13:])
+ elif k in ("rootPath", "message"):
+ obj[k] = v.replace("@ROOT@", path)
+ else:
+ obj[k] = root_subst(v, path, uri)
+ return obj
+ elif obj is None or isinstance(obj, (str, int)):
+ return obj
+ elif isinstance(obj, list):
+ res = []
+ for v in obj:
+ res.append(root_subst(v, path, uri))
+ return res
+ else:
+ raise AssertionError("root_subst: unhandled type {}".format(type(obj)))
class JSONTest(TestCase):
- _LSPTestDirectory = Path(__file__).parent.resolve()
-
- subdir = None
-
- def _RequestResponse(self, requestName: str, responseName: Optional[str] = None):
- root = str(self._LSPTestDirectory)
- root_uri = self._LSPTestDirectory.as_uri()
- assert(root_uri.startswith("file://"))
- root_uri = root_uri[7:]
- requestFile = self._LSPTestDirectory / self.subdir / requestName
- # Convert the JSON input file to an LSP string.
- with requestFile.open('r') as file:
- res = json_load(file)
- res = root_subst(res, root, root_uri)
-
- conn = StrConn()
- ls = LanguageProtocolServer(None, conn)
- for req in res:
- ls.write_output(req)
-
- # Run
- p = subprocess_run(
- [executable, '-m', 'pyGHDL.cli.lsp'],
- input=conn.res.encode('utf-8'),
- stdout=PIPE)
- self.assertEqual(p.returncode, 0, "Language server executable exit with a non-zero return code.")
-
- if responseName is None:
- return
- responseFile = self._LSPTestDirectory / self.subdir / responseName
-
- # Check output
- in_io = BytesIO(p.stdout)
- conn = LSPConn(in_io, None)
- ls = LanguageProtocolServer(None, conn)
- with responseFile.open('r') as file:
- ref = json_load(file)
- ref = root_subst(ref, root, root_uri)
-
- errs = 0
- json_res = []
- for i, r in enumerate(ref):
- rep = ls.read_request()
- if rep is None:
- print('FAIL: number of reply does not match')
- errs += 1
- break
-
- rep = json_loads(rep)
- json_res.append(rep)
-# self.assertEqual(rep, r, "reply does not match for {!s}".format(requestFile))
- if rep != r:
- print(self.__class__.__name__)
- show_diffs("[{}]".format(i), r, rep)
- errs += 1
-
- rep = ls.read_request()
- self.assertIsNone(rep, "Too many replies.")
-
- if errs != 0:
- print('FAILURE between output and {!s} (for {!s})'.format(responseFile, requestFile))
- print('Writing result output to result.json')
- with open('result.json', 'w') as f:
- f.write(json_dumps(json_res, indent=2))
- f.write('\n')
- with open('request.json', 'w') as f:
- f.write(json_dumps(res, indent=2))
- f.write('\n')
-
- self.fail()
+ _LSPTestDirectory = Path(__file__).parent.resolve()
+
+ subdir = None
+
+ def _RequestResponse(self, requestName: str, responseName: Optional[str] = None):
+ root = str(self._LSPTestDirectory)
+ root_uri = self._LSPTestDirectory.as_uri()
+ assert root_uri.startswith("file://")
+ root_uri = root_uri[7:]
+ requestFile = self._LSPTestDirectory / self.subdir / requestName
+ # Convert the JSON input file to an LSP string.
+ with requestFile.open("r") as file:
+ res = json_load(file)
+ res = root_subst(res, root, root_uri)
+
+ conn = StrConn()
+ ls = LanguageProtocolServer(None, conn)
+ for req in res:
+ ls.write_output(req)
+
+ # Run
+ p = subprocess_run(
+ [executable, "-m", "pyGHDL.cli.lsp"],
+ input=conn.res.encode("utf-8"),
+ stdout=PIPE,
+ )
+ self.assertEqual(
+ p.returncode,
+ 0,
+ "Language server executable exit with a non-zero return code.",
+ )
+
+ if responseName is None:
+ return
+ responseFile = self._LSPTestDirectory / self.subdir / responseName
+
+ # Check output
+ in_io = BytesIO(p.stdout)
+ conn = LSPConn(in_io, None)
+ ls = LanguageProtocolServer(None, conn)
+ with responseFile.open("r") as file:
+ ref = json_load(file)
+ ref = root_subst(ref, root, root_uri)
+
+ errs = 0
+ json_res = []
+ for i, r in enumerate(ref):
+ rep = ls.read_request()
+ if rep is None:
+ print("FAIL: number of reply does not match")
+ errs += 1
+ break
+
+ rep = json_loads(rep)
+ json_res.append(rep)
+ # self.assertEqual(rep, r, "reply does not match for {!s}".format(requestFile))
+ if rep != r:
+ print(self.__class__.__name__)
+ show_diffs("[{}]".format(i), r, rep)
+ errs += 1
+
+ rep = ls.read_request()
+ self.assertIsNone(rep, "Too many replies.")
+
+ if errs != 0:
+ print(
+ "FAILURE between output and {!s} (for {!s})".format(
+ responseFile, requestFile
+ )
+ )
+ print("Writing result output to result.json")
+ with open("result.json", "w") as f:
+ f.write(json_dumps(json_res, indent=2))
+ f.write("\n")
+ with open("request.json", "w") as f:
+ f.write(json_dumps(res, indent=2))
+ f.write("\n")
+
+ self.fail()
class Test001_Simple(JSONTest):
- subdir = Path("001simple")
+ subdir = Path("001simple")
- def test_Request_Response(self):
- self._RequestResponse("cmds.json", "replies.json")
+ def test_Request_Response(self):
+ self._RequestResponse("cmds.json", "replies.json")
class Test002_Coverage(JSONTest):
- subdir = Path("002coverage")
+ subdir = Path("002coverage")
- def test_Request_Response(self):
- self._RequestResponse("cmds.json", "replies.json")
+ def test_Request_Response(self):
+ self._RequestResponse("cmds.json", "replies.json")
class Test003_Errors(JSONTest):
- subdir = Path("003errors")
+ subdir = Path("003errors")
- def test_Crash1(self):
- self._RequestResponse("crash1.json")
+ def test_Crash1(self):
+ self._RequestResponse("crash1.json")
- def test_Crash2(self):
- self._RequestResponse("crash2.json")
+ def test_Crash2(self):
+ self._RequestResponse("crash2.json")
- def test_Request_Response(self):
- self._RequestResponse("cmds.json", "replies.json")
+ def test_Request_Response(self):
+ self._RequestResponse("cmds.json", "replies.json")
class Test004_Error_Project(JSONTest):
- subdir = Path("004errprj")
+ subdir = Path("004errprj")
- def test_Request_Response(self):
- self._RequestResponse("cmds.json", "replies.json")
+ def test_Request_Response(self):
+ self._RequestResponse("cmds.json", "replies.json")
class Test005_Create(JSONTest):
- subdir = Path("005create")
+ subdir = Path("005create")
- def test_Request_Response(self):
- self._RequestResponse("cmds.json", "replies.json")
+ def test_Request_Response(self):
+ self._RequestResponse("cmds.json", "replies.json")
class Test006_Option_Error(JSONTest):
- subdir = Path("006opterr")
+ subdir = Path("006opterr")
- def test_Request_Response(self):
- self._RequestResponse("cmds.json", "replies.json")
+ def test_Request_Response(self):
+ self._RequestResponse("cmds.json", "replies.json")
class Test007_Error_Project(JSONTest):
- subdir = Path("007errprj")
+ subdir = Path("007errprj")
- def test_Request_Response(self):
- self._RequestResponse("cmds.json", "replies.json")
+ def test_Request_Response(self):
+ self._RequestResponse("cmds.json", "replies.json")
class Test008_Error_NoFile(JSONTest):
- subdir = Path("008errnofile")
+ subdir = Path("008errnofile")
- def test_Request_Response(self):
- self._RequestResponse("cmds.json", "replies.json")
+ def test_Request_Response(self):
+ self._RequestResponse("cmds.json", "replies.json")