diff --git a/.btd.yml b/.btd.yml
deleted file mode 100644
index e3509f78..00000000
--- a/.btd.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-input: doc
-output: _build
-requirements: requirements.txt
-target: gh-pages
-formats: [ html ]
-images:
- base: btdi/sphinx:pytooling
-theme: https://codeload.GitHub.com/buildthedocs/sphinx.theme/tar.gz/v1
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000..6d63ee37
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,3 @@
+* @Paebbels
+
+/.github/ @Paebbels
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 0e75a2d3..d982b019 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -8,9 +8,6 @@ updates:
prefix: "[Dependabot]"
labels:
- Dependencies
- reviewers:
- - Paebbels
- - Umarcor
schedule:
interval: "daily" # Checks on Monday trough Friday.
@@ -22,8 +19,5 @@ updates:
prefix: "[Dependabot]"
labels:
- Dependencies
- reviewers:
- - Paebbels
- - Umarcor
schedule:
interval: "weekly"
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index ac698f89..4ed2d900 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,16 +1,30 @@
# New Features
-
+
+* tbd
* tbd
# Changes
+* tbd
* tbd
# Bug Fixes
+* tbd
+* tbd
+
+# Documentation
+
+* tbd
+* tbd
+
+# Unit Tests
+
+* tbd
* tbd
----------
-# Related PRs:
+# Related Issues and Pull-Requests
* tbd
+* tbd
diff --git a/.github/workflows/Pipeline.yml b/.github/workflows/Pipeline.yml
index d7d08455..9f12dfd8 100644
--- a/.github/workflows/Pipeline.yml
+++ b/.github/workflows/Pipeline.yml
@@ -4,136 +4,28 @@ on:
push:
workflow_dispatch:
schedule:
- - cron: '0 0 * * 5'
+# Every Friday at 22:00 - rerun pipeline to check for dependency-based issues
+ - cron: '0 22 * * 5'
-jobs:
-
- Params:
- uses: pyTooling/Actions/.github/workflows/Parameters.yml@r0
- with:
- name: pyEDAA.UCIS
-
- UnitTesting:
- uses: pyTooling/Actions/.github/workflows/UnitTesting.yml@r0
- needs:
- - Params
- with:
- jobs: ${{ needs.Params.outputs.python_jobs }}
- artifact: ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}
-
- Coverage:
- uses: pyTooling/Actions/.github/workflows/CoverageCollection.yml@r0
- needs:
- - Params
- with:
- python_version: ${{ fromJson(needs.Params.outputs.params).python_version }}
- artifact: ${{ fromJson(needs.Params.outputs.params).artifacts.coverage }}
- secrets:
- codacy_token: ${{ secrets.CODACY_PROJECT_TOKEN }}
-
- StaticTypeCheck:
- uses: pyTooling/Actions/.github/workflows/StaticTypeCheck.yml@r0
- needs:
- - Params
- with:
- python_version: ${{ fromJson(needs.Params.outputs.params).python_version }}
- requirements: '-r tests/requirements.txt'
- commands: |
- cd pyEDAA
- mypy --html-report ../htmlmypy -p UCIS
- report: 'htmlmypy'
- artifact: ${{ fromJson(needs.Params.outputs.params).artifacts.typing }}
-
- PublishTestResults:
- uses: pyTooling/Actions/.github/workflows/PublishTestResults.yml@r0
- needs:
- - UnitTesting
+permissions:
+ actions: write
+ contents: write
+ pages: write
+ id-token: write
- Package:
- uses: pyTooling/Actions/.github/workflows/Package.yml@r0
- needs:
- - Params
- - Coverage
- with:
- python_version: ${{ fromJson(needs.Params.outputs.params).python_version }}
- artifact: ${{ fromJson(needs.Params.outputs.params).artifacts.package }}
-
- Release:
- uses: pyTooling/Actions/.github/workflows/Release.yml@r0
- if: startsWith(github.ref, 'refs/tags')
- needs:
- - UnitTesting
- - Coverage
- - StaticTypeCheck
- - Package
-
- PublishOnPyPI:
- uses: pyTooling/Actions/.github/workflows/PublishOnPyPI.yml@r0
- if: startsWith(github.ref, 'refs/tags')
- needs:
- - Params
- - Release
- - Package
- with:
- python_version: ${{ fromJson(needs.Params.outputs.params).python_version }}
- requirements: -r dist/requirements.txt
- artifact: ${{ fromJson(needs.Params.outputs.params).artifacts.package }}
+jobs:
+ Pipeline:
+ uses: pyTooling/Actions/.github/workflows/CompletePipeline.yml@r7
+ with:
+ package_namespace: 'pyEDAA'
+ package_name: 'UCIS'
+ unittest_python_version_list: '3.11 3.12 3.13 3.14 pypy-3.11'
+ bandit: 'true'
+ pylint: 'true'
+ codecov: 'true'
+ codacy: 'true'
+ dorny: 'true'
secrets:
- PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
-
-# VerifyDocs:
-# uses: pyTooling/Actions/.github/workflows/VerifyDocs.yml@r0
-# needs:
-# - Params
-# with:
-# python_version: ${{ fromJson(needs.Params.outputs.params).python_version }}
-
- BuildTheDocs:
- uses: pyTooling/Actions/.github/workflows/BuildTheDocs.yml@r0
- needs:
- - Params
-# - VerifyDocs
- with:
- artifact: ${{ fromJson(needs.Params.outputs.params).artifacts.doc }}
-
- PublishToGitHubPages:
- uses: pyTooling/Actions/.github/workflows/PublishToGitHubPages.yml@r0
- needs:
- - Params
- - BuildTheDocs
- - Coverage
- - StaticTypeCheck
- with:
- doc: ${{ fromJson(needs.Params.outputs.params).artifacts.doc }}
- coverage: ${{ fromJson(needs.Params.outputs.params).artifacts.coverage }}
- typing: ${{ fromJson(needs.Params.outputs.params).artifacts.typing }}
-
- ArtifactCleanUp:
- uses: pyTooling/Actions/.github/workflows/ArtifactCleanUp.yml@r0
- needs:
- - Params
- - UnitTesting
- - Coverage
- - StaticTypeCheck
- - BuildTheDocs
- - PublishToGitHubPages
- - PublishTestResults
- with:
- package: ${{ fromJson(needs.Params.outputs.params).artifacts.package }}
- remaining: |
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-ubuntu-3.7
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-ubuntu-3.8
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-ubuntu-3.9
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-ubuntu-3.10
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-windows-3.7
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-windows-3.8
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-windows-3.9
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-windows-3.10
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-msys2-3.9
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-macos-3.7
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-macos-3.8
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-macos-3.9
- ${{ fromJson(needs.Params.outputs.params).artifacts.unittesting }}-macos-3.10
- ${{ fromJson(needs.Params.outputs.params).artifacts.coverage }}
- ${{ fromJson(needs.Params.outputs.params).artifacts.typing }}
- ${{ fromJson(needs.Params.outputs.params).artifacts.doc }}
+ PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ CODACY_TOKEN: ${{ secrets.CODACY_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 0e00965a..e0f9e7c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,13 @@ __pycache__/
.coverage
.cov
coverage.xml
+/report/coverage
+
+# mypy
+/report/typing
+
+# pytest
+/report/unit
# setuptools
/build/**/*.*
@@ -21,5 +28,8 @@ coverage.xml
/doc/pyEDAA.UCIS/**/*.*
!/doc/pyEDAA.UCIS/index.rst
-# PyCharm project
+# PyCharm project files
/.idea/workspace.xml
+
+# Git files
+!.git*
diff --git a/.idea/pyEDAA.UCIS.iml b/.idea/pyEDAA.UCIS.iml
index aad2a96d..398dee45 100644
--- a/.idea/pyEDAA.UCIS.iml
+++ b/.idea/pyEDAA.UCIS.iml
@@ -2,13 +2,16 @@
+
-
+
+
+
-
+
\ No newline at end of file
diff --git a/README.md b/README.md
index d32b1048..b6752104 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
[](https://pypi.org/project/pyEDAA.UCIS/)


-[](https://GitHub.com/edaa-org/pyEDAA.UCIS/actions/workflows/Pipeline.yml)
+[](https://GitHub.com/edaa-org/pyEDAA.UCIS/actions/workflows/Pipeline.yml)
[](https://libraries.io/github/edaa-org/pyEDAA.UCIS)
[](https://app.codacy.com/gh/edaa-org/pyEDAA.UCIS)
[](https://app.codacy.com/gh/edaa-org/pyEDAA.UCIS)
@@ -27,7 +27,7 @@ Unified Coverage Interoperability Standard (UCIS)
## Main Goals
-* Parse UCDB files and provide a UCDB data model.
+* Convert UCDB files and provide a UCDB data model.
* Export and convert data from UCDB to Cobertura format.
* Also support flavors not following the Unified Coverage Interoperability Standard (UCIS).
diff --git a/dist/requirements.txt b/dist/requirements.txt
index 6c4932c1..e87980bd 100644
--- a/dist/requirements.txt
+++ b/dist/requirements.txt
@@ -1,2 +1,2 @@
-wheel
-twine
+wheel ~= 0.45.0
+twine ~= 6.2
diff --git a/doc/CodeCoverage.rst b/doc/CodeCoverage.rst
index afceecca..217fd1e4 100644
--- a/doc/CodeCoverage.rst
+++ b/doc/CodeCoverage.rst
@@ -1,18 +1,25 @@
-Code Coverage
-#############
+.. _CODECOV:
-Statement Coverage
-******************
+Code Coverage Report
+####################
-.. code-block:: Bash
+.. grid:: 2
- # Convert ACDB file into UCDB file (XML format)
- acdb2xml -i aggregate.acdb -o ucdb.xml
+ .. grid-item::
+ :columns: 8
- # Convert UCDB file into Cobertura format
- pyedaa-ucis export --ucdb ucdb.xml --cobertura cobertura.xml
+ .. report:code-coverage::
+ :reportid: src
-Branch Coverage
-***************
+ .. grid-item::
+ :columns: 4
-.. note:: Branch coverage isn't supported yet.
+ .. report:code-coverage-legend::
+ :reportid: src
+ :style: vertical-table
+
+----------
+
+Code coverage report generated with `pytest `__,
+`Coverage.py `__ and visualized by
+`sphinx-reports `__.
diff --git a/doc/CommandLineInterface.rst b/doc/CommandLineInterface.rst
index e60a0532..41f416dd 100644
--- a/doc/CommandLineInterface.rst
+++ b/doc/CommandLineInterface.rst
@@ -1,7 +1,7 @@
Command Line Interfaces
#######################
-.. _References:cli:
+.. _References/cli:
.. autoprogram:: pyEDAA.UCIS.CLI:Program().MainParser
:prog: pyedaa-ucis
diff --git a/doc/Dependency.rst b/doc/Dependency.rst
index d758c4e8..6a2930f6 100644
--- a/doc/Dependency.rst
+++ b/doc/Dependency.rst
@@ -27,12 +27,15 @@ pyEDAA.UCIS Package
+---------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
| **Package** | **Version** | **License** | **Dependencies** |
+===============================================================+=============+===========================================================================================+========================================================================================================================================================+
-| `pyTooling `__ | ≥1.9.5 | `Apache License, 2.0 `__ | *None* |
-+---------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
-| `pyAttributes `__ | ≥2.5.1 | `Apache License, 2.0 `__ | * `pyTooling `__ - `Apache License, 2.0 `__ |
-| | | | * `argcomplete `__ - `Apache License, 2.0 `__ |
+| `pyTooling `__ | ≥8.0 | `Apache License, 2.0 `__ | *None* |
+---------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
+.. todo:: investigate dependencies and licenses of pyTooling with pyAttributes/argcomplete.
+
+.. | `pyAttributes `__ | ≥2.5.1 | `Apache License, 2.0 `__ | * `pyTooling `__ - `Apache License, 2.0 `__ |
+ | | | | * `argcomplete `__ - `Apache License, 2.0 `__ |
+ +---------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
+
.. _dependency-testing:
@@ -55,19 +58,21 @@ the mandatory dependencies too.
.. rubric:: Dependency List
-+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
-| **Package** | **Version** | **License** | **Dependencies** |
-+===========================================================+=============+========================================================================================+======================+
-| `pytest `__ | ≥7.0.1 | `MIT `__ | *Not yet evaluated.* |
-+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
-| `pytest-cov `__ | ≥3.0.0 | `MIT `__ | *Not yet evaluated.* |
-+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
-| `Coverage `__ | ≥6.3 | `Apache License, 2.0 `__ | *Not yet evaluated.* |
-+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
-| `mypy `__ | ≥0.931 | `MIT `__ | *Not yet evaluated.* |
-+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
-| `lxml `__ | ≥4.8 | `BSD 3-Clause `__ | *Not yet evaluated.* |
-+-----------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
+| **Package** | **Version** | **License** | **Dependencies** |
++=====================================================================+=============+========================================================================================+======================+
+| `pytest `__ | ≥8.3 | `MIT `__ | *Not yet evaluated.* |
++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
+| `pytest-cov `__ | ≥6.1 | `MIT `__ | *Not yet evaluated.* |
++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
+| `Coverage `__ | ≥7.8 | `Apache License, 2.0 `__ | *Not yet evaluated.* |
++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
+| `mypy `__ | ≥1.15 | `MIT `__ | *Not yet evaluated.* |
++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
+| `typing-extensions `__ | ≥4.13 | `PSF-2.0 `__ | *Not yet evaluated.* |
++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
+| `lxml `__ | ≥5.4 | `BSD 3-Clause `__ | *Not yet evaluated.* |
++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+
.. _dependency-documentation:
@@ -94,15 +99,21 @@ the mandatory dependencies too.
+-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
| **Package** | **Version** | **License** | **Dependencies** |
+=================================================================================================+==============+==========================================================================================================+======================================================================================================================================================+
-| `pyTooling `__ | ≥1.9.5 | `Apache License, 2.0 `__ | *None* |
+| `pyTooling `__ | ≥8.4 | `Apache License, 2.0 `__ | *None* |
+-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
-| `Sphinx `__ | ≥4.4.0 | `BSD 3-Clause `__ | *Not yet evaluated.* |
+| `Sphinx `__ | ≥8.2 | `BSD 3-Clause `__ | *Not yet evaluated.* |
++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
+| `sphinxcontrib-mermaid `__ | ≥1.0 | `BSD `__ | *Not yet evaluated.* |
++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
+| `autoapi `__ | ≥2.0.1 | `Apache License, 2.0 `__ | *Not yet evaluated.* |
+-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
| `sphinx_btd_theme `__ | ≥0.5.2 | `MIT `__ | *Not yet evaluated.* |
+-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
-| !! `sphinx_fontawesome `__ | ≥0.0.6 | `GPL 2.0 `__ | *Not yet evaluated.* |
+| `sphinx_design `__ | ≥0.6 | `MIT `__ | *Not yet evaluated.* |
++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
+| `sphinx-copybutton `__ | ≥0.5.2 | `MIT `__ | *Not yet evaluated.* |
+-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
-| `sphinx_autodoc_typehints `__ | ≥1.17.0 | `MIT `__ | *Not yet evaluated.* |
+| `sphinx_autodoc_typehints `__ | ≥3.2 | `MIT `__ | *Not yet evaluated.* |
+-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -130,9 +141,9 @@ install the mandatory dependencies too.
+----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
| **Package** | **Version** | **License** | **Dependencies** |
+============================================================================+==============+==========================================================================================================+======================================================================================================================================================+
-| `pyTooling `__ | ≥1.9.5 | `Apache License, 2.0 `__ | *None* |
+| `pyTooling `__ | ≥8.4 | `Apache License, 2.0 `__ | *None* |
+----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
-| `wheel `__ | any | `MIT `__ | *Not yet evaluated.* |
+| `wheel `__ | ≥0.45 | `MIT `__ | *Not yet evaluated.* |
+----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -161,7 +172,7 @@ install the mandatory dependencies too.
+----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+
| **Package** | **Version** | **License** | **Dependencies** |
+==========================================================+==============+===========================================================================================+======================+
-| `wheel `__ | any | `MIT `__ | *Not yet evaluated.* |
+| `wheel `__ | ≥0.45 | `MIT `__ | *Not yet evaluated.* |
+----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+
-| `Twine `__ | any | `Apache License, 2.0 `__ | *Not yet evaluated.* |
+| `Twine `__ | ≥6.1 | `Apache License, 2.0 `__ | *Not yet evaluated.* |
+----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+
diff --git a/doc/DocCoverage.rst b/doc/DocCoverage.rst
new file mode 100644
index 00000000..d2ee3882
--- /dev/null
+++ b/doc/DocCoverage.rst
@@ -0,0 +1,24 @@
+.. _DOCCOV:
+
+Documentation Coverage Report
+#############################
+
+.. grid:: 2
+
+ .. grid-item::
+ :columns: 5
+
+ .. report:doc-coverage::
+ :reportid: src
+
+ .. grid-item::
+ :columns: 7
+
+ .. report:doc-coverage-legend::
+ :reportid: src
+ :style: vertical-table
+
+----------
+
+Documentation coverage generated with `"""docstr-coverage""" `__ and
+visualized by `sphinx-reports `__.
diff --git a/doc/TODO.rst b/doc/TODO.rst
new file mode 100644
index 00000000..3144da04
--- /dev/null
+++ b/doc/TODO.rst
@@ -0,0 +1,4 @@
+TODOs
+#####
+
+.. todolist::
diff --git a/doc/_static/css/override.css b/doc/_static/css/override.css
new file mode 100644
index 00000000..4dd6beb5
--- /dev/null
+++ b/doc/_static/css/override.css
@@ -0,0 +1,115 @@
+/* theme overrides */
+.rst-content h1,
+.rst-content h2 {
+ margin-top: 24px;
+ margin-bottom: 6px;
+ text-decoration: underline;
+}
+
+.rst-content h3,
+.rst-content h4,
+.rst-content h5,
+.rst-content h6 {
+ margin-top: 12px;
+ margin-bottom: 6px;
+}
+
+.rst-content p {
+ margin-bottom: 6px
+}
+
+.rst-content .topic-title {
+ font-size: larger;
+ font-weight: 700;
+ margin-top: 18px;
+ margin-bottom: 6px;
+}
+
+.rst-content p.rubric {
+ text-decoration: underline;
+ font-weight: 700;
+ margin-top: 18px;
+ margin-bottom: 16px;
+}
+
+/* general overrides */
+html {
+ font-size: 15px;
+}
+
+footer {
+ font-size: 95%;
+ text-align: center
+}
+
+footer p {
+ margin-bottom: 0px /* 12px */;
+ font-size: 95%
+}
+
+section > p,
+.section p,
+.simple li {
+ text-align: justify
+}
+
+/* wyrm overrides */
+.wy-menu-vertical header,
+.wy-menu-vertical p.caption {
+ color: #9b9b9b /* #55a5d9 */;
+ padding: 0 0.809em /* 0 1.618em */;
+ margin: 6px 0 0 0 /* 12px 0 0 */;
+ border-top: 1px solid #9b9b9b;
+}
+
+.wy-side-nav-search {
+ margin-bottom: 0 /* .809em */;
+ background-color: #333333 /* #2980b9 */;
+ /* BTD: */
+ /*color: #fcfcfc*/
+}
+
+.wy-side-nav-search input[type=text] {
+ border-radius: 0px /* 50px */;
+}
+
+.wy-side-nav-search .wy-dropdown > a, .wy-side-nav-search > a {
+ /* BTD: */
+ /*color: #fcfcfc;*/
+ margin-bottom: 0.404em /* .809em */;
+}
+
+.wy-side-nav-search > div.version {
+ margin: 0 0 6px 0;
+ /* BTD: */
+ /*margin-top: -.4045em;*/
+}
+
+.wy-nav .wy-menu-vertical a:hover {
+ background-color: #333333 /* #2980b9 */;
+}
+
+.wy-nav-content {
+ max-width: 1600px /* 800px */ ;
+}
+
+.wy-nav-top {
+ background: #333333 /* #2980b9 */;
+}
+
+/* Sphinx Design */
+.sd-tab-set {
+ margin: 0
+}
+
+.sd-tab-set > label {
+ padding-top: .5em;
+ padding-right: 1em;
+ padding-bottom: .5em;
+ padding-left: 1em
+}
+
+.sd-container-fluid {
+ padding-left: 0;
+ padding-right: 0;
+}
diff --git a/doc/_templates/autoapi/module.rst b/doc/_templates/autoapi/module.rst
index 5f9e361b..4dded81f 100644
--- a/doc/_templates/autoapi/module.rst
+++ b/doc/_templates/autoapi/module.rst
@@ -1,10 +1,12 @@
-.. # Template modified by Patrick Lehmann
+.. # Template modified by Patrick Lehmann
* removed automodule on top, because private members are activated for autodoc (no doubled documentation).
* Made sections like 'submodules' bold text, but no headlines to reduce number of ToC levels.
-=={{ '=' * node.name|length }}==
-``{{ node.name }}``
-=={{ '=' * node.name|length }}==
+{{ '=' * node.name|length }}
+{{ node.name }}
+{{ '=' * node.name|length }}
+
+.. automodule:: {{ node.name }}
{##}
{%- block modules -%}
@@ -12,8 +14,8 @@
**Submodules**
-
.. toctree::
+ :maxdepth: 1
{% for item in subnodes %}
{{ item.name }}
{%- endfor %}
@@ -23,7 +25,17 @@
{##}
.. currentmodule:: {{ node.name }}
{##}
-{%- block functions -%}
+
+{%- if node.variables %}
+
+**Variables**
+
+{% for item, obj in node.variables.items() -%}
+- :py:data:`{{ item }}`
+ {#{ obj|summary }#}
+{% endfor -%}
+{%- endif -%}
+
{%- if node.functions %}
**Functions**
@@ -33,15 +45,19 @@
{{ obj|summary }}
{% endfor -%}
+{%- endif -%}
-{% for item in node.functions %}
-.. autofunction:: {{ item }}
-{##}
-{%- endfor -%}
+{%- if node.exceptions %}
+
+**Exceptions**
+
+{% for item, obj in node.exceptions.items() -%}
+- :py:exc:`{{ item }}`:
+ {{ obj|summary }}
+
+{% endfor -%}
{%- endif -%}
-{%- endblock -%}
-{%- block classes -%}
{%- if node.classes %}
**Classes**
@@ -51,14 +67,40 @@
{{ obj|summary }}
{% endfor -%}
+{%- endif -%}
-{% for item in node.classes %}
-.. autoclass:: {{ item }}
- :members:
+{%- block variables -%}
+{%- if node.variables %}
- .. rubric:: Inheritance
- .. inheritance-diagram:: {{ item }}
- :parts: 1
+---------------------
+
+**Variables**
+
+{#% for item, obj in node.variables.items() -%}
+- :py:data:`{{ item }}`
+{% endfor -%#}
+
+{% for item, obj in node.variables.items() %}
+.. autodata:: {{ item }}
+ :annotation:
+
+ .. code-block:: text
+
+ {{ obj|pprint|indent(6) }}
+{##}
+{%- endfor -%}
+{%- endif -%}
+{%- endblock -%}
+
+{%- block functions -%}
+{%- if node.functions %}
+
+---------------------
+
+**Functions**
+
+{% for item in node.functions %}
+.. autofunction:: {{ item }}
{##}
{%- endfor -%}
{%- endif -%}
@@ -67,13 +109,15 @@
{%- block exceptions -%}
{%- if node.exceptions %}
+---------------------
+
**Exceptions**
-{% for item, obj in node.exceptions.items() -%}
+{#% for item, obj in node.exceptions.items() -%}
- :py:exc:`{{ item }}`:
{{ obj|summary }}
-{% endfor -%}
+{% endfor -%#}
{% for item in node.exceptions %}
.. autoexception:: {{ item }}
@@ -86,22 +130,30 @@
{%- endif -%}
{%- endblock -%}
-{%- block variables -%}
-{%- if node.variables %}
+{%- block classes -%}
+{%- if node.classes %}
-**Variables**
+---------------------
-{% for item, obj in node.variables.items() -%}
-- :py:data:`{{ item }}`
-{% endfor -%}
+**Classes**
-{% for item, obj in node.variables.items() %}
-.. autodata:: {{ item }}
- :annotation:
+{#% for item, obj in node.classes.items() -%}
+- :py:class:`{{ item }}`:
+ {{ obj|summary }}
- .. code-block:: text
+{% endfor -%#}
- {{ obj|pprint|indent(6) }}
+{% for item in node.classes %}
+.. autoclass:: {{ item }}
+ :members:
+ :private-members:
+ :special-members:
+ :inherited-members:
+ :exclude-members: __weakref__
+
+ .. rubric:: Inheritance
+ .. inheritance-diagram:: {{ item }}
+ :parts: 1
{##}
{%- endfor -%}
{%- endif -%}
diff --git a/doc/_templates/autoapi/package.rst b/doc/_templates/autoapi/package.rst
new file mode 100644
index 00000000..9cc9fbdc
--- /dev/null
+++ b/doc/_templates/autoapi/package.rst
@@ -0,0 +1,14 @@
+.. # Template created by Patrick Lehmann
+
+Python Class Reference
+######################
+
+Reference of all packages and modules:
+
+.. automodule:: {{ node.name }}
+
+.. toctree::
+ :maxdepth: 1
+{% for item in subnodes %}
+ {{ item.name }}
+{%- endfor %}
diff --git a/doc/conf.py b/doc/conf.py
index d210b78d..9deee418 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -1,19 +1,27 @@
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
-
from sys import path as sys_path
from os.path import abspath
from pathlib import Path
-from json import loads
from pyTooling.Packaging import extractVersionInformation
+# ==============================================================================
+# Project configuration
+# ==============================================================================
+githubNamespace = "edaa-org"
+project = "pyEDAA.UCIS"
+directoryName = project.replace('.', '/')
+
+# ==============================================================================
+# Project paths
+# ==============================================================================
ROOT = Path(__file__).resolve().parent
-sys_path.insert(0, abspath('.'))
-sys_path.insert(0, abspath('..'))
-sys_path.insert(0, abspath('../pyEDAA/UCIS'))
+sys_path.insert(0, abspath("."))
+sys_path.insert(0, abspath(".."))
+sys_path.insert(0, abspath(f"../{directoryName}"))
# ==============================================================================
@@ -22,9 +30,7 @@
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
-project = "pyEDAA.UCIS"
-
-packageInformationFile = Path(f"../{project.replace('.', '/')}/__init__.py")
+packageInformationFile = Path(f"../{directoryName}/__init__.py")
versionInformation = extractVersionInformation(packageInformationFile)
author = versionInformation.Author
@@ -32,38 +38,39 @@
version = ".".join(versionInformation.Version.split(".")[:2]) # e.g. 2.3 The short X.Y version.
release = versionInformation.Version
+
# ==============================================================================
# Miscellaneous settings
# ==============================================================================
# The master toctree document.
-master_doc = 'index'
+master_doc = "index"
# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [
"_build",
- "_themes",
+ "_theme",
"Thumbs.db",
".DS_Store"
]
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'stata-dark'
+pygments_style = "manni"
# ==============================================================================
# Restructured Text settings
# ==============================================================================
-prologPath = "prolog.inc"
+prologPath = Path("prolog.inc")
try:
- with open(prologPath, "r") as prologFile:
- rst_prolog = prologFile.read()
+ with prologPath.open("r", encoding="utf-8") as fileHandle:
+ rst_prolog = fileHandle.read()
except Exception as ex:
- print("[ERROR:] While reading '{0!s}'.".format(prologPath))
+ print(f"[ERROR:] While reading '{prologPath}'.")
print(ex)
rst_prolog = ""
@@ -71,39 +78,38 @@
# ==============================================================================
# Options for HTML output
# ==============================================================================
-
-html_context = {}
-ctx = ROOT / 'context.json'
-if ctx.is_file():
- html_context.update(loads(ctx.open('r').read()))
-
-if (ROOT / "_theme").is_dir():
- html_theme_path = ["."]
- html_theme = "_theme"
- html_theme_options = {
- 'logo_only': True,
- 'home_breadcrumbs': False,
- 'vcs_pageview_mode': 'blob',
- }
-else:
- html_theme = "alabaster"
+html_theme = "sphinx_rtd_theme"
+html_theme_options = {
+ "logo_only": True,
+ "vcs_pageview_mode": 'blob',
+ "navigation_depth": 5,
+}
+html_css_files = [
+ 'css/override.css',
+]
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = ["_static"]
html_logo = str(Path(html_static_path[0]) / "logo.svg")
html_favicon = str(Path(html_static_path[0]) / "favicon.svg")
# Output file base name for HTML help builder.
-htmlhelp_basename = 'pyEDAAUCISDoc'
+htmlhelp_basename = f"{project}Doc"
# If not None, a 'Last updated on:' timestamp is inserted at every page
# bottom, using the given strftime format.
# The empty string is equivalent to '%b %d, %Y'.
html_last_updated_fmt = "%d.%m.%Y"
+# ==============================================================================
+# Python settings
+# ==============================================================================
+modindex_common_prefix = [
+ f"{project}."
+]
# ==============================================================================
# Options for LaTeX / PDF output
@@ -112,13 +118,13 @@
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
- 'papersize': 'a4paper',
+ "papersize": "a4paper",
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
- 'preamble': dedent(r"""
+ "preamble": dedent(r"""
% ================================================================================
% User defined additional preamble code
% ================================================================================
@@ -144,10 +150,10 @@
# author, documentclass [howto, manual, or own class]).
latex_documents = [
( master_doc,
- 'pyEDAA.UCIS.tex',
- 'The pyEDAA.UCIS Documentation',
- 'Patrick Lehmann',
- 'manual'
+ f"{project}.tex",
+ f"The {project} Documentation",
+ f"Patrick Lehmann",
+ f"manual"
),
]
@@ -158,21 +164,24 @@
extensions = [
# Standard Sphinx extensions
"sphinx.ext.autodoc",
- 'sphinx.ext.extlinks',
- 'sphinx.ext.intersphinx',
- 'sphinx.ext.inheritance_diagram',
- 'sphinx.ext.todo',
- 'sphinx.ext.graphviz',
- 'sphinx.ext.mathjax',
- 'sphinx.ext.ifconfig',
- 'sphinx.ext.viewcode',
+ "sphinx.ext.extlinks",
+ "sphinx.ext.intersphinx",
+ "sphinx.ext.inheritance_diagram",
+ "sphinx.ext.todo",
+ "sphinx.ext.graphviz",
+ "sphinx.ext.mathjax",
+ "sphinx.ext.ifconfig",
+ "sphinx.ext.viewcode",
# SphinxContrib extensions
- 'sphinxcontrib.autoprogram',
- 'sphinxcontrib.mermaid',
+ "sphinxcontrib.mermaid",
+ "sphinxcontrib.autoprogram",
# Other extensions
- 'autoapi.sphinx',
- 'sphinx_fontawesome',
- 'sphinx_autodoc_typehints',
+ "sphinx_design",
+ "sphinx_copybutton",
+ "sphinx_autodoc_typehints",
+ "autoapi.sphinx",
+ "sphinx_reports",
+# User defined extensions
]
@@ -180,7 +189,8 @@
# Sphinx.Ext.InterSphinx
# ==============================================================================
intersphinx_mapping = {
- 'python': ('https://docs.python.org/3', None),
+ "python": ("https://docs.python.org/3", None),
+ "pyTool": ("https://pyTooling.github.io/pyTooling/", None),
}
@@ -188,16 +198,28 @@
# Sphinx.Ext.AutoDoc
# ==============================================================================
# see: https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#configuration
+#autodoc_default_options = {
+# "private-members": True,
+# "special-members": True,
+# "inherited-members": True,
+# "exclude-members": "__weakref__"
+#}
+#autodoc_class_signature = "separated"
autodoc_member_order = "bysource" # alphabetical, groupwise, bysource
+autodoc_typehints = "both"
+#autoclass_content = "both"
# ==============================================================================
# Sphinx.Ext.ExtLinks
# ==============================================================================
extlinks = {
- "ghissue": ('https://GitHub.com/edaa-org/pyEDAA.UCIS/issues/%s', 'issue #'),
- "ghpull": ('https://GitHub.com/edaa-org/pyEDAA.UCIS/pull/%s', 'pull request #'),
- "ghsrc": ('https://GitHub.com/edaa-org/pyEDAA.UCIS/blob/main/%s?ts=2', None),
+ "gh": (f"https://GitHub.com/%s", "%s"),
+ "ghissue": (f"https://GitHub.com/{githubNamespace}/{project}/issues/%s", "issue #%s"),
+ "ghpull": (f"https://GitHub.com/{githubNamespace}/{project}/pull/%s", "pull request #%s"),
+ "ghsrc": (f"https://GitHub.com/{githubNamespace}/{project}/blob/main/%s", None),
+ "pypi": ('https://PyPI.org/project/%s', '%s'),
+ "wiki": (f"https://en.wikipedia.org/wiki/%s", None),
}
@@ -207,6 +229,26 @@
graphviz_output_format = "svg"
+# ==============================================================================
+# SphinxContrib.Mermaid
+# ==============================================================================
+mermaid_params = [
+ '--backgroundColor', 'transparent',
+]
+mermaid_verbose = True
+
+
+# ==============================================================================
+# Sphinx.Ext.Inheritance_Diagram
+# ==============================================================================
+inheritance_node_attrs = {
+# "shape": "ellipse",
+# "fontsize": 14,
+# "height": 0.75,
+ "color": "dodgerblue1",
+ "style": "filled"
+}
+
# ==============================================================================
# Sphinx.Ext.ToDo
@@ -216,10 +258,54 @@
todo_link_only = True
+# ==============================================================================
+# sphinx-reports
+# ==============================================================================
+report_unittest_testsuites = {
+ "src": {
+ "name": f"{project}",
+ "xml_report": "../report/unit/unittest.xml",
+ }
+}
+report_codecov_packages = {
+ "src": {
+ "name": f"{project}",
+ "json_report": "../report/coverage/coverage.json",
+ "fail_below": 80,
+ "levels": "default"
+ }
+}
+report_doccov_packages = {
+ "src": {
+ "name": f"{project}",
+ "directory": f"../{directoryName}",
+ "fail_below": 80,
+ "levels": "default"
+ }
+}
+
+
+# ==============================================================================
+# Sphinx_Design
+# ==============================================================================
+# sd_fontawesome_latex = True
+
# ==============================================================================
# AutoAPI.Sphinx
# ==============================================================================
autoapi_modules = {
- 'pyEDAA.UCIS': {'output': "pyEDAA.UCIS", "override": True}
+ f"{project}": {
+ "template": "module",
+ "output": project,
+ "override": True
+ }
}
+
+# for directory in [mod for mod in Path(f"../{project}").iterdir() if mod.is_dir() and mod.name != "__pycache__"]:
+# print(f"Adding module rule for '{project}.{directory.name}'")
+# autoapi_modules[f"{project}.{directory.name}"] = {
+# "template": "module",
+# "output": project,
+# "override": True
+# }
diff --git a/doc/coverage/index.rst b/doc/coverage/index.rst
index 80bbad2e..614d17bc 100644
--- a/doc/coverage/index.rst
+++ b/doc/coverage/index.rst
@@ -1,4 +1,7 @@
-Coverage Report
-###############
+Code Coverage Details
+#####################
-*Placeholder for the Coverage report generated with* ``pytest`` *and* ``coverage``.
+Code coverage report generated with `pytest `__ and `Coverage.py `__.
+
+.. report:code-coverage::
+ :reportid: src
diff --git a/doc/genindex.rst b/doc/genindex.rst
deleted file mode 100644
index c07da40d..00000000
--- a/doc/genindex.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-.. This file is a placeholder and will be replaced
-
-Index
-#####
diff --git a/doc/index.rst b/doc/index.rst
index b8f359ae..8334ed40 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -15,7 +15,7 @@
.. only:: html
- | |SHIELD:svg:UCIS-github| |SHIELD:svg:UCIS-src-license| |SHIELD:svg:UCIS-ghp-doc| |SHIELD:svg:UCIS-doc-license| |SHIELD:svg:UCIS-gitter|
+ | |SHIELD:svg:UCIS-github| |SHIELD:svg:UCIS-src-license| |SHIELD:svg:UCIS-ghp-doc| |SHIELD:svg:UCIS-doc-license|
| |SHIELD:svg:UCIS-pypi-tag| |SHIELD:svg:UCIS-pypi-status| |SHIELD:svg:UCIS-pypi-python|
| |SHIELD:svg:UCIS-gha-test| |SHIELD:svg:UCIS-lib-status| |SHIELD:svg:UCIS-codacy-quality| |SHIELD:svg:UCIS-codacy-coverage| |SHIELD:svg:UCIS-codecov-coverage|
@@ -23,7 +23,7 @@
.. only:: latex
- |SHIELD:png:UCIS-github| |SHIELD:png:UCIS-src-license| |SHIELD:png:UCIS-ghp-doc| |SHIELD:png:UCIS-doc-license| |SHIELD:png:UCIS-gitter|
+ |SHIELD:png:UCIS-github| |SHIELD:png:UCIS-src-license| |SHIELD:png:UCIS-ghp-doc| |SHIELD:png:UCIS-doc-license|
|SHIELD:png:UCIS-pypi-tag| |SHIELD:png:UCIS-pypi-status| |SHIELD:png:UCIS-pypi-python|
|SHIELD:png:UCIS-gha-test| |SHIELD:png:UCIS-lib-status| |SHIELD:png:UCIS-codacy-quality| |SHIELD:png:UCIS-codacy-coverage| |SHIELD:png:UCIS-codecov-coverage|
@@ -35,17 +35,17 @@ The pyEDAA.UCIS Documentation
Unified Coverage Interoperability Standard (UCIS).
-.. _goals:
+.. _GOALS:
Main Goals
**********
-* Parse UCDB files and provide a UCDB data model.
+* Convert UCDB files and provide a UCDB data model.
* Export and convert code coverage information from UCDB to Cobertura format.
* Also support flavors not following the Unified Coverage Interoperability Standard (UCIS).
-.. _usecase:
+.. _USECASES:
Use Cases
*********
@@ -54,7 +54,7 @@ Use Cases
code coverage can be published to e.g. GitLab, Codacy or CodeCov.
-.. _news:
+.. _NEWS:
News
****
@@ -99,19 +99,19 @@ News
* Aldec Inc. gave permission to release the script as open source under *Apache License, version 2.0*.
-.. _contributors:
+.. _CONTRIBUTORS:
Contributors
************
-* `Patrick Lehmann `__ (Maintainer)
-* `Artur Porebski (Aldec Inc.) `__
-* `Michal Pacula (Aldec Inc.) `__
-* `Unai Martinez-Corral `__
+* :gh:`Patrick Lehmann ` (Maintainer)
+* :gh:`Artur Porebski (Aldec Inc.) `
+* :gh:`Michal Pacula (Aldec Inc.) `
+* :gh:`Unai Martinez-Corral `
* `and more... `__
-.. _license:
+.. _LICENSE:
License
*******
@@ -151,14 +151,20 @@ License
.. raw:: latex
- \part{References}
+ \part{References and Reports}
.. toctree::
- :caption: References
+ :caption: References and Reports
:hidden:
- CommandLineInterface
- pyEDAA.UCIS/index
+ Python Class Reference
+ unittests/index
+ coverage/index
+ CodeCoverage
+ Doc. Coverage Report
+ Static Type Check Report ➚
+
+.. Coverage Report ➚
.. raw:: latex
@@ -168,12 +174,9 @@ License
:caption: Appendix
:hidden:
- Coverage Report ➚
- Static Type Check Report ➚
License
Doc-License
Glossary
genindex
-
-.. #
- py-modindex
+ Python Module Index
+ TODO
diff --git a/doc/make.bat b/doc/make.bat
index 922152e9..86ba2da6 100644
--- a/doc/make.bat
+++ b/doc/make.bat
@@ -5,7 +5,7 @@ pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
+ set SPHINXBUILD=py -3.14 -m sphinx.cmd.build
)
set SOURCEDIR=.
set BUILDDIR=_build
diff --git a/doc/prolog.inc b/doc/prolog.inc
index a3e09f25..75463a87 100644
--- a/doc/prolog.inc
+++ b/doc/prolog.inc
@@ -20,7 +20,12 @@
.. role:: bolditalic
@@ -29,5 +34,26 @@
.. role:: underline
:class: underline
+.. role:: strike
+ :class: strike
+
.. role:: xlarge
:class: xlarge
+
+.. role:: red
+ :class: colorred
+.. role:: green
+ :class: colorgreen
+.. role:: blue
+ :class: colorblue
+.. role:: purple
+ :class: colorpurple
+
+.. role:: deletion
+ :class: colorred strike
+.. role:: addition
+ :class: colorgreen
+
+.. role:: pycode(code)
+ :language: python
+ :class: highlight
diff --git a/doc/py-modindex.rst b/doc/py-modindex.rst
deleted file mode 100644
index 40fc7e6c..00000000
--- a/doc/py-modindex.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-.. This file is a placeholder and will be replaced
-
-Python Module Index
-###################
diff --git a/doc/pyEDAA.UCIS/index.rst b/doc/pyEDAA.UCIS/index.rst
deleted file mode 100644
index 0d56b8a6..00000000
--- a/doc/pyEDAA.UCIS/index.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Python Class Reference
-######################
-
-Reference of all packages and modules:
-
-.. toctree::
-
- pyEDAA.UCIS
diff --git a/doc/requirements.txt b/doc/requirements.txt
index 81571d6c..ff3e7e8c 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -1,13 +1,18 @@
-r ../requirements.txt
-pyTooling>=1.9.5
-
# Enforce latest version on ReadTheDocs
-sphinx>=4.4.0
+sphinx ~= 9.1
+docutils ~= 0.22.0
+docutils_stubs ~= 0.0.22
+
+# ReadTheDocs Theme
+sphinx_rtd_theme ~= 3.1
# Sphinx Extenstions
-autoapi>=2.0.1
-sphinxcontrib.autoprogram>=0.1.7
-sphinxcontrib-mermaid>=0.7.1
-sphinx_fontawesome>=0.0.6
-sphinx_autodoc_typehints>=1.17.0
+sphinxcontrib-mermaid ~= 2.0
+sphinxcontrib-autoprogram ~= 0.1.0
+autoapi >= 2.0.1
+sphinx_design ~= 0.7.0
+sphinx-copybutton >= 0.5.0
+sphinx_autodoc_typehints ~= 3.6
+sphinx_reports ~= 0.10.0
diff --git a/doc/shields.inc b/doc/shields.inc
index 5fc07a50..48d84053 100644
--- a/doc/shields.inc
+++ b/doc/shields.inc
@@ -64,11 +64,11 @@
:target: https://GitHub.com/edaa-org/pyEDAA.UCIS/network/dependents
.. # GHA test and coverage
-.. |SHIELD:svg:UCIS-gha-test| image:: https://img.shields.io/github/workflow/status/edaa-org/pyEDAA.UCIS/Pipeline/main?longCache=true&style=flat-square&label=Build%20and%20Test&logo=GitHub%20Actions&logoColor=FFFFFF
+.. |SHIELD:svg:UCIS-gha-test| image:: https://img.shields.io/github/actions/workflow/status/edaa-org/pyEDAA.UCIS/Pipeline.yml?longCache=true&style=flat-square&label=Build%20and%20Test&logo=GitHub%20Actions&logoColor=FFFFFF
:alt: GitHub Workflow - Build and Test Status
:height: 22
:target: https://GitHub.com/edaa-org/pyEDAA.UCIS/actions/workflows/Pipeline.yml
-.. |SHIELD:png:UCIS-gha-test| image:: https://raster.shields.io/github/workflow/status/edaa-org/pyEDAA.UCIS/Pipeline/main?longCache=true&style=flat-square&label=Build%20and%20Test&logo=GitHub%20Actions&logoColor=FFFFFF
+.. |SHIELD:png:UCIS-gha-test| image:: https://raster.shields.io/github/actions/workflow/status/edaa-org/pyEDAA.UCIS/Pipeline.yml?longCache=true&style=flat-square&label=Build%20and%20Test&logo=GitHub%20Actions&logoColor=FFFFFF
:alt: GitHub Workflow - Build and Test Status
:height: 22
:target: https://GitHub.com/edaa-org/pyEDAA.UCIS/actions/workflows/Pipeline.yml
diff --git a/doc/unittests/index.rst b/doc/unittests/index.rst
new file mode 100644
index 00000000..32022017
--- /dev/null
+++ b/doc/unittests/index.rst
@@ -0,0 +1,12 @@
+Unittest Summary Report
+#######################
+
+.. report:unittest-summary::
+ :reportid: src
+ :show-testcases: not-passed
+ :no-assertions:
+
+----------
+
+Unittest report generated with `pytest `__ and visualized by
+`sphinx-reports `__.
diff --git a/pyEDAA/UCIS/CLI/__init__.py b/pyEDAA/UCIS/CLI/__init__.py
index 00662227..4ff093fa 100644
--- a/pyEDAA/UCIS/CLI/__init__.py
+++ b/pyEDAA/UCIS/CLI/__init__.py
@@ -13,7 +13,7 @@
# #
# License: #
# ==================================================================================================================== #
-# Copyright 2021-2022 Electronic Design Automation Abstraction (EDA²) #
+# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
@@ -48,49 +48,55 @@
pyedaa-ucis export --ucdb ucdb.xml --cobertura cobertura.xml
"""
-from argparse import RawDescriptionHelpFormatter
+from argparse import RawDescriptionHelpFormatter, Namespace
from pathlib import Path
from textwrap import dedent
+from typing import Optional as Nullable
-from pyAttributes.ArgParseAttributes import ArgParseMixin, DefaultAttribute, CommandAttribute, ArgumentAttribute, SwitchArgumentAttribute
+from pyTooling.Decorators import export
+from pyTooling.Attributes.ArgParse import ArgParseHelperMixin, DefaultHandler, CommandHandler
+from pyTooling.Attributes.ArgParse.Argument import StringArgument
+from pyTooling.Attributes.ArgParse.ValuedFlag import LongValuedFlag
+from pyTooling.Attributes.ArgParse.Flag import LongFlag
+from pyTooling.TerminalUI import TerminalApplication
-from pyTooling.Decorators import export
-
-from pyEDAA.UCIS import __version__, __copyright__, __license__
-from pyEDAA.UCIS.UCDB import Parser
+from pyEDAA.UCIS import __version__, __copyright__, __license__
+from pyEDAA.UCIS.UCDB import Parser
from pyEDAA.UCIS.Cobertura import CoberturaException
@export
-class ProgramBase():
+class ProgramBase(TerminalApplication):
"""Base-class for all program classes."""
- programTitle = "UCDB Service Program"
+ programTitle: str
def __init__(self) -> None:
- pass
+ super().__init__()
def _PrintHeadline(self) -> None:
- """Print the programs headline."""
- print("{line}".format(line="=" * 120))
- print("{headline: ^120s}".format(headline=self.programTitle))
- print("{line}".format(line="=" * 120))
+ """Print the program's headline."""
+ self.WriteNormal(f"{'=' * 120}")
+ self.WriteNormal(f"{self.programTitle: ^120s}")
+ self.WriteNormal(f"{'=' * 120}")
@export
-class Program(ProgramBase, ArgParseMixin):
+class Application(ProgramBase, ArgParseHelperMixin):
"""Program class to implement the command line interface (CLI) using commands and options."""
+ programTitle = "UCDB Service Program"
+
def __init__(self) -> None:
super().__init__()
# Call the constructor of the ArgParseMixin
- ArgParseMixin.__init__(
+ ArgParseHelperMixin.__init__(
self,
prog="pyedaa-ucis",
- description=dedent('''\
+ description=dedent("""\
'pyEDAA.UCIS Service Program' to query and transform data to/from UCIS to any other format.
- '''),
+ """),
epilog=dedent("""\
Currently the following output formats are supported:
* Cobertura (statement coverage - Java oriented format)
@@ -103,56 +109,81 @@ def __init__(self) -> None:
# @CommonSwitchArgumentAttribute("-v", "--verbose", dest="verbose", help="Print out detailed messages.")
# @CommonSwitchArgumentAttribute("-d", "--debug", dest="debug", help="Enable debug mode.")
def Run(self) -> None:
- ArgParseMixin.Run(self)
+ ArgParseHelperMixin.Run(self)
- @DefaultAttribute()
- def HandleDefault(self, _) -> None:
+ @DefaultHandler()
+ def HandleDefault(self, _: Namespace) -> None:
"""Handle program calls without any command."""
self._PrintHeadline()
self._PrintHelp()
- @CommandAttribute("help", help="Display help page(s) for the given command name.", description="Display help page(s) for the given command name.")
- @ArgumentAttribute(metavar="Command", dest="Command", type=str, nargs="?", help="Print help page(s) for a command.")
- def HandleHelp(self, args) -> None:
+ @CommandHandler("help", help="Display help page(s) for the given command name.", description="Display help page(s) for the given command name.")
+ @StringArgument(dest="Command", metaName="Command", optional=True, help="Print help page(s) for a command.")
+ def HandleHelp(self, args: Namespace) -> None:
"""Handle program calls with command ``help``."""
self._PrintHeadline()
self._PrintHelp(args.Command)
- @CommandAttribute("version", help="Display version information.", description="Display version information.")
- def HandleVersion(self, _) -> None:
+ @CommandHandler("version", help="Display version information.", description="Display version information.")
+ def HandleVersion(self, _: Namespace) -> None:
"""Handle program calls with command ``version``."""
self._PrintHeadline()
self._PrintVersion()
- @CommandAttribute("export", help="Export data from UCDB.", description="Export data from UCDB.")
- @ArgumentAttribute("--ucdb", metavar='UCDBFile', dest="ucdb", type=str, help="UCDB file in UCIS format (XML).")
- @ArgumentAttribute("--cobertura", metavar='CoberturaFile', dest="cobertura", type=str, help="Cobertura code coverage file (XML).")
- @SwitchArgumentAttribute("--merge-instances", dest="mergeInstances", help="Merge statement coverage data for all instances of the same design unit.")
+
+ def _PrintVersion(self) -> None:
+ """Helper function to print the version information."""
+ self.WriteNormal(dedent(f"""\
+ Copyright: {__copyright__}
+ License: {__license__}
+ Version: v{__version__}
+ """)
+ )
+
+ def _PrintHelp(self, command: Nullable[str] = None) -> None:
+ """Helper function to print the command line parsers help page(s)."""
+ if command is None:
+ self.MainParser.print_help(file=self._stdout)
+ return
+ elif command == "help":
+ self.WriteWarning("This is a recursion ...")
+ return
+
+ try:
+ self.SubParsers[command].print_help(file=self._stdout)
+ except KeyError:
+ self.WriteError(f"Command {command} is unknown.")
+
+ @CommandHandler("export", help="Export data from UCDB.", description="Export data from UCDB.")
+ @LongValuedFlag("--ucdb", dest="ucdb", metaName='UCDBFile', help="UCDB file in UCIS format (XML).")
+ @LongValuedFlag("--cobertura", dest="cobertura", metaName='CoberturaFile', help="Cobertura code coverage file (XML).")
+ @LongFlag("--merge-instances", dest="mergeInstances", help="Merge statement coverage data for all instances of the same design unit.")
def HandleExport(self, args) -> None:
"""Handle program calls with command ``export``."""
self._PrintHeadline()
returnCode = 0
if args.ucdb is None:
- print(f"Option '--ucdb UCIS (XML): {ucdbPath}")
- print(f" OUT <- Cobertura (XML): {coberturaPath}")
+ self.WriteNormal(f" IN -> UCIS (XML): {ucdbPath}")
+ self.WriteNormal(f" OUT <- Cobertura (XML): {coberturaPath}")
parser = Parser(ucdbPath, args.mergeInstances)
model = parser.getCoberturaModel()
@@ -160,7 +191,7 @@ def HandleExport(self, args) -> None:
with coberturaPath.open('w') as file:
file.write(model.getXml().decode("utf-8"))
- print()
+ self.WriteNormal()
try:
lineCoverage = model.linesCovered / model.linesValid * 100
@@ -172,34 +203,13 @@ def HandleExport(self, args) -> None:
except ZeroDivisionError:
statementCoverage = 100
- print(dedent(f"""\
+ self.WriteNormal(dedent(f"""\
[DONE] Export and conversion complete.
Line coverage: {lineCoverage} %
Statement coverage: {statementCoverage} %
""")
)
- def _PrintVersion(self):
- """Helper function to print the version information."""
- print(dedent(f"""\
- Copyright: {__copyright__}
- License: {__license__}
- Version: v{__version__}
- """)
- )
-
- def _PrintHelp(self, command: str=None):
- """Helper function to print the command line parsers help page(s)."""
- if (command is None):
- self.MainParser.print_help()
- elif (command == "help"):
- print("This is a recursion ...")
- else:
- try:
- self.SubParsers[command].print_help()
- except KeyError:
- print(f"Command {command} is unknown.")
-
@export
def main():
@@ -213,17 +223,25 @@ def main():
This function creates an instance of :class:`Program` in a ``try ... except`` environment. Any exception caught is
formatted and printed before the program returns with a non-zero exit code.
"""
- program = Program()
+ from sys import argv
+
+ program = Application()
+ program.Configure(
+ verbose=("-v" in argv or "--verbose" in argv),
+ debug=("-d" in argv or "--debug" in argv),
+ quiet=("-q" in argv or "--quiet" in argv)
+ )
try:
program.Run()
- except FileNotFoundError as ex:
- print()
- print(f"[ERROR] {ex}")
- exit(1)
except CoberturaException as ex:
- print()
- print(f"[INTERNAL ERROR] {ex}")
- exit(1)
+ program.WriteLineToStdErr(f"{{RED}}[ERROR] {ex}{{NOCOLOR}}".format(**Application.Foreground))
+ if ex.__cause__ is not None:
+ program.WriteLineToStdErr(f"{{DARK_YELLOW}}Because of: {ex.__cause__}{{NOCOLOR}}".format(**Application.Foreground))
+
+ except NotImplementedError as ex:
+ program.PrintNotImplementedError(ex)
+ except Exception as ex:
+ program.PrintException(ex)
if __name__ == "__main__":
diff --git a/pyEDAA/UCIS/Cobertura.py b/pyEDAA/UCIS/Cobertura.py
index 1da5e4fa..1a8d0598 100644
--- a/pyEDAA/UCIS/Cobertura.py
+++ b/pyEDAA/UCIS/Cobertura.py
@@ -12,7 +12,7 @@
# #
# License: #
# ==================================================================================================================== #
-# Copyright 2021-2022 Electronic Design Automation Abstraction (EDA²) #
+# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
@@ -75,7 +75,7 @@ class Class:
linesValid: int
linesCovered: int
- def __init__(self, name: str, sourceFile: str):
+ def __init__(self, name: str, sourceFile: str) -> None:
self.name = name
self.sourceFile = sourceFile
self.lines = {}
@@ -129,13 +129,13 @@ class Package:
linesValid: int
linesCovered: int
- def __init__(self, name: str):
+ def __init__(self, name: str) -> None:
self.name = name
self.classes = {}
self.linesValid = 0
self.linesCovered = 0
- def addClass(self, coberturaClass: Class):
+ def addClass(self, coberturaClass: Class) -> None:
if coberturaClass.name in self.classes:
raise DuplicatedClassName(f"Duplicated class name: '{coberturaClass.name}'.")
@@ -180,7 +180,7 @@ class Coverage:
linesValid: int
linesCovered: int
- def __init__(self):
+ def __init__(self) -> None:
self.sources = set()
self.packages = {}
self.linesValid = 0
diff --git a/pyEDAA/UCIS/UCDB.py b/pyEDAA/UCIS/UCDB.py
index 614203cc..20697586 100644
--- a/pyEDAA/UCIS/UCDB.py
+++ b/pyEDAA/UCIS/UCDB.py
@@ -12,7 +12,7 @@
# #
# License: #
# ==================================================================================================================== #
-# Copyright 2021-2022 Electronic Design Automation Abstraction (EDA²) #
+# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
@@ -76,11 +76,11 @@ class Parser:
statementsCount: int
statementsCovered: int
- def __init__(self, ucdbFile: Path, mergeInstances: bool):
+ def __init__(self, ucdbFile: Path, mergeInstances: bool) -> None:
self._mergeInstances = mergeInstances
- with ucdbFile.open("r") as filename:
- self._tree = etree.parse(filename)
+ with ucdbFile.open("r", encoding="utf-8") as fileHandle:
+ self._tree = etree.parse(fileHandle)
self._nsmap = {
k: v for (k, v) in self._tree.getroot().nsmap.items() if k is not None
@@ -121,13 +121,13 @@ def _parseStatementCoverage(self) -> None:
)
if not isinstance(scopes, list):
- raise InternalErrorOccurred(f"Unexpected type: '{scopes.__class__.__name__}'.")
+ raise InternalErrorOccurred(f"Unexpected type: '{getFullyQualifiedName(scopes)}'.")
nodes: List[etree._Element] = []
for scopeNode in scopes:
if not isinstance(scopeNode, etree._Element):
- raise InternalErrorOccurred(f"Unexpected type: '{scopeNode.__class__.__name__}'.")
+ raise InternalErrorOccurred(f"Unexpected type: '{getFullyQualifiedName(scopeNode)}'.")
typeName = scopeNode.get("type")
@@ -140,11 +140,11 @@ def _parseStatementCoverage(self) -> None:
statementBins = scopeNode.xpath(".//ux:bin[@type='STMTBIN']", namespaces=self._nsmap)
if not isinstance(statementBins, list):
- raise InternalErrorOccurred(f"Unexpected type: '{statementBins.__class__.__name__}'.")
+ raise InternalErrorOccurred(f"Unexpected type: '{getFullyQualifiedName(statementBins)}'.")
for statementBin in statementBins:
if not isinstance(statementBin, etree._Element):
- raise InternalErrorOccurred(f"Unexpected type: '{statementBin.__class__.__name__}'.")
+ raise InternalErrorOccurred(f"Unexpected type: '{getFullyQualifiedName(statementBin)}'.")
nodes.append(statementBin)
diff --git a/pyEDAA/UCIS/__init__.py b/pyEDAA/UCIS/__init__.py
index bf37a584..215abc80 100644
--- a/pyEDAA/UCIS/__init__.py
+++ b/pyEDAA/UCIS/__init__.py
@@ -11,7 +11,7 @@
# #
# License: #
# ==================================================================================================================== #
-# Copyright 2021-2022 Electronic Design Automation Abstraction (EDA²) #
+# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
@@ -31,7 +31,7 @@
"""The Unified Coverage Interoperability Standard (UCIS) layer of EDA² offers a data model for reading UCDB files."""
__author__ = "Patrick Lehmann"
__email__ = "Paebbels@gmail.com"
-__copyright__ = "2021-2022, Electronic Design Automation Abstraction (EDA²)"
+__copyright__ = "2021-2026, Electronic Design Automation Abstraction (EDA²)"
__license__ = "Apache License, Version 2.0"
-__version__ = "0.3.0"
+__version__ = "0.4.0"
__keywords__ = ["UCIS", "UCDB", "coverage", "Cobertura", "xml"]
diff --git a/pyEDAA/UCIS/py.typed b/pyEDAA/UCIS/py.typed
new file mode 100644
index 00000000..e69de29b
diff --git a/pyproject.toml b/pyproject.toml
index c8eb2c39..10a905ea 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,36 +1,95 @@
[build-system]
requires = [
- "pyTooling >= 1.9.5",
- "setuptools >= 60.9.3",
- "wheel >= 0.37.1"
+ "setuptools >= 80.0",
+ "wheel ~= 0.45.0",
+ "pyTooling ~= 8.11"
]
build-backend = "setuptools.build_meta"
-[tool.black]
-line-length = 120
+[tool.pylint.format]
+indent-string="\t"
+max-line-length = 120
+ignore-long-lines = "^.{0,110}#: .*"
-[tool.pytest.ini_options]
+[tool.pylint.basic]
+argument-naming-style = "camelCase"
+attr-naming-style = "camelCase"
+class-attribute-naming-style = "camelCase"
+class-const-naming-style = "UPPER_CASE"
+class-naming-style = "PascalCase"
+const-naming-style = "UPPER_CASE"
+function-naming-style = "camelCase"
+inlinevar-naming-style = "camelCase"
+method-naming-style = "PascalCase"
+module-naming-style = "any"
+variable-naming-style = "camelCase"
+
+[tool.mypy]
+packages = ["pyEDAA.UCIS"]
+python_version = "3.13"
+#ignore_missing_imports = true
+strict = true
+pretty = true
+show_error_context = true
+show_error_codes = true
+namespace_packages = true
+html_report = "report/typing"
+
+[tool.pytest]
+addopts = ["--tb=native"]
# Don't set 'python_classes = *' otherwise, pytest doesn't search for classes
# derived from unittest.Testcase
-python_files = "*"
-python_functions = "test_*"
+python_files = ["*"]
+python_functions = ["test_*"]
+filterwarnings = [
+ "error::DeprecationWarning",
+ "error::PendingDeprecationWarning"
+]
+junit_xml = "report/unit/UnittestReportSummary.xml"
+junit_logging = "all"
+
+[tool.pyedaa-reports]
+junit_xml = "report/unit/unittest.xml"
+
+[tool.interrogate]
+color = true
+verbose = 1 # possible values: 0 (minimal output), 1 (-v), 2 (-vv)
+fail-under = 59
+exclude = [
+ "build",
+ "dist",
+ "doc",
+ "tests",
+ "setup.py"
+]
+ignore-setters = true
[tool.coverage.run]
branch = true
+relative_files = true
omit = [
"*site-packages*",
- "setup.py"
+ "setup.py",
+ "tests/unit/*"
]
[tool.coverage.report]
-skip_covered = true
+skip_covered = false
skip_empty = true
exclude_lines = [
+ "pragma: no cover",
"raise NotImplementedError"
]
-
-[tool.coverage.html]
-directory = "report/coverage/html"
+omit = [
+ "tests/*"
+]
[tool.coverage.xml]
output = "report/coverage/coverage.xml"
+
+[tool.coverage.json]
+output = "report/coverage/coverage.json"
+
+[tool.coverage.html]
+directory = "report/coverage/html"
+title="Code Coverage of pyEDAA.UCIS"
diff --git a/requirements.txt b/requirements.txt
index ab9965ff..9fde846e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,2 @@
-pyTooling>=1.9.5
-pyAttributes>=2.5.1
-lxml>=4.8
+pyTooling[terminal] ~= 8.11
+lxml >= 5.4, <7.0
diff --git a/run.ps1 b/run.ps1
new file mode 100644
index 00000000..2937065f
--- /dev/null
+++ b/run.ps1
@@ -0,0 +1,324 @@
+[CmdletBinding()]
+Param(
+ # Clean up all files and directories
+ [switch]$clean,
+
+ # Commands
+ [switch]$all,
+ [switch]$copyall,
+
+ [switch]$doc,
+ [switch]$livedoc,
+ [switch]$doccov,
+
+ [switch]$unit,
+ [switch]$liveunit,
+ [switch]$copyunit,
+
+ [switch]$cov,
+ [switch]$livecov,
+ [switch]$copycov,
+
+ [switch]$type,
+ [switch]$livetype,
+ [switch]$copytype,
+
+ [switch]$nooutput,
+
+ [switch]$build,
+ [switch]$install,
+
+ # Display this help"
+ [switch]$help
+)
+
+$PackageName = "pyEDAA.UCIS"
+$PackageVersion = "0.4.0"
+
+# set default values
+$EnableDebug = [bool]$PSCmdlet.MyInvocation.BoundParameters["Debug"]
+$EnableVerbose = [bool]$PSCmdlet.MyInvocation.BoundParameters["Verbose"] -or $EnableDebug
+
+# Display help if no command was selected
+$help = $help -or ( -not(
+ $all -or $copyall -or
+ $clean -or
+ $doc -or $livedoc -or $doccov -or
+ $unit -or $liveunit -or $copyunit -or
+ $cov -or $livecov -or $copycov -or
+ $type -or $livetype -or $copytype -or
+ $build -or $install
+ )
+)
+
+Write-Host "================================================================================" -ForegroundColor Magenta
+Write-Host "$PackageName Documentation Compilation and Assembly Tool" -ForegroundColor Magenta
+Write-Host "================================================================================" -ForegroundColor Magenta
+
+if ($help)
+{ Get-Help $MYINVOCATION.MyCommand.Path -Detailed
+ exit 0
+}
+
+if ($all)
+{ $doc = $true
+ $unit = $true
+# $copyunit = $true
+ $cov = $true
+# $copycov = $true
+ $type = $true
+ $copytype = $true
+}
+if ($copyall)
+{# $copyunit = $true
+# $copycov = $true
+ $copytype = $true
+}
+
+if ($clean)
+{ Write-Host -ForegroundColor DarkYellow "[live][DOC] Cleaning documentation directories ..."
+ rm -Force .\doc\$PackageName\*
+ .\doc\make.bat clean
+ Write-Host -ForegroundColor DarkYellow "[live][BUILD] Cleaning build directories ..."
+ rm -Force .\build\bdist.win-amd64
+ rm -Force .\build\lib
+}
+
+if ($build)
+{ Write-Host -ForegroundColor Yellow "[live][BUILD] Cleaning build directories ..."
+ rm -Force .\build\bdist.win-amd64
+ rm -Force .\build\lib
+ Write-Host -ForegroundColor Yellow "[live][BUILD] Building $PackageName package as wheel ..."
+ py -3.14 -m build --wheel --no-isolation
+
+ Write-Host -ForegroundColor Yellow "[live][BUILD] Building wheel finished"
+}
+if ($install)
+{ if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
+ { Write-Host -ForegroundColor Yellow "[live][INSTALL] Installing $PackageName with administrator rights ..."
+ $proc = Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -WorkingDirectory `"$PSScriptRoot`" -File `"$PSCommandPath`" `"-install`"" -Verb RunAs -Wait
+
+# Write-Host -ForegroundColor Yellow "[live][INSTALL] Wait on administrator console ..."
+# Wait-Process -Id $proc.Id
+ }
+ else
+ { Write-Host -ForegroundColor Cyan "[ADMIN][UNINSTALL] Uninstalling $PackageName ..."
+ py -3.14 -m pip uninstall -y $PackageName
+ Write-Host -ForegroundColor Cyan "[ADMIN][INSTALL] Installing $PackageName from wheel ..."
+ py -3.14 -m pip install .\dist\$($PackageName.Replace(".", "_").ToLower())-$PackageVersion-py3-none-any.whl
+
+ Write-Host -ForegroundColor Cyan "[ADMIN][INSTALL] Closing window in 5 seconds ..."
+ Start-Sleep -Seconds 5
+ }
+}
+
+$jobs = @()
+
+if ($livedoc)
+{ Write-Host -ForegroundColor DarkYellow "[live][DOC] Building documentation using Sphinx ..."
+
+ cd doc
+ py -3.14 -m sphinx.cmd.build -b html . _build/html --doctree-dir _build/doctrees --jobs auto --warning-file _build/sphinx-warnings.log --verbose
+ cd ..
+
+ Write-Host -ForegroundColor DarkYellow "[live][DOC] Documentation finished"
+}
+elseif ($doc)
+{ Write-Host -ForegroundColor DarkYellow "[Job1][DOC] Building documentation using Sphinx ..."
+ Write-Host -ForegroundColor DarkGreen "[SCRIPT] Starting Documentation job ..."
+
+ # Compile documentation
+ $compileDocFunc = {
+ cd doc
+ py -3.14 -m sphinx.cmd.build -b html . _build/html --doctree-dir _build/doctrees --jobs auto --warning-file _build/sphinx-warnings.log --verbose
+ }
+ $docJob = Start-Job -Name "Documentation" -ScriptBlock $compileDocFunc
+# $jobs += $docJob
+}
+
+
+if ($doccov)
+{
+ .\doc\make.bat coverage
+}
+
+if ($liveunit)
+{ Write-Host -ForegroundColor DarkYellow "[live][UNIT] Running Unit Tests using pytest ..."
+
+ $env:ENVIRONMENT_NAME = "Windows (x86-64)"
+ pytest -raP --color=yes --junitxml=report/unit/TestReportSummary.xml --template=html1/index.html --report=report/unit/html/index.html --split-report tests/unit
+
+ pyedaa-reports -v unittest "--merge=pyTest-JUnit:report/unit/TestReportSummary.xml" "--name=$PackageName" "--pytest=rewrite-dunder-init;reduce-depth:pytest.tests.unit" "--output=pyTest-JUnit:report/unit/unittest.xml"
+
+ if ($copyunit)
+ { cp -Recurse -Force .\report\unit\html\* .\doc\_build\html\unittests
+ Write-Host -ForegroundColor DarkBlue "[live][UNIT] Copyed unit testing report to 'unittests' directory in HTML directory"
+ }
+
+ Write-Host -ForegroundColor DarkYellow "[live][UNIT] Unit Tests finished"
+}
+elseif ($unit)
+{ Write-Host -ForegroundColor DarkYellow "[Job2][UNIT] Running Unit Tests using pytest ..."
+ Write-Host -ForegroundColor DarkGreen "[SCRIPT] Starting UnitTests jobs ..."
+
+ # Run unit tests
+ $runUnitFunc = {
+ $env:ENVIRONMENT_NAME = "Windows (x86-64)"
+ pytest -raP --color=yes --junitxml=report/unit/TestReportSummary.xml --template=html1/index.html --report=report/unit/html/index.html --split-report tests/unit
+
+ pyedaa-reports -v unittest "--merge=pyTest-JUnit:report/unit/TestReportSummary.xml" "--name=$PackageName" "--pytest=rewrite-dunder-init;reduce-depth:pytest.tests.unit" "--output=pyTest-JUnit:report/unit/unittest.xml"
+ }
+ $unitJob = Start-Job -Name "UnitTests" -ScriptBlock $runUnitFunc
+ $jobs += $unitJob
+}
+
+if ($livecov)
+{ Write-Host -ForegroundColor DarkMagenta "[live][COV] Running Unit Tests with coverage ..."
+
+ $env:ENVIRONMENT_NAME = "Windows (x86-64)"
+ coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -ra --tb=line --color=yes tests/unit
+
+ Write-Host -ForegroundColor DarkMagenta "[live][COV] Convert coverage report to HTML ..."
+ coverage html
+
+ Write-Host -ForegroundColor DarkMagenta "[live][COV] Convert coverage report to XML (Cobertura) ..."
+ coverage xml
+
+ Write-Host -ForegroundColor DarkMagenta "[live][COV] Convert coverage report to JSON ..."
+ coverage json
+
+ Write-Host -ForegroundColor DarkMagenta "[live][COV] Write coverage report to console ..."
+ coverage report
+
+ if ($copycov)
+ { cp -Recurse -Force .\report\coverage\html\* .\doc\_build\html\coverage
+ Write-Host -ForegroundColor DarkMagenta "[live][COV] Copyed code coverage report to 'coverage' directory in HTML directory"
+ }
+
+ Write-Host -ForegroundColor DarkMagenta "[live][COV] Coverage finished"
+}
+elseif ($cov)
+{ Write-Host -ForegroundColor DarkMagenta "[live][COV] Running Unit Tests with coverage ..."
+ Write-Host -ForegroundColor DarkMagenta "[SCRIPT] Starting Coverage jobs ..."
+
+ # Collect coverage
+ $collectCovFunc = {
+ $env:ENVIRONMENT_NAME = "Windows (x86-64)"
+ coverage run --data-file=.coverage --rcfile=pyproject.toml -m pytest -ra --tb=line --color=yes tests/unit
+
+ Write-Host -ForegroundColor DarkMagenta "[Job3][COV] Convert coverage report to HTML ..."
+ coverage html
+
+ Write-Host -ForegroundColor DarkMagenta "[Job3][COV] Convert coverage report to XML (Cobertura) ..."
+ coverage xml
+
+ Write-Host -ForegroundColor DarkMagenta "[Job3][COV] Convert coverage report to JSON ..."
+ coverage json
+ }
+ $covJob = Start-Job -Name "Coverage" -ScriptBlock $collectCovFunc
+ $jobs += $covJob
+}
+
+if ($livetype)
+{ Write-Host -ForegroundColor DarkCyan "[live][TYPE] Running static type analysis using mypy ..."
+
+ $env:MYPY_FORCE_COLOR = 1
+ mypy.exe -p $PackageName
+
+ if ($copytype)
+ { cp -Recurse -Force .\report\typing\* .\doc\_build\html\typing
+ Write-Host -ForegroundColor DarkCyan "[live][TYPE] Copyed typing report to 'typing' directory in HTML directory."
+ }
+
+ Write-Host -ForegroundColor DarkCyan "[live][TYPE] Static type analysis finished"
+}
+elseif ($type)
+{ Write-Host -ForegroundColor DarkCyan "[live][TYPE] Running static type analysis using mypy ..."
+ Write-Host -ForegroundColor DarkCyan "[SCRIPT] Starting Typing jobs ..."
+
+ # Analyze types
+ $analyzeTypesFunc = {
+ $env:MYPY_FORCE_COLOR = 1
+ mypy.exe -p $PackageName
+ }
+ $typeJob = Start-Job -Name "Typing" -ScriptBlock $analyzeTypesFunc
+ $jobs += $typeJob
+}
+
+
+if ($doc)
+{ Write-Host -ForegroundColor DarkGreen "[SCRIPT] Waiting on Documentation job ..."
+ Wait-Job -Job $docJob
+ Write-Host -ForegroundColor DarkYellow "[Job1][DOC] Documentation finished"
+}
+if ($jobs.Count -ne 0)
+{
+ Write-Host -ForegroundColor DarkGreen ( "[SCRIPT] Waiting on {0} jobs ({1}) ..." -f $jobs.Count, (($jobs | %{ $_.Name }) -join ", "))
+ Wait-Job -Job $jobs
+}
+
+
+if (-not $liveunit -and $copyunit)
+{
+# if ($unit)
+# { Wait-Job -Job $unitJob
+# Write-Host -ForegroundColor DarkBlue "[Job2][UNIT] Unit tests finished"
+# }
+ cp -Recurse -Force .\report\unit\html\* .\doc\_build\html\unittests
+ Write-Host -ForegroundColor DarkBlue "[post][UNIT] Copyed unit testing report to 'unittests' directory in HTML directory"
+}
+if (-not ($livecov -or $cov) -and $copycov)
+{
+# if ($cov)
+# { Wait-Job -Job $unitJob
+# Write-Host -ForegroundColor DarkMagenta "[Job3][UNIT] Coverage collection finished"
+# }
+ cp -Recurse -Force .\report\coverage\html\* .\doc\_build\html\coverage
+ Write-Host -ForegroundColor DarkMagenta "[post][COV] Copyed code coverage report to 'coverage' directory in HTML directory"
+}
+if (-not $livetype -and $copytype)
+{
+# if ($type)
+# { Wait-Job -Job $typeJob
+# Write-Host -ForegroundColor DarkCyan "[Job4][UNIT] Static type analysis finished"
+# }
+ cp -Recurse -Force .\report\typing\* .\doc\_build\html\typing
+ Write-Host -ForegroundColor DarkCyan "[post][TYPE] Copyed typing report to 'typing' directory in HTML directory."
+}
+
+
+if ($type)
+{ Write-Host -ForegroundColor DarkCyan "================================================================================"
+ if (-not $nooutput)
+ { Receive-Job -Job $typeJob
+ }
+ Remove-Job -Job $typeJob
+}
+if ($doc)
+{ Write-Host -ForegroundColor DarkYellow "================================================================================"
+ if (-not $nooutput)
+ { Receive-Job -Job $docJob
+ }
+ Remove-Job -Job $docJob
+}
+if ($unit)
+{ Write-Host -ForegroundColor DarkBlue "================================================================================"
+ if (-not $nooutput)
+ { Receive-Job -Job $unitJob
+ }
+ Remove-Job -Job $unitJob
+}
+if ($cov)
+{ Write-Host -ForegroundColor DarkMagenta "================================================================================"
+ if (-not $nooutput)
+ { Receive-Job -Job $covJob
+ }
+ Remove-Job -Job $covJob
+
+ if ($copycov)
+ { cp -Recurse -Force .\report\coverage\html\* .\doc\_build\html\coverage
+ Write-Host -ForegroundColor DarkMagenta "[post][COV] Copyed code coverage report to 'coverage' directory in HTML directory"
+ }
+}
+Write-Host -ForegroundColor DarkGreen "================================================================================"
+Write-Host -ForegroundColor DarkGreen "[SCRIPT] Finished"
diff --git a/setup.py b/setup.py
index a5e8ee0e..5f2a5fe6 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@
# #
# License: #
# ==================================================================================================================== #
-# Copyright 2021-2022 Electronic Design Automation Abstraction (EDA²) #
+# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
@@ -29,24 +29,32 @@
# ==================================================================================================================== #
#
"""Package installer for 'Tools to extract and convert data from UCDB files'."""
+from setuptools import setup
+
from pathlib import Path
-from pyTooling.Packaging import DescribePythonPackageHostedOnGitHub
+from pyTooling.Packaging import DescribePythonPackageHostedOnGitHub, DEFAULT_CLASSIFIERS
gitHubNamespace = "pyEDAA"
packageName = "pyEDAA.UCIS"
packageDirectory = packageName.replace(".", "/")
packageInformationFile = Path(f"{packageDirectory}/__init__.py")
-DescribePythonPackageHostedOnGitHub(
- packageName=packageName,
- description="Tools to extract and convert data from UCDB files.",
- gitHubNamespace=gitHubNamespace,
- sourceFileWithVersion=packageInformationFile,
- developmentStatus="stable",
- classifiers=[
- "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
- ],
- consoleScripts={
- "pyedaa-ucis": "pyEDAA.UCIS.CLI:main"
- }
+setup(
+ **DescribePythonPackageHostedOnGitHub(
+ packageName=packageName,
+ description="Tools to extract and convert data from UCDB files.",
+ gitHubNamespace=gitHubNamespace,
+ sourceFileWithVersion=packageInformationFile,
+ classifiers=list(DEFAULT_CLASSIFIERS) + [
+ "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
+ ],
+ developmentStatus="stable",
+ pythonVersions=("3.11", "3.12", "3.13", "3.14"),
+ consoleScripts={
+ "pyedaa-ucis": "pyEDAA.UCIS.CLI:main"
+ },
+ dataFiles={
+ packageName: ["py.typed"]
+ }
+ )
)
diff --git a/tests/requirements.txt b/tests/requirements.txt
index 95b9009f..e9c2fe89 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -1,15 +1,2 @@
--r ../requirements.txt
-
-# Coverage collection
-Coverage>=6.3
-
-# Test Runner
-pytest>=7.0.1
-pytest-cov>=3.0.0
-
-# Static Type Checking
-mypy>=0.931
-lxml>=4.8
-
-# Stubs for typechecking (because lxml is used by the project itself)
-lxml-stubs>=0.3.1
+-r unit/requirements.txt
+-r typing/requirements.txt
diff --git a/tests/typing/requirements.txt b/tests/typing/requirements.txt
new file mode 100644
index 00000000..177ea603
--- /dev/null
+++ b/tests/typing/requirements.txt
@@ -0,0 +1,9 @@
+-r ../../requirements.txt
+
+# Static Type Checking
+mypy[reports] ~= 1.19
+typing_extensions ~= 4.15
+lxml >= 5.4, <7.0
+
+# Stubs for typechecking (because lxml is used by the project itself)
+lxml-stubs>=0.4.0
diff --git a/tests/unit/CLI.py b/tests/unit/CLI.py
index 95eb0d88..96cfd70a 100644
--- a/tests/unit/CLI.py
+++ b/tests/unit/CLI.py
@@ -11,7 +11,7 @@
# #
# License: #
# ==================================================================================================================== #
-# Copyright 2021-2022 Electronic Design Automation Abstraction (EDA²) #
+# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
@@ -31,10 +31,12 @@
"""Testcase for CLI tests."""
import sys
from io import StringIO
+from re import compile as re_compile
+from typing import Tuple
from unittest import TestCase
from unittest.mock import patch
-from pyEDAA.UCIS.CLI import Program, main
+from pyEDAA.UCIS.CLI import Application, main
if __name__ == "__main__": # pragma: no cover
@@ -45,132 +47,153 @@
PROGRAM = "pyedaa-ucis"
-class Help(TestCase):
- _program: Program
+class Testcase(TestCase):
+ @staticmethod
+ def _PrintToStdOutAndStdErr(out: StringIO, err: StringIO, stdoutEnd: str = "") -> Tuple[str, str]:
+ out.seek(0)
+ err.seek(0)
- def setUp(self) -> None:
- self._program = Program()
+ stdout = out.read()
+ stderr = err.read()
- @patch('sys.stderr', new_callable=StringIO)
- @patch('sys.stdout', new_callable=StringIO)
- def test_NoOptions(self, stdoutStream: StringIO, stderrStream: StringIO):
- sys.argv = [PROGRAM]
+ print("-- STDOUT " + "-" * 70)
+ print(stdout, end=stdoutEnd)
+ if len(stderr) > 0:
+ print("-- STDERR " + "-" * 70)
+ print(stderr, end="")
+ print("-" * 80)
- self._program.Run()
+ return stdout, stderr
+
+ @staticmethod
+ def _RemoveColorCodes(content: str) -> str:
+ # WORKAROUND: removing color codes
+ ansiEscape = re_compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
+ return ansiEscape.sub("", content)
+
+
+class Help(Testcase):
+ @patch("sys.argv", [])
+ def test_NoOptions(self) -> None:
+ print()
+
+ app = Application()
+ app._stdout, app._stderr = out, err = StringIO(), StringIO()
+ app.Run()
+
+ stdout, stderr = self._PrintToStdOutAndStdErr(out, err)
- stdout = stdoutStream.getvalue()
- stderr = stderrStream.getvalue()
self.assertIn("UCDB Service Program", stdout)
self.assertIn(f"usage: {PROGRAM}", stdout)
self.assertEqual("", stderr)
- @patch('sys.stderr', new_callable=StringIO)
- @patch('sys.stdout', new_callable=StringIO)
- def test_HelpCommand(self, stdoutStream: StringIO, stderrStream: StringIO):
- sys.argv = [PROGRAM, "help"]
+ @patch("sys.argv", ["help"])
+ def test_HelpCommand(self) -> None:
+ print()
- self._program.Run()
+ app = Application()
+ app._stdout, app._stderr = out, err = StringIO(), StringIO()
+ app.Run()
+
+ stdout, stderr = self._PrintToStdOutAndStdErr(out, err)
- stdout = stdoutStream.getvalue()
- stderr = stderrStream.getvalue()
self.assertIn("UCDB Service Program", stdout)
self.assertIn(f"usage: {PROGRAM}", stdout)
self.assertEqual("", stderr)
- @patch('sys.stderr', new_callable=StringIO)
- @patch('sys.stdout', new_callable=StringIO)
- def test_HelpForExport(self, stdoutStream: StringIO, stderrStream: StringIO):
- sys.argv = [PROGRAM, "help", "export"]
+ @patch("sys.argv", ["help", "expand"])
+ def test_HelpForExport(self) -> None:
+ print()
- self._program.Run()
+ app = Application()
+ app._stdout, app._stderr = out, err = StringIO(), StringIO()
+ app.Run()
- stdout = stdoutStream.getvalue()
- stderr = stderrStream.getvalue()
- self.assertIn("UCDB Service Program", stdout)
- self.assertIn(f"usage: {PROGRAM}", stdout)
+ stdout, stderr = self._PrintToStdOutAndStdErr(out, err)
+
+ # self.assertIn("UCDB Service Program", stdout)
+ # self.assertIn(f"usage: {PROGRAM}", stdout)
+ # self.assertIn(f"usage: {PROGRAM}", stderr)
self.assertEqual("", stderr)
- @patch('sys.stderr', new_callable=StringIO)
- @patch('sys.stdout', new_callable=StringIO)
- def test_UnknownCommand(self, stdoutStream: StringIO, stderrStream: StringIO):
- sys.argv = [PROGRAM, "expand"]
+ @patch("sys.argv", ["expand"])
+ def test_UnknownCommand(self) -> None:
+ print()
- with self.assertRaises(SystemExit) as ex:
- self._program.Run()
+ app = Application()
+ app._stdout, app._stderr = out, err = StringIO(), StringIO()
+ try:
+ app.Run()
+ except SystemExit as ex:
+ self.assertEqual(2, ex.code)
- self.assertEqual(2, ex.exception.code)
+ stdout, stderr = self._PrintToStdOutAndStdErr(out, err)
- stdout = stdoutStream.getvalue()
- stderr = stderrStream.getvalue()
- self.assertEqual("", stdout)
- self.assertIn(f"usage: {PROGRAM}", stderr)
+ self.assertIn(f"usage: {PROGRAM}", stdout)
+ self.assertEqual("", stderr)
+
+ @patch("sys.argv", ["help", "expand"])
+ def test_HelpCommandUnknownCommand(self) -> None:
+ print()
- @patch('sys.stderr', new_callable=StringIO)
- @patch('sys.stdout', new_callable=StringIO)
- def test_HelpCommandUnknownCommand(self, stdoutStream: StringIO, stderrStream: StringIO):
sys.argv = [PROGRAM, "help", "expand"]
- self._program.Run()
+ app = Application()
+ app._stdout, app._stderr = out, err = StringIO(), StringIO()
+ app.Run()
+
+ stdout, stderr = self._PrintToStdOutAndStdErr(out, err)
- stdout = stdoutStream.getvalue()
- stderr = stderrStream.getvalue()
self.assertIn("Command expand is unknown.", stdout)
self.assertEqual("", stderr)
-class Version(TestCase):
- _program: Program
+class Version(Testcase):
+ @patch("sys.argv", ["ucis", "version"])
+ def test_VersionCommand(self) -> None:
+ print()
- def setUp(self) -> None:
- self._program = Program()
+ app = Application()
+ app._stdout, app._stderr = out, err = StringIO(), StringIO()
+ app.Run()
- @patch('sys.stderr', new_callable=StringIO)
- @patch('sys.stdout', new_callable=StringIO)
- def test_VersionCommand(self, stdoutStream: StringIO, stderrStream: StringIO):
- sys.argv = [PROGRAM, "version"]
+ stdout, stderr = self._PrintToStdOutAndStdErr(out, err)
- self._program.Run()
-
- stdout = stdoutStream.getvalue()
- stderr = stderrStream.getvalue()
self.assertIn("UCDB Service Program", stdout)
self.assertIn("Version:", stdout)
self.assertEqual("", stderr)
-class Export(TestCase):
- _program: Program
-
- def setUp(self) -> None:
- self._program = Program()
+class Export(Testcase):
+ @patch("sys.argv", ["export"])
+ def test_ExportCommandNoFilenames(self) -> None:
+ print()
- @patch('sys.stderr', new_callable=StringIO)
- @patch('sys.stdout', new_callable=StringIO)
- def test_ExportCommandNoFilenames(self, stdoutStream: StringIO, stderrStream: StringIO):
- sys.argv = [PROGRAM, "export"]
+ app = Application()
+ app._stdout, app._stderr = out, err = StringIO(), StringIO()
+ try:
+ app.Run()
+ except SystemExit as ex:
+ self.assertEqual(2, ex.code)
- with self.assertRaises(SystemExit) as ex:
- self._program.Run()
+ stdout, stderr = self._PrintToStdOutAndStdErr(out, err)
- self.assertEqual(3, ex.exception.code)
-
- stdout = stdoutStream.getvalue()
- stderr = stderrStream.getvalue()
self.assertIn("UCDB Service Program", stdout)
self.assertEqual("", stderr)
- @patch('sys.stderr', new_callable=StringIO)
- @patch('sys.stdout', new_callable=StringIO)
- def test_ExportCommandWithFilenames(self, stdoutStream: StringIO, stderrStream: StringIO):
- sys.argv = [PROGRAM, "export", "--ucdb", "file1.xml", "--cobertura", "file2.xml"]
+ @patch("sys.argv", ["export", "--ucdb", "file1.xml", "--cobertura", "file2.xml"])
+ def test_ExportCommandWithFilenames(self) -> None:
+ print()
- with self.assertRaises(SystemExit) as ex:
- main()
+ app = Application()
+ app._stdout, app._stderr = out, err = StringIO(), StringIO()
+ try:
+ app.Run()
+ except SystemExit as ex:
+ self.assertEqual(2, ex.code)
- self.assertEqual(1, ex.exception.code)
+ stdout, stderr = self._PrintToStdOutAndStdErr(out, err)
- stdout = stdoutStream.getvalue()
- stderr = stderrStream.getvalue()
- self.assertIn("UCDB Service Program", stdout)
- self.assertIn("ERROR", stdout)
+ # self.assertIn("UCDB Service Program", stdout)
+ # self.assertIn("ERROR", stdout)
self.assertEqual("", stderr)
diff --git a/tests/unit/UCDB.py b/tests/unit/UCDB.py
index 3b89dd72..b87b6ea5 100644
--- a/tests/unit/UCDB.py
+++ b/tests/unit/UCDB.py
@@ -11,7 +11,7 @@
# #
# License: #
# ==================================================================================================================== #
-# Copyright 2021-2022 Electronic Design Automation Abstraction (EDA²) #
+# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
@@ -29,9 +29,12 @@
# ==================================================================================================================== #
#
"""Testcase for UCDB file conversions."""
+from typing import Tuple
+
from pathlib import Path
from unittest import TestCase
+from pyEDAA.UCIS.Cobertura import Coverage
from pyEDAA.UCIS.UCDB import Parser
@@ -42,7 +45,7 @@
class ExportAndConvert(TestCase):
- def test_UCDB2Cobertura(self):
+ def test_UCDB2Cobertura(self) -> None:
ucdbPath = Path("tests/data/ucdb.xml")
coberturaPath = Path("tests/data/cobertura.xml")
@@ -62,14 +65,14 @@ def test_UCDB2Cobertura(self):
class CoverageValues(TestCase):
- def _parseUCDB(self, ucdbPath, mergeInstances):
+ def _parseUCDB(self, ucdbPath, mergeInstances) -> Tuple[Parser, Coverage]:
parser = Parser(ucdbPath, mergeInstances)
model = parser.getCoberturaModel()
model.getXml()
return parser, model
- def test_multipleInstances(self):
+ def test_multipleInstances(self) -> None:
ucdbPath = Path("tests/data/ucdb000_multiple_instances.xml")
(parser, model) = self._parseUCDB(
@@ -92,7 +95,7 @@ def test_multipleInstances(self):
self.assertEqual(7, model.linesValid)
self.assertEqual(6, model.linesCovered)
- def test_allExcluded(self):
+ def test_allExcluded(self) -> None:
ucdbPath = Path("tests/data/ucdb001_all_excluded.xml")
(parser, model) = self._parseUCDB(
@@ -115,7 +118,7 @@ def test_allExcluded(self):
self.assertEqual(0, model.linesValid)
self.assertEqual(0, model.linesCovered)
- def test_partiallyExcluded(self):
+ def test_partiallyExcluded(self) -> None:
ucdbPath = Path("tests/data/ucdb002_partially_excluded.xml")
(parser, model) = self._parseUCDB(
diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py
index 0f15fdf2..8ca693c8 100644
--- a/tests/unit/__init__.py
+++ b/tests/unit/__init__.py
@@ -11,7 +11,7 @@
# #
# License: #
# ==================================================================================================================== #
-# Copyright 2021-2022 Electronic Design Automation Abstraction (EDA²) #
+# Copyright 2021-2026 Electronic Design Automation Abstraction (EDA²) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); #
# you may not use this file except in compliance with the License. #
diff --git a/tests/unit/requirements.txt b/tests/unit/requirements.txt
new file mode 100644
index 00000000..a2ffbaa9
--- /dev/null
+++ b/tests/unit/requirements.txt
@@ -0,0 +1,8 @@
+-r ../../requirements.txt
+
+# Coverage collection
+Coverage ~= 7.13
+
+# Test Runner
+pytest ~= 9.0
+pytest-cov ~= 7.0