diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..2b8ffcc3 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 9d33e054244839e4106e3c3e8228db59 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/CodeCov/index.html b/CodeCov/index.html new file mode 100644 index 00000000..c06b3d22 --- /dev/null +++ b/CodeCov/index.html @@ -0,0 +1,306 @@ + + + + + + + Code Coverage — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Code Coverage

+

Code Coverage checks if a source code was used during execution. Usually, testcases are run by a testcase +execution framework like pytest, which also offers to instrument the code for +code coverage collection using the pytest-cov plugin. For Python, coverage collection is usually based on +Coverage.py, which supports statement and branch coverage collection.

+
+

Quick Configuration

+

See the overview page on how to setup and enable the Sphinx extension in general.

+
+

Note

+

This is a quick and minimal configuration. See below detailed explanations.

+
+
    +
  1. Configure one or more coverage analysis reports in conf.py by adding a new ‘section’ defining some +configuration variables. Each analysis report is identified by an ID, which is later referred to by the report +directive. Here, the ID is called src (dictionary key). Each analysis report needs 4 configuration entries:

    +
    +
    name

    Name of the Python package[#PkgNameVsPkgDir]_.

    +
    +
    json_report

    The code coverage report as JSON file as generated by Coverage.py.

    +
    +
    fail_below

    An integer value in range 0..100, for when a code coverage is considered FAILED.

    +
    +
    levels

    A dictionary of coverage limits, their description and CSS style classes.

    +
    +
    +
    # ==============================================================================
    +# Sphinx-reports - CodeCov
    +# ==============================================================================
    +report_codecov_packages = {
    +   "src": {
    +      "name":        "myPackage",
    +      "json_report": "../report/coverage/coverage.json",
    +      "fail_below":  80,
    +      "levels": {
    +         30:      {"class": "report-cov-below30",  "desc": "almost unused"},
    +         50:      {"class": "report-cov-below50",  "desc": "poorly used"},
    +         80:      {"class": "report-cov-below80",  "desc": "medium used"},
    +         90:      {"class": "report-cov-below90",  "desc": "well well"},
    +         100:     {"class": "report-cov-below100", "desc": "excellent used"},
    +         "error": {"class": "report-cov-error",    "desc": "internal error"},
    +      },
    +   }
    +}
    +
    +
    +
  2. +
  3. Add the code-coverage directive into your Restructured Text (ReST) document.

    +
    .. report:code-coverage::
    +   :packageid: src
    +
    +
    +
  4. +
+
+
+

Example Document

+

The following coverage/index document is an example on how this documentation uses the code-coverage +directive. The first file consists of three parts: At first, a headline; at second second a short introduction paragraph +and at third, the report generating directive. The second file shows how to integrate that document into the navigation +bar.

+
+

coverage/index.rst

+
Code Coverage Report
+####################
+
+Code coverage generated by `Coverage.py <https://github.com/nedbat/coveragepy>`__.
+
+.. report:code-coverage::
+   :packageid: src
+
+
+
+
+

index.rst

+
.. toctree::
+   :caption: References and Reports
+   :hidden:
+
+   sphinx_reports/sphinx_reports
+   unittests/index
+   coverage/index
+   Doc. Coverage Report <DocCoverage>
+   Static Type Check Report ➚ <typing/index>
+
+.. toctree::
+   :caption: Appendix
+   :hidden:
+
+
+
+
+
+

Directives

+
+
+.. code-coverage::
+

Add a table summarizing the code coverage per Python source code file (packages and/or modules).

+
+
+:packageid:
+

An identifier referencing a dictionary entry in the configuration variable report_codecov_packages defined in +conf.py.

+
+ +
+
+:legend:
+

Describes if and where to add a legend. Possible values: no_legend, top, bottom, both.

+
+ +
+ +
+
+

Roles

+

There are no roles defined.

+
+

Footnotes

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Dependency.html b/Dependency.html new file mode 100644 index 00000000..011229bd --- /dev/null +++ b/Dependency.html @@ -0,0 +1,484 @@ + + + + + + + Dependencies — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Dependencies

+ + + + + + + + + + + +

Libraries.io

Vulnerabilities Summary

Libraries.io status for latest release

Snyk Vulnerabilities for GitHub Repo

+
+

sphinx-reports Package (Mandatory)

+

Manually Installing Package Requirements

+

Use the requirements.txt file to install all dependencies via pip3 or install the package directly from +PyPI (see Installation/Updates).

+
+ +
+
pip3 install -U -r requirements.txt
+
+
+
+ +
+
pip install -U -r requirements.txt
+
+
+
+
+

Dependency List

+

When installed as pyTooling:

+ + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

pyTooling

≥5.0.0

Apache License, 2.0

None

+
+

Todo

+

document the dependency to

+
    +
  • Sphinx

  • +
  • docstr_coverage

  • +
  • interrogate

  • +
+
+
+
+

Unit Testing (Optional)

+
+

Unit Testing / Coverage / Type Checking (Optional)

+

Additional Python packages needed for testing, code coverage collection and static type checking. These packages are +only needed for developers or on a CI server, thus sub-dependencies are not evaluated further.

+

Manually Installing Test Requirements

+

Use the tests/requirements.txt file to install all dependencies via pip3. The file will recursively install +the mandatory dependencies too.

+
+ +
+
pip install -U -r tests/requirements.txt
+
+
+
+ +
+
pip3 install -U -r tests\requirements.txt
+
+
+
+
+

Dependency List - Unit Testing

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

pytest

≥7.4.0

MIT

Not yet evaluated.

pytest-cov

≥4.1.0

MIT

Not yet evaluated.

Coverage

≥7.4

Apache License, 2.0

Not yet evaluated.

mypy

≥1.8.0

MIT

Not yet evaluated.

typing-extensions

≥4.9.0

PSF-2.0

Not yet evaluated.

lxml

≥5.0

BSD 3-Clause

Not yet evaluated.

+
+
+
+

Sphinx Documentation (Optional)

+

Additional Python packages needed for documentation generation. These packages are only needed for developers or on a +CI server, thus sub-dependencies are not evaluated further.

+

Manually Installing Documentation Requirements

+

Use the doc/requirements.txt file to install all dependencies via pip3. The file will recursively install +the mandatory dependencies too.

+
+ +
+
pip install -U -r doc/requirements.txt
+
+
+
+ +
+
pip3 install -U -r doc\requirements.txt
+
+
+
+
+

Dependency List

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

pyTooling

≥5.0.0

Apache License, 2.0

None

Sphinx

≥5.3.0

BSD 3-Clause

Not yet evaluated.

sphinxcontrib-mermaid

≥0.9.2

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_design

≥0.5.0

MIT

Not yet evaluated.

sphinx-copybutton

≥0.5.2

MIT | Not yet evaluated.

sphinx_autodoc_typehints

≥1.25.2

MIT

Not yet evaluated.

+
+

Todo

+

document the usage of

+
    +
  • autoapi

  • +
  • sphinxcontrib-mermaid

  • +
  • theme v2?

  • +
  • sphinx-design

  • +
+
+
+
+

Packaging (Optional)

+

Additional Python packages needed for installation package generation. These packages are only needed for developers or +on a CI server, thus sub-dependencies are not evaluated further.

+

Manually Installing Packaging Requirements

+

Use the build/requirements.txt file to install all dependencies via pip3. The file will recursively +install the mandatory dependencies too.

+
+ +
+
pip install -U -r build/requirements.txt
+
+
+
+ +
+
pip3 install -U -r build\requirements.txt
+
+
+
+
+

Dependency List

+ + + + + + + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

pyTooling

≥5.0.0

Apache License, 2.0

None

wheel

≥0.40.0

MIT

Not yet evaluated.

+
+
+

Publishing (CI-Server only)

+

Additional Python packages needed for publishing the generated installation package to e.g, PyPI or any equivalent +services. These packages are only needed for maintainers or on a CI server, thus sub-dependencies are not evaluated +further.

+

Manually Installing Publishing Requirements

+

Use the dist/requirements.txt file to install all dependencies via pip3. The file will recursively +install the mandatory dependencies too.

+
+ +
+
pip install -U -r dist/requirements.txt
+
+
+
+ +
+
pip3 install -U -r dist\requirements.txt
+
+
+
+
+

Dependency List

+ + + + + + + + + + + + + + + + + + + + +

Package

Version

License

Dependencies

wheel

≥0.40.0

MIT

Not yet evaluated.

Twine

≥4.0.2

Apache License, 2.0

Not yet evaluated.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Doc-License.html b/Doc-License.html new file mode 100644 index 00000000..2bf8862d --- /dev/null +++ b/Doc-License.html @@ -0,0 +1,510 @@ + + + + + + + Creative Commons Attribution 4.0 International — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + +
+

Attention

+

This CC BY 4.0 license applies only to the documentation of this project.

+
+
+

Creative Commons Attribution 4.0 International

+

Creative Commons Corporation (“Creative Commons”) is not a law firm and does not +provide legal services or legal advice. Distribution of Creative Commons public +licenses does not create a lawyer-client or other relationship. Creative Commons +makes its licenses and related information available on an “as-is” basis. +Creative Commons gives no warranties regarding its licenses, any material +licensed under their terms and conditions, or any related information. Creative +Commons disclaims all liability for damages resulting from their use to the +fullest extent possible.

+ +

Creative Commons Attribution 4.0 International Public License

+

By exercising the Licensed Rights (defined below), You accept and agree to be +bound by the terms and conditions of this Creative Commons Attribution 4.0 +International Public License (“Public License”). To the extent this Public +License may be interpreted as a contract, You are granted the Licensed Rights +in consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the Licensor +receives from making the Licensed Material available under these terms and +conditions.

+
+

Section 1 – Definitions.

+
    +
  1. Adapted Material means material subject to Copyright and Similar +Rights that is derived from or based upon the Licensed Material and in +which the Licensed Material is translated, altered, arranged, transformed, or +otherwise modified in a manner requiring permission under the Copyright and +Similar Rights held by the Licensor. For purposes of this Public License, +where the Licensed Material is a musical work, performance, or sound +recording, Adapted Material is always produced where the Licensed Material +is synched in timed relation with a moving image.

  2. +
  3. Adapter’s License means the license You apply to Your Copyright and +Similar Rights in Your contributions to Adapted Material in accordance with +the terms and conditions of this Public License.

  4. +
  5. Copyright and Similar Rights means copyright and/or similar rights +closely related to copyright including, without limitation, performance, +broadcast, sound recording, and Sui Generis Database Rights, without regard +to how the rights are labeled or categorized. For purposes of this Public +License, the rights specified in Section 2(b)(1)-(2) are not Copyright and +Similar Rights.

  6. +
  7. Effective Technological Measures means those measures that, in the +absence of proper authority, may not be circumvented under laws fulfilling +obligations under Article 11 of the WIPO Copyright Treaty adopted on +December 20, 1996, and/or similar international agreements.

  8. +
  9. Exceptions and Limitations means fair use, fair dealing, and/or any +other exception or limitation to Copyright and Similar Rights that applies to +Your use of the Licensed Material.

  10. +
  11. Licensed Material means the artistic or literary work, database, or +other material to which the Licensor applied this Public License.

  12. +
  13. Licensed Rights means the rights granted to You subject to the terms +and conditions of this Public License, which are limited to all Copyright and +Similar Rights that apply to Your use of the Licensed Material and that the +Licensor has authority to license.

  14. +
  15. Licensor means the individual(s) or entity(ies) granting rights under +this Public License.

  16. +
  17. Share means to provide material to the public by any means or process +that requires permission under the Licensed Rights, such as reproduction, +public display, public performance, distribution, dissemination, +communication, or importation, and to make material available to the public +including in ways that members of the public may access the material from a +place and at a time individually chosen by them.

  18. +
  19. Sui Generis Database Rights means rights other than copyright +resulting from Directive 96/9/EC of the European Parliament and of the +Council of 11 March 1996 on the legal protection of databases, as amended +and/or succeeded, as well as other essentially equivalent rights anywhere +in the world.

  20. +
  21. You means the individual or entity exercising the Licensed Rights +under this Public License. Your has a corresponding meaning.

  22. +
+
+
+

Section 2 – Scope.

+
    +
  1. License grant.

    +
      +
    1. Subject to the terms and conditions of this Public License, the Licensor +hereby grants You a worldwide, royalty-free, non-sublicensable, +non-exclusive, irrevocable license to exercise the Licensed Rights in the +Licensed Material to:

      +
      +
        +
      1. reproduce and Share the Licensed Material, in whole or in part; and

      2. +
      3. produce, reproduce, and Share Adapted Material.

      4. +
      +
      +
    2. +
    3. Exceptions and Limitations. For the avoidance of doubt, where +Exceptions and Limitations apply to Your use, this Public License does not +apply, and You do not need to comply with its terms and conditions.

    4. +
    5. Term. The term of this Public License is specified in Section 6(a).

    6. +
    7. Media and formats; technical modifications allowed. The Licensor +authorizes You to exercise the Licensed Rights in all media and formats +whether now known or hereafter created, and to make technical +modifications necessary to do so. The Licensor waives and/or agrees not to +assert any right or authority to forbid You from making technical +modifications necessary to exercise the Licensed Rights, including +technical modifications necessary to circumvent Effective Technological +Measures. For purposes of this Public License, simply making modifications +authorized by this Section 2(a)(4) never produces Adapted Material.

    8. +
    9. Downstream recipients.

      +
      +
        +
      1. Offer from the Licensor – Licensed Material. Every recipient of +the Licensed Material automatically receives an offer from the +Licensor to exercise the Licensed Rights under the terms and +conditions of this Public License.

      2. +
      3. No downstream restrictions. You may not offer or impose any +additional or different terms or conditions on, or apply any Effective +Technological Measures to, the Licensed Material if doing so restricts +exercise of the Licensed Rights by any recipient of the Licensed +Material.

      4. +
      +
      +
    10. +
    11. No endorsement. Nothing in this Public License constitutes or may +be construed as permission to assert or imply that You are, or that Your +use of the Licensed Material is, connected with, or sponsored, endorsed, +or granted official status by, the Licensor or others designated to +receive attribution as provided in Section 3(a)(1)(A)(i).

    12. +
    +
  2. +
  3. Other rights.

    +
      +
    1. Moral rights, such as the right of integrity, are not licensed under this +Public License, nor are publicity, privacy, and/or other similar +personality rights; however, to the extent possible, the Licensor waives +and/or agrees not to assert any such rights held by the Licensor to the +limited extent necessary to allow You to exercise the Licensed Rights, but +not otherwise.

    2. +
    3. Patent and trademark rights are not licensed under this Public License.

    4. +
    5. To the extent possible, the Licensor waives any right to collect royalties +from You for the exercise of the Licensed Rights, whether directly or +through a collecting society under any voluntary or waivable statutory or +compulsory licensing scheme. In all other cases the Licensor expressly +reserves any right to collect such royalties.

    6. +
    +
  4. +
+
+
+

Section 3 – License Conditions.

+

Your exercise of the Licensed Rights is expressly made subject to the following conditions.

+
    +
  1. Attribution.

    +
      +
    1. If You Share the Licensed Material (including in modified form), You must:

      +
      +
        +
      1. retain the following if it is supplied by the Licensor with the +Licensed Material:

      2. +
      +
      +
        +
      1. identification of the creator(s) of the Licensed Material and any +others designated to receive attribution, in any reasonable manner +requested by the Licensor (including by pseudonym if designated);

      2. +
      3. a copyright notice;

      4. +
      5. a notice that refers to this Public License;

      6. +
      7. a notice that refers to the disclaimer of warranties;

      8. +
      9. a URI or hyperlink to the Licensed Material to the extent reasonably +practicable;

      10. +
      +
      +
        +
      1. indicate if You modified the Licensed Material and retain an +indication of any previous modifications; and

      2. +
      3. indicate the Licensed Material is licensed under this Public License, +and include the text of, or the URI or hyperlink to, this Public +License.

      4. +
      +
      +
    2. +
    3. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner +based on the medium, means, and context in which You Share the Licensed +Material. For example, it may be reasonable to satisfy the conditions by +providing a URI or hyperlink to a resource that includes the required +information.

    4. +
    5. If requested by the Licensor, You must remove any of the information +required by Section 3(a)(1)(A) to the extent reasonably practicable.

    6. +
    7. If You Share Adapted Material You produce, the Adapter’s License You apply +must not prevent recipients of the Adapted Material from complying with +this Public License.

    8. +
    +
  2. +
+
+
+

Section 4 – Sui Generis Database Rights.

+

Where the Licensed Rights include Sui Generis Database Rights that apply to Your +use of the Licensed Material:

+
    +
  1. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, +reuse, reproduce, and Share all or a substantial portion of the contents of +the database;

  2. +
  3. if You include all or a substantial portion of the database contents in a +database in which You have Sui Generis Database Rights, then the database +in which You have Sui Generis Database Rights (but not its individual +contents) is Adapted Material; and

  4. +
  5. You must comply with the conditions in Section 3(a) if You Share all or a +substantial portion of the contents of the database.

  6. +
+

For the avoidance of doubt, this Section 4 supplements and does not replace +Your obligations under this Public License where the Licensed Rights include +other Copyright and Similar Rights.

+
+
+

Section 5 – Disclaimer of Warranties and Limitation of Liability.

+
    +
  1. Unless otherwise separately undertaken by the Licensor, to the extent +possible, the Licensor offers the Licensed Material as-is and as-available, +and makes no representations or warranties of any kind concerning the +Licensed Material, whether express, implied, statutory, or other. This +includes, without limitation, warranties of title, merchantability, +fitness for a particular purpose, non-infringement, absence of latent or +other defects, accuracy, or the presence or absence of errors, whether or +not known or discoverable. Where disclaimers of warranties are not allowed +in full or in part, this disclaimer may not apply to You.

  2. +
  3. To the extent possible, in no event will the Licensor be liable to You +on any legal theory (including, without limitation, negligence) or +otherwise for any direct, special, indirect, incidental, consequential, +punitive, exemplary, or other losses, costs, expenses, or damages arising +out of this Public License or use of the Licensed Material, even if the +Licensor has been advised of the possibility of such losses, costs, expenses, +or damages. Where a limitation of liability is not allowed in full or in +part, this limitation may not apply to You.

  4. +
  5. The disclaimer of warranties and limitation of liability provided above +shall be interpreted in a manner that, to the extent possible, most +closely approximates an absolute disclaimer and waiver of all liability.

  6. +
+
+
+

Section 6 – Term and Termination.

+
    +
  1. This Public License applies for the term of the Copyright and Similar Rights +licensed here. However, if You fail to comply with this Public License, then +Your rights under this Public License terminate automatically.

  2. +
  3. Where Your right to use the Licensed Material has terminated under +Section 6(a), it reinstates:

    +
      +
    1. automatically as of the date the violation is cured, provided it is cured +within 30 days of Your discovery of the violation; or

    2. +
    3. upon express reinstatement by the Licensor.

    4. +
    +

    For the avoidance of doubt, this Section 6(b) does not affect any right the +Licensor may have to seek remedies for Your violations of this Public License.

    +
  4. +
  5. For the avoidance of doubt, the Licensor may also offer the Licensed Material +under separate terms or conditions or stop distributing the Licensed Material +at any time; however, doing so will not terminate this Public License.

  6. +
  7. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.

  8. +
+
+
+

Section 7 – Other Terms and Conditions.

+
    +
  1. The Licensor shall not be bound by any additional or different terms or +conditions communicated by You unless expressly agreed.

  2. +
  3. Any arrangements, understandings, or agreements regarding the Licensed +Material not stated herein are separate from and independent of the terms +and conditions of this Public License.

  4. +
+
+
+

Section 8 – Interpretation.

+
    +
  1. For the avoidance of doubt, this Public License does not, and shall not be +interpreted to, reduce, limit, restrict, or impose conditions on any use of +the Licensed Material that could lawfully be made without permission under +this Public License.

  2. +
  3. To the extent possible, if any provision of this Public License is deemed +unenforceable, it shall be automatically reformed to the minimum extent +necessary to make it enforceable. If the provision cannot be reformed, it +shall be severed from this Public License without affecting the +enforceability of the remaining terms and conditions.

  4. +
  5. No term or condition of this Public License will be waived and no failure to +comply consented to unless expressly agreed to by the Licensor.

  6. +
  7. Nothing in this Public License constitutes or may be interpreted as a +limitation upon, or waiver of, any privileges and immunities that apply to +the Licensor or You, including from the legal processes of any jurisdiction +or authority.

  8. +
+
+

Creative Commons is not a party to its public licenses. Notwithstanding, +Creative Commons may elect to apply one of its public licenses to material it +publishes and in those instances will be considered the “Licensor.” Except for +the limited purpose of indicating that material is shared under a Creative +Commons public license or as otherwise permitted by the Creative Commons +policies published at creativecommons.org/policies, +Creative Commons does not authorize the use of the trademark “Creative Commons” +or any other trademark or logo of Creative Commons without its prior written +consent including, without limitation, in connection with any unauthorized +modifications to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For the +avoidance of doubt, this paragraph does not form part of the public licenses.

+

Creative Commons may be contacted at creativecommons.org

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/DocCov/index.html b/DocCov/index.html new file mode 100644 index 00000000..57e2ce10 --- /dev/null +++ b/DocCov/index.html @@ -0,0 +1,312 @@ + + + + + + + Documentation Coverage — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Documentation Coverage

+

Documentation coverage counts how many publicly accessible members (packages, modules, classes, methods, +functions, variables, …) are documented using a Python doc-string. Based on the count of possibly documented +public members and the actual number of non-empty doc-strings, a percentage of documentation coverage can be computed.

+

Documentation coverage is a measure of code quality, which expresses how well documented (completeness or documentation, +but not necessarily quality/helpfulness of documentation) source code is. Well documented code helps to use and maintain +the existing code base. It also allows for automated documentation generation.

+

Depending on quality standards, a coverage goal (or limit) like 90% might be defined, which considers an overall +documentation coverage less then 90% as FAILED. Such a limit might be enforced by maintainers or merge rules (via CI +jobs). This ensures new code introduced by merge requests (pull requests) cannot decrease the once achieved overall +project’s code quality.

+
+

Quick Configuration

+

See the overview page on how to setup and enable the Sphinx extension in general.

+
+

Note

+

This is a quick and minimal configuration. See below detailed explanations.

+
+
    +
  1. Configure one or more Python packages for documentation coverage analysis in conf.py by adding a new +‘section’ defining some configuration variables. Each package is identified by an ID, which is later referred to by +the report directive. Here, the ID is called src (dictionary key). Each package needs 4 configuration entries:

    +
    +
    name

    Name of the Python package[#PkgNameVsPkgDir]_.

    +
    +
    directory

    The directory of the package to analyze.

    +
    +
    fail_below

    An integer value in range 0..100, for when a documentation coverage is considered FAILED.

    +
    +
    levels

    A dictionary of coverage limits, their description and CSS style classes.

    +
    +
    +
    # ==============================================================================
    +# Sphinx-reports - DocCov
    +# ==============================================================================
    +report_doccov_packages = {
    +   "src": {
    +      "name":       "myPackage",
    +      "directory":  "../myPackage",
    +      "fail_below": 80,
    +      "levels": {
    +         30:      {"class": "report-cov-below30",  "desc": "almost undocumented"},
    +         50:      {"class": "report-cov-below50",  "desc": "poorly documented"},
    +         80:      {"class": "report-cov-below80",  "desc": "roughly documented"},
    +         90:      {"class": "report-cov-below90",  "desc": "well documented"},
    +         100:     {"class": "report-cov-below100", "desc": "excellent documented"},
    +         "error": {"class": "report-cov-error",    "desc": "internal error"},
    +      },
    +   }
    +}
    +
    +
    +
  2. +
  3. Add the doc-coverage directive into your Restructured Text (ReST) document.

    +
    .. report:doc-coverage::
    +   :packageid: src
    +
    +
    +
  4. +
+
+
+

Example Document

+

The following DocCoverage document is an example on how this documentation uses the doc-coverage +directive. The first file consists of three parts: At first, a headline; at second second a short introduction paragraph +and at third, the report generating directive. The second file shows how to integrate that document into the navigation +bar.

+
+

DocCoverage.rst

+
Documentation Coverage Report
+#############################
+
+Documentation coverage generated by `docstr-coverage <https://github.com/HunterMcGushion/docstr_coverage>`__.
+
+.. report:doc-coverage::
+   :packageid: src
+
+
+
+
+

index.rst

+
.. toctree::
+   :caption: References and Reports
+   :hidden:
+
+   sphinx_reports/sphinx_reports
+   unittests/index
+   coverage/index
+   Doc. Coverage Report <DocCoverage>
+   Static Type Check Report ➚ <typing/index>
+
+.. toctree::
+   :caption: Appendix
+   :hidden:
+
+
+
+
+
+

Directives

+
+
+.. doc-coverage::
+

Add a table summarizing the documentation coverage per Python source code file (packages and/or modules).

+
+
+:packageid:
+

An identifier referencing a dictionary entry in the configuration variable report_doccov_packages defined in +conf.py.

+
+ +
+
+:legend:
+

Describes if and where to add a legend. Possible values: no_legend, top, bottom, both.

+
+ +
+ +
+
+

Roles

+

There are no roles defined.

+
+

Footnotes

+ +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/DocCoverage.html b/DocCoverage.html new file mode 100644 index 00000000..b8f19870 --- /dev/null +++ b/DocCoverage.html @@ -0,0 +1,302 @@ + + + + + + + Documentation Coverage — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Documentation Coverage

+

Documentation coverage generated by docstr-coverage.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename

Total

Covered

Missing

Coverage in %

📦sphinx_reports

8

5

3

62.5%

 📦Adapter

1

1

0

100.0%

    Coverage

8

1

7

12.5%

    DocStrCoverage

10

1

9

10.0%

    JUnit

8

1

7

12.5%

 📦DataModel

1

1

0

100.0%

    CodeCoverage

25

1

24

4.0%

    DocumentationCoverage

53

1

52

1.9%

    Unittest

33

1

32

3.0%

 📦static

1

1

0

100.0%

   CodeCoverage

11

2

9

18.2%

   Common

5

1

4

20.0%

   DocCoverage

12

2

10

16.7%

   Sphinx

7

1

6

14.3%

   Unittest

13

2

11

15.4%

Overall (15 files):

59

16

43

27.1%

+

Legend

+ + + + + + + + + + + + + + + + + + + + + + + +

%

Coverage Level

≤30%

almost undocumented

≤50%

poorly documented

≤80%

roughly documented

≤90%

well documented

≤100%

excellent documented

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Examples/FullyDocumented.html b/Examples/FullyDocumented.html new file mode 100644 index 00000000..d5f21fb9 --- /dev/null +++ b/Examples/FullyDocumented.html @@ -0,0 +1,224 @@ + + + + + + + Fully Undocumented — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Fully Undocumented

+

The following report shows a fully documented package.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename

Total

Covered

Missing

Coverage in %

📦MyPackage

6

6

0

100.0%

   MyModule

6

6

0

100.0%

Overall (2 files):

12

12

0

100.0%

+

Legend

+ + + + + + + + + + + + + + + + + + + + + + + +

%

Coverage Level

≤30%

almost undocumented

≤50%

poorly documented

≤80%

roughly documented

≤90%

well documented

≤100%

excellent documented

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Examples/PartiallyDocumented.html b/Examples/PartiallyDocumented.html new file mode 100644 index 00000000..88dd958c --- /dev/null +++ b/Examples/PartiallyDocumented.html @@ -0,0 +1,224 @@ + + + + + + + Partially Documented — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Partially Documented

+

The following report shows a partially documented package.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename

Total

Covered

Missing

Coverage in %

📦MyPackage

6

3

3

50.0%

   MyModule

6

2

4

33.3%

Overall (2 files):

12

5

7

41.7%

+

Legend

+ + + + + + + + + + + + + + + + + + + + + + + +

%

Coverage Level

≤30%

almost undocumented

≤50%

poorly documented

≤80%

roughly documented

≤90%

well documented

≤100%

excellent documented

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Examples/Undocumented.html b/Examples/Undocumented.html new file mode 100644 index 00000000..1cf6c8e5 --- /dev/null +++ b/Examples/Undocumented.html @@ -0,0 +1,224 @@ + + + + + + + Undocumented — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Undocumented

+

The following report shows an undocumented package.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename

Total

Covered

Missing

Coverage in %

📦MyPackage

6

0

6

0.0%

   MyModule

6

0

6

0.0%

Overall (2 files):

12

0

12

0.0%

+

Legend

+ + + + + + + + + + + + + + + + + + + + + + + +

%

Coverage Level

≤30%

almost undocumented

≤50%

poorly documented

≤80%

roughly documented

≤90%

well documented

≤100%

excellent documented

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Glossary.html b/Glossary.html new file mode 100644 index 00000000..29c276e3 --- /dev/null +++ b/Glossary.html @@ -0,0 +1,189 @@ + + + + + + + Glossary — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Glossary

+
+
Branch Coverage

tbd

+
+
Code Coverage

tbd

+
+
doc-string

tbd

+
def myFunction(a: int, b: int) -> str:
+  """
+  Converts 2 integers to a tuple represented as a string.
+
+  :param a: First tuple element.
+  :param b: Second tuple element.
+  :returns: The tuple ``"(a, b)"`` as a string.
+  """
+  return f"({a}, {b})"
+
+
+
+
Documentation Coverage

tbd

+
+
Statement Coverage

tbd

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Installation.html b/Installation.html new file mode 100644 index 00000000..44fc5c6f --- /dev/null +++ b/Installation.html @@ -0,0 +1,374 @@ + + + + + + + Installation/Updates — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Installation/Updates

+
+

Using PIP to Install from PyPI

+

The following instruction are using PIP (Package Installer for Python) as a package manager and PyPI (Python Package +Index) as a source of Python packages.

+
+

Installing a Wheel Package from PyPI using PIP

+

Users of pyTooling can select if the want to install a basic variant of pyTooling. See Dependencies for more +details.

+
+ +
+
# Basic sphinx-reports package
+pip3 install sphinx_reports
+
+
+
+ +
+
# Basic sphinx-reports package
+pip install sphinx_reports
+
+
+
+
+

Developers can install further dependencies for documentation generation (doc) or running unit tests (test) or +just all (all) dependencies.

+
+ +
+
+ +
+
+
# Install with dependencies to generate documentation
+pip3 install sphinx_reports[doc]
+
+
+
+
+ +
+
+
# Install with dependencies to run unit tests
+pip3 install sphinx_reports[test]
+
+
+
+
+ +
+
+
# Install with all developer dependencies
+pip install sphinx_reports[all]
+
+
+
+
+
+
+ +
+
+ +
+
+
# Install with dependencies to generate documentation
+pip install sphinx_reports[doc]
+
+
+
+
+ +
+
+
# Install with dependencies to run unit tests
+pip install sphinx_reports[test]
+
+
+
+
+ +
+
+
# Install with all developer dependencies
+pip install sphinx_reports[all]
+
+
+
+
+
+
+
+
+
+

Updating from PyPI using PIP

+
+ +
+
pip install -U sphinx_reports
+
+
+
+ +
+
pip3 install -U sphinx_reports
+
+
+
+
+
+
+

Uninstallation using PIP

+
+ +
+
pip uninstall sphinx_reports
+
+
+
+ +
+
pip3 uninstall sphinx_reports
+
+
+
+
+
+
+
+

Using setup.py (legacy)

+

See sections above on how to use PIP.

+
+

Installation using setup.py

+
setup.py install
+
+
+
+
+
+

Local Packaging and Installation via PIP

+

For development and bug fixing it might be handy to create a local wheel package and also install it locally on the +development machine. The following instructions will create a local wheel package (*.whl) and then use PIP to +install it. As a user might have a sphinx-reports installation from PyPI, it’s recommended to uninstall any previous +sphinx-reports packages. (This step is also needed if installing an updated local wheel file with same version number. PIP +will not detect a new version and thus not overwrite/reinstall the updated package contents.)

+

Ensure packaging requirements are installed.

+
+ +
+
cd <sphinx-reports>
+
+# Package the code in a wheel (*.whl)
+python -m build --wheel
+
+# Uninstall the old package
+python -m pip uninstall -y sphinx_reports
+
+# Install from wheel
+python -m pip install ./dist/sphinx_reports-1.0.0-py3-none-any.whl
+
+
+
+ +
+
cd <sphinx-reports>
+
+# Package the code in a wheel (*.whl)
+py -m build --wheel
+
+# Uninstall the old package
+py -m pip uninstall -y sphinx_reports
+
+# Install from wheel
+py -m pip install .\dist\sphinx_reports-1.0.0-py3-none-any.whl
+
+
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/License.html b/License.html new file mode 100644 index 00000000..8c2c26a9 --- /dev/null +++ b/License.html @@ -0,0 +1,297 @@ + + + + + + + Apache License 2.0 — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Note

+

This is a local copy of the Apache License Version 2.0.

+
+
+

Apache License 2.0

+

Version 2.0, January 2004

+

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+
+

1. Definitions.

+

“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

+

“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

+

“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that +entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether +by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

+

“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

+

“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and +configuration files.

+

“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object +code, generated documentation, and conversions to other media types.

+

“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is +included in or attached to the work (an example is provided in the Appendix below).

+

“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

+

“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative +Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to +submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication +sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue +tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is +conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

+

“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work.

+
+ +
+

3. Grant of Patent License.

+

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such +license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of +their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim +or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then +any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

+
+
+

4. Redistribution.

+

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions:

+
    +
  • You must give any other recipients of the Work or Derivative Works a copy of this License; and

  • +
  • You must cause any modified files to carry prominent notices stating that You changed the files; and

  • +
  • You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source +form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

  • +
  • If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the +Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE +file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, +alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

  • +
+

You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise +complies with the conditions stated in this License.

+
+
+

5. Submission of Contributions.

+

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any +separate license agreement you may have executed with Licensor regarding such Contributions.

+
+
+

6. Trademarks.

+

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable +and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

+
+
+

7. Disclaimer of Warranty.

+

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, +MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and +assume any risks associated with Your exercise of permissions under this License.

+
+
+

8. Limitation of Liability.

+

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or +consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages +for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been +advised of the possibility of such damages.

+
+
+

9. Accepting Warranty or Additional Liability.

+

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other +liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole +responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

+
+

Appendix: How to apply the Apache License to your work

+

To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets “[]” replaced with your own identifying +information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or +class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.

+
Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Overview.html b/Overview.html new file mode 100644 index 00000000..f58a8a58 --- /dev/null +++ b/Overview.html @@ -0,0 +1,227 @@ + + + + + + + Overview — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Overview

+
+

General Extension Setup

+

To use the sphinx-reports extension in your Sphinx documentation project, the sphinx_reports package must be +downloaded and installed from PyPI in your environment. The installation page also shows, +how to update the package from PyPI using pip.

+

At next, it’s recommended to add sphinx_reports to your documentation’s doc/requirements.txt. As +modification to the package might bring braking changes, it’s recommended to specify a package version (range/limit).

+

See the following doc/requirements.txt file as an example with commonly used extensions:

+
-r ../requirements.txt
+
+# Enforce latest version on ReadTheDocs
+sphinx ~= 7
+docutils ~= 0.18
+
+# ReadTheDocs Theme
+sphinx_rtd_theme ~= 2.0
+
+# Sphinx Extenstions
+sphinxcontrib-mermaid ~= 0.9.2
+autoapi ~= 2.0.1
+sphinx_design ~= 0.5.0
+sphinx-copybutton ~= 0.5.2
+sphinx_autodoc_typehints ~= 1.25.2
+sphinx_reports ~= 1.0
+
+
+

Finally, the extension needs to be enabled in Sphinx’s conf.py, so the extension is loaded by Sphinx.

+

The following code snippets shows a list of commonly enabled extensions, including sphinx_report:

+
+
# ==============================================================================
+# Extensions
+# ==============================================================================
+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",
+# SphinxContrib extensions
+  "sphinxcontrib.mermaid",
+# Other extensions
+  "autoapi.sphinx",
+  "sphinx_design",
+  "sphinx_copybutton",
+  "sphinx_autodoc_typehints",
+  "sphinx_reports",
+# User defined extensions
+  # ...
+]
+
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/TODO.html b/TODO.html new file mode 100644 index 00000000..8c2bcc88 --- /dev/null +++ b/TODO.html @@ -0,0 +1,197 @@ + + + + + + + TODOs — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

TODOs

+
+

Todo

+

document the dependency to

+
    +
  • Sphinx

  • +
  • docstr_coverage

  • +
  • interrogate

  • +
+
+

original entry

+
+

Todo

+

document the usage of

+
    +
  • autoapi

  • +
  • sphinxcontrib-mermaid

  • +
  • theme v2?

  • +
  • sphinx-design

  • +
+
+

original entry

+
+

Todo

+

index: Screen shot here and link to this unitest summary.

+
+

original entry

+
+

Todo

+

index: Screen shot here and link to this code coverage report.

+
+

original entry

+
+

Todo

+

index: Screen shot here and link to this documentations report.

+
+

original entry

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/Unittest/index.html b/Unittest/index.html new file mode 100644 index 00000000..24100705 --- /dev/null +++ b/Unittest/index.html @@ -0,0 +1,278 @@ + + + + + + + Unit Test Summary — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Unit Test Summary

+

🚧 This is a work-in-progress feature. 🚧

+

execution framework like pytest.

+

Supported report generators

+ +
+

Quick Configuration

+

See the overview page on how to setup and enable the Sphinx extension in general.

+
+

Note

+

This is a quick and minimal configuration. See below detailed explanations.

+
+
    +
  1. Configure one or more unitest summary reports in conf.py by adding a new ‘section’ defining some +configuration variables. Each summary report is identified by an ID, which is later referred to by the report +directive. Here, the ID is called src (dictionary key). Each analysis report needs 2 configuration entries:

    +
    +
    name

    Name of the Python package[#PkgNameVsPkgDir]_.

    +
    +
    xml_report

    The code coverage report as JSON file as generated by Coverage.py.

    +
    +
    +
    # ==============================================================================
    +# Sphinx-reports - Unittest
    +# ==============================================================================
    +report_codecov_packages = {
    +   "src": {
    +      "name":       "myPackage",
    +      "xml_report": "../report/unit/unittest.xml",
    +   }
    +}
    +
    +
    +
  2. +
  3. Add the unittest-summary directive into your Restructured Text (ReST) document.

    +
    .. report:unittest-summary::
    +   :reportid: src
    +
    +
    +
  4. +
+
+
+

Example Document

+

The following unittest/index document is an example on how this documentation uses the unittest-summary +directive. The first file consists of three parts: At first, a headline; at second second a short introduction paragraph +and at third, the report generating directive. The second file shows how to integrate that document into the navigation +bar.

+
+

unittest/index.rst

+
Unittest Summary Report
+#######################
+
+Code coverage report generated with `pytest <https://github.com/pytest-dev/pytest>`__.
+
+.. report:unittest-summary::
+   :reportid: src
+
+
+
+
+

index.rst

+
.. toctree::
+   :caption: References and Reports
+   :hidden:
+
+   sphinx_reports/sphinx_reports
+   unittests/index
+   coverage/index
+   Doc. Coverage Report <DocCoverage>
+   Static Type Check Report ➚ <typing/index>
+
+.. toctree::
+   :caption: Appendix
+   :hidden:
+
+
+
+
+
+

Directives

+
+
+.. unittest-summary::
+

Add a table summarizing the unittest results.

+
+
+:reportid:
+

An identifier referencing a dictionary entry in the configuration variable report_unittest_testsuites defined +in conf.py.

+
+ +
+ +
+
+

Roles

+

There are no roles defined.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_images/inheritance-004bb9fac14041b3756a4c9c42e547ed7a6e60e1.svg b/_images/inheritance-004bb9fac14041b3756a4c9c42e547ed7a6e60e1.svg new file mode 100644 index 00000000..ac225a8d --- /dev/null +++ b/_images/inheritance-004bb9fac14041b3756a4c9c42e547ed7a6e60e1.svg @@ -0,0 +1,29 @@ + + +inheritance315bb6953e + + +ClassCoverage + + +ClassCoverage + + + + + +Coverage + + +Coverage + + + + + +Coverage->ClassCoverage + + + + + \ No newline at end of file diff --git a/_images/inheritance-0ad1d6c22e4ee4f1a8dbcf6049e4465cc61cad60.svg b/_images/inheritance-0ad1d6c22e4ee4f1a8dbcf6049e4465cc61cad60.svg new file mode 100644 index 00000000..d4cf40b6 --- /dev/null +++ b/_images/inheritance-0ad1d6c22e4ee4f1a8dbcf6049e4465cc61cad60.svg @@ -0,0 +1,29 @@ + + +inheritance3350518557 + + +AggregatedCoverage + + +AggregatedCoverage + + + + + +Coverage + + +Coverage + + + + + +Coverage->AggregatedCoverage + + + + + \ No newline at end of file diff --git a/_images/inheritance-0b5cc61e7e3dcbdf74e7980b644d46af49a241e0.svg b/_images/inheritance-0b5cc61e7e3dcbdf74e7980b644d46af49a241e0.svg new file mode 100644 index 00000000..dc4dc07e --- /dev/null +++ b/_images/inheritance-0b5cc61e7e3dcbdf74e7980b644d46af49a241e0.svg @@ -0,0 +1,44 @@ + + +inheritance1c172a31ab + + +AggregatedCoverage + + +AggregatedCoverage + + + + + +ModuleCoverage + + +ModuleCoverage + + + + + +AggregatedCoverage->ModuleCoverage + + + + + +Coverage + + +Coverage + + + + + +Coverage->AggregatedCoverage + + + + + \ No newline at end of file diff --git a/_images/inheritance-10a049b04b75d41a93762b32d6ef0eec4d38be2e.svg b/_images/inheritance-10a049b04b75d41a93762b32d6ef0eec4d38be2e.svg new file mode 100644 index 00000000..237797ca --- /dev/null +++ b/_images/inheritance-10a049b04b75d41a93762b32d6ef0eec4d38be2e.svg @@ -0,0 +1,44 @@ + + +inheritanced59e88981e + + +Enum + + +Enum + + + + + +Flag + + +Flag + + + + + +Enum->Flag + + + + + +TestcaseState + + +TestcaseState + + + + + +Flag->TestcaseState + + + + + \ No newline at end of file diff --git a/_images/inheritance-1c88a1615e45ab2fd117a42143345c9d8b16ad42.svg b/_images/inheritance-1c88a1615e45ab2fd117a42143345c9d8b16ad42.svg new file mode 100644 index 00000000..ea7fb3f3 --- /dev/null +++ b/_images/inheritance-1c88a1615e45ab2fd117a42143345c9d8b16ad42.svg @@ -0,0 +1,44 @@ + + +inheritanced81a0faa0b + + +CoverageState + + +CoverageState + + + + + +Flag + + +Flag + + + + + +Flag->CoverageState + + + + + +Enum + + +Enum + + + + + +Enum->Flag + + + + + \ No newline at end of file diff --git a/_images/inheritance-271cf7b82b2f5b673e2bce4fab27a28736b62b88.svg b/_images/inheritance-271cf7b82b2f5b673e2bce4fab27a28736b62b88.svg new file mode 100644 index 00000000..899fb239 --- /dev/null +++ b/_images/inheritance-271cf7b82b2f5b673e2bce4fab27a28736b62b88.svg @@ -0,0 +1,14 @@ + + +inheritance3ac5f154f4 + + +Analyzer + + +Analyzer + + + + + \ No newline at end of file diff --git a/_images/inheritance-276f33f3d22c1660e55d27c62b7e5afd63eb1eb3.svg b/_images/inheritance-276f33f3d22c1660e55d27c62b7e5afd63eb1eb3.svg new file mode 100644 index 00000000..84e1995b --- /dev/null +++ b/_images/inheritance-276f33f3d22c1660e55d27c62b7e5afd63eb1eb3.svg @@ -0,0 +1,14 @@ + + +inheritance3ac5f154f4 + + +Analyzer + + +Analyzer + + + + + \ No newline at end of file diff --git a/_images/inheritance-296114096496a51320d4c76020d2834dd3cd2138.svg b/_images/inheritance-296114096496a51320d4c76020d2834dd3cd2138.svg new file mode 100644 index 00000000..250e5b5f --- /dev/null +++ b/_images/inheritance-296114096496a51320d4c76020d2834dd3cd2138.svg @@ -0,0 +1,14 @@ + + +inheritance3ac5f154f4 + + +Analyzer + + +Analyzer + + + + + \ No newline at end of file diff --git a/_images/inheritance-29666331c47bf3efaba30c258b3d7b8d208b9b5d.svg b/_images/inheritance-29666331c47bf3efaba30c258b3d7b8d208b9b5d.svg new file mode 100644 index 00000000..7cbc9f00 --- /dev/null +++ b/_images/inheritance-29666331c47bf3efaba30c258b3d7b8d208b9b5d.svg @@ -0,0 +1,29 @@ + + +inheritance1963c5de16 + + +Base + + +Base + + + + + +Testcase + + +Testcase + + + + + +Base->Testcase + + + + + \ No newline at end of file diff --git a/_images/inheritance-2dfb0eacd5355c5a3f782b9c25fe2362eeefd735.svg b/_images/inheritance-2dfb0eacd5355c5a3f782b9c25fe2362eeefd735.svg new file mode 100644 index 00000000..967dfb1c --- /dev/null +++ b/_images/inheritance-2dfb0eacd5355c5a3f782b9c25fe2362eeefd735.svg @@ -0,0 +1,59 @@ + + +inheritance9b2d3cecfb + + +CodeCoverageError + + +CodeCoverageError + + + + + +ReportExtensionError + + +ReportExtensionError + + + + + +ReportExtensionError->CodeCoverageError + + + + + +ExtensionError + + +ExtensionError + + + + + +ExtensionError->ReportExtensionError + + + + + +SphinxError + + +SphinxError + + + + + +SphinxError->ExtensionError + + + + + \ No newline at end of file diff --git a/_images/inheritance-41debb8d1ed1326dde6abb6366c77de3f1a1c460.svg b/_images/inheritance-41debb8d1ed1326dde6abb6366c77de3f1a1c460.svg new file mode 100644 index 00000000..8377e7c7 --- /dev/null +++ b/_images/inheritance-41debb8d1ed1326dde6abb6366c77de3f1a1c460.svg @@ -0,0 +1,14 @@ + + +inheritance030f0c49ab + + +Coverage + + +Coverage + + + + + \ No newline at end of file diff --git a/_images/inheritance-4a9dae5c3d3f6c28f0f73f41fed4a65b6112e4a9.svg b/_images/inheritance-4a9dae5c3d3f6c28f0f73f41fed4a65b6112e4a9.svg new file mode 100644 index 00000000..fa0d43e8 --- /dev/null +++ b/_images/inheritance-4a9dae5c3d3f6c28f0f73f41fed4a65b6112e4a9.svg @@ -0,0 +1,44 @@ + + +inheritance2f548e4376 + + +ExtensionError + + +ExtensionError + + + + + +ReportExtensionError + + +ReportExtensionError + + + + + +ExtensionError->ReportExtensionError + + + + + +SphinxError + + +SphinxError + + + + + +SphinxError->ExtensionError + + + + + \ No newline at end of file diff --git a/_images/inheritance-4bf1c5b6da7de63d24c0571f56154611e590cf87.svg b/_images/inheritance-4bf1c5b6da7de63d24c0571f56154611e590cf87.svg new file mode 100644 index 00000000..db3a7ff6 --- /dev/null +++ b/_images/inheritance-4bf1c5b6da7de63d24c0571f56154611e590cf87.svg @@ -0,0 +1,29 @@ + + +inheritance1402373e3c + + +Base + + +Base + + + + + +Test + + +Test + + + + + +Base->Test + + + + + \ No newline at end of file diff --git a/_images/inheritance-654b223654761ecce8ca8d6d5b01659e45eb126a.svg b/_images/inheritance-654b223654761ecce8ca8d6d5b01659e45eb126a.svg new file mode 100644 index 00000000..cbfd52e0 --- /dev/null +++ b/_images/inheritance-654b223654761ecce8ca8d6d5b01659e45eb126a.svg @@ -0,0 +1,44 @@ + + +inheritance42f105934e + + +AggregatedCoverage + + +AggregatedCoverage + + + + + +PackageCoverage + + +PackageCoverage + + + + + +AggregatedCoverage->PackageCoverage + + + + + +Coverage + + +Coverage + + + + + +Coverage->AggregatedCoverage + + + + + \ No newline at end of file diff --git a/_images/inheritance-94e274095a29e9093043b08f7f57e25cdab67892.svg b/_images/inheritance-94e274095a29e9093043b08f7f57e25cdab67892.svg new file mode 100644 index 00000000..e04135f9 --- /dev/null +++ b/_images/inheritance-94e274095a29e9093043b08f7f57e25cdab67892.svg @@ -0,0 +1,59 @@ + + +inheritancea6fd13e7e5 + + +ExtensionError + + +ExtensionError + + + + + +ReportExtensionError + + +ReportExtensionError + + + + + +ExtensionError->ReportExtensionError + + + + + +SphinxError + + +SphinxError + + + + + +SphinxError->ExtensionError + + + + + +UnittestError + + +UnittestError + + + + + +ReportExtensionError->UnittestError + + + + + \ No newline at end of file diff --git a/_images/inheritance-9d338973781bebdea4f333be4cd117a2c23ebaad.svg b/_images/inheritance-9d338973781bebdea4f333be4cd117a2c23ebaad.svg new file mode 100644 index 00000000..3a1409fd --- /dev/null +++ b/_images/inheritance-9d338973781bebdea4f333be4cd117a2c23ebaad.svg @@ -0,0 +1,74 @@ + + +inheritance420ebf692c + + +BaseDirective + + +BaseDirective + + + + + +ObjectDescription + + +ObjectDescription + + + + + +ObjectDescription->BaseDirective + + + + + +Directive + + +Directive + + + + + +SphinxDirective + + +SphinxDirective + + + + + +Directive->SphinxDirective + + + + + +Generic + + +Generic + + + + + +Generic->ObjectDescription + + + + + +SphinxDirective->ObjectDescription + + + + + \ No newline at end of file diff --git a/_images/inheritance-9f9807a5ea127aa35abc49b8d3cbed3f665cc709.svg b/_images/inheritance-9f9807a5ea127aa35abc49b8d3cbed3f665cc709.svg new file mode 100644 index 00000000..158cbba2 --- /dev/null +++ b/_images/inheritance-9f9807a5ea127aa35abc49b8d3cbed3f665cc709.svg @@ -0,0 +1,29 @@ + + +inheritanceedc3255e8f + + +Base + + +Base + + + + + +TestsuiteBase + + +TestsuiteBase + + + + + +Base->TestsuiteBase + + + + + \ No newline at end of file diff --git a/_images/inheritance-a10cdd4a48b3c904478276283ea274ca29a97592.svg b/_images/inheritance-a10cdd4a48b3c904478276283ea274ca29a97592.svg new file mode 100644 index 00000000..aa99efe9 --- /dev/null +++ b/_images/inheritance-a10cdd4a48b3c904478276283ea274ca29a97592.svg @@ -0,0 +1,89 @@ + + +inheritance8f7335ae33 + + +BaseDirective + + +BaseDirective + + + + + +DocCoverage + + +DocCoverage + + + + + +BaseDirective->DocCoverage + + + + + +ObjectDescription + + +ObjectDescription + + + + + +ObjectDescription->BaseDirective + + + + + +Directive + + +Directive + + + + + +SphinxDirective + + +SphinxDirective + + + + + +Directive->SphinxDirective + + + + + +Generic + + +Generic + + + + + +Generic->ObjectDescription + + + + + +SphinxDirective->ObjectDescription + + + + + \ No newline at end of file diff --git a/_images/inheritance-a4b94e6092769a7cdec9e095487b83115d3230c5.svg b/_images/inheritance-a4b94e6092769a7cdec9e095487b83115d3230c5.svg new file mode 100644 index 00000000..8a443402 --- /dev/null +++ b/_images/inheritance-a4b94e6092769a7cdec9e095487b83115d3230c5.svg @@ -0,0 +1,89 @@ + + +inheritanceaeeba635c7 + + +BaseDirective + + +BaseDirective + + + + + +CodeCoverage + + +CodeCoverage + + + + + +BaseDirective->CodeCoverage + + + + + +ObjectDescription + + +ObjectDescription + + + + + +ObjectDescription->BaseDirective + + + + + +Directive + + +Directive + + + + + +SphinxDirective + + +SphinxDirective + + + + + +Directive->SphinxDirective + + + + + +Generic + + +Generic + + + + + +Generic->ObjectDescription + + + + + +SphinxDirective->ObjectDescription + + + + + \ No newline at end of file diff --git a/_images/inheritance-a6b96c732fd7e4f2c96521ed2db8d2366e692fbe.svg b/_images/inheritance-a6b96c732fd7e4f2c96521ed2db8d2366e692fbe.svg new file mode 100644 index 00000000..14318d2d --- /dev/null +++ b/_images/inheritance-a6b96c732fd7e4f2c96521ed2db8d2366e692fbe.svg @@ -0,0 +1,29 @@ + + +inheritance472103c3ad + + +Domain + + +Domain + + + + + +ReportDomain + + +ReportDomain + + + + + +Domain->ReportDomain + + + + + \ No newline at end of file diff --git a/_images/inheritance-b2a51b83075109799f7b4ff23ce41e18fa516a7d.svg b/_images/inheritance-b2a51b83075109799f7b4ff23ce41e18fa516a7d.svg new file mode 100644 index 00000000..46fa1b08 --- /dev/null +++ b/_images/inheritance-b2a51b83075109799f7b4ff23ce41e18fa516a7d.svg @@ -0,0 +1,44 @@ + + +inheritance84c535a038 + + +Base + + +Base + + + + + +TestsuiteBase + + +TestsuiteBase + + + + + +Base->TestsuiteBase + + + + + +Testsuite + + +Testsuite + + + + + +TestsuiteBase->Testsuite + + + + + \ No newline at end of file diff --git a/_images/inheritance-b3ab8866a38a3bf7108973a06bfc11e1c490f16d.svg b/_images/inheritance-b3ab8866a38a3bf7108973a06bfc11e1c490f16d.svg new file mode 100644 index 00000000..3957e06d --- /dev/null +++ b/_images/inheritance-b3ab8866a38a3bf7108973a06bfc11e1c490f16d.svg @@ -0,0 +1,29 @@ + + +inheritance3350518557 + + +AggregatedCoverage + + +AggregatedCoverage + + + + + +Coverage + + +Coverage + + + + + +Coverage->AggregatedCoverage + + + + + \ No newline at end of file diff --git a/_images/inheritance-c7ab3e0deee7adcde9e69100059bab8773152d51.svg b/_images/inheritance-c7ab3e0deee7adcde9e69100059bab8773152d51.svg new file mode 100644 index 00000000..c2b67ae7 --- /dev/null +++ b/_images/inheritance-c7ab3e0deee7adcde9e69100059bab8773152d51.svg @@ -0,0 +1,44 @@ + + +inheritance4f42c1461d + + +Base + + +Base + + + + + +TestsuiteBase + + +TestsuiteBase + + + + + +Base->TestsuiteBase + + + + + +TestsuiteSummary + + +TestsuiteSummary + + + + + +TestsuiteBase->TestsuiteSummary + + + + + \ No newline at end of file diff --git a/_images/inheritance-cab259f2901aa34572cc63a626c243608638d99e.svg b/_images/inheritance-cab259f2901aa34572cc63a626c243608638d99e.svg new file mode 100644 index 00000000..6bfd4e90 --- /dev/null +++ b/_images/inheritance-cab259f2901aa34572cc63a626c243608638d99e.svg @@ -0,0 +1,104 @@ + + +inheritanced00ef7988f + + +BaseDirective + + +BaseDirective + + + + + +DocCoverage + + +DocCoverage + + + + + +BaseDirective->DocCoverage + + + + + +ObjectDescription + + +ObjectDescription + + + + + +ObjectDescription->BaseDirective + + + + + +Directive + + +Directive + + + + + +SphinxDirective + + +SphinxDirective + + + + + +Directive->SphinxDirective + + + + + +DocStrCoverage + + +DocStrCoverage + + + + + +DocCoverage->DocStrCoverage + + + + + +Generic + + +Generic + + + + + +Generic->ObjectDescription + + + + + +SphinxDirective->ObjectDescription + + + + + \ No newline at end of file diff --git a/_images/inheritance-d40824be7ceb9e855ff0063198942135318b0dc7.svg b/_images/inheritance-d40824be7ceb9e855ff0063198942135318b0dc7.svg new file mode 100644 index 00000000..0b83cadc --- /dev/null +++ b/_images/inheritance-d40824be7ceb9e855ff0063198942135318b0dc7.svg @@ -0,0 +1,14 @@ + + +inheritance42359a937f + + +Base + + +Base + + + + + \ No newline at end of file diff --git a/_images/inheritance-e1b5cc50832a3da5ac6060499f7b9bb853fd908e.svg b/_images/inheritance-e1b5cc50832a3da5ac6060499f7b9bb853fd908e.svg new file mode 100644 index 00000000..c677fe52 --- /dev/null +++ b/_images/inheritance-e1b5cc50832a3da5ac6060499f7b9bb853fd908e.svg @@ -0,0 +1,44 @@ + + +inheritance2c9d687d8c + + +Enum + + +Enum + + + + + +Flag + + +Flag + + + + + +Enum->Flag + + + + + +LegendPosition + + +LegendPosition + + + + + +Flag->LegendPosition + + + + + \ No newline at end of file diff --git a/_images/inheritance-ea741a684969bf43b3943610d1cc85b94cf6ea04.svg b/_images/inheritance-ea741a684969bf43b3943610d1cc85b94cf6ea04.svg new file mode 100644 index 00000000..f0fea097 --- /dev/null +++ b/_images/inheritance-ea741a684969bf43b3943610d1cc85b94cf6ea04.svg @@ -0,0 +1,89 @@ + + +inheritance6527200f6c + + +BaseDirective + + +BaseDirective + + + + + +UnittestSummary + + +UnittestSummary + + + + + +BaseDirective->UnittestSummary + + + + + +ObjectDescription + + +ObjectDescription + + + + + +ObjectDescription->BaseDirective + + + + + +Directive + + +Directive + + + + + +SphinxDirective + + +SphinxDirective + + + + + +Directive->SphinxDirective + + + + + +Generic + + +Generic + + + + + +Generic->ObjectDescription + + + + + +SphinxDirective->ObjectDescription + + + + + \ No newline at end of file diff --git a/_images/inheritance-eb2a0d2f33730f7fcd601445c982b9840c33b307.svg b/_images/inheritance-eb2a0d2f33730f7fcd601445c982b9840c33b307.svg new file mode 100644 index 00000000..6238bbf4 --- /dev/null +++ b/_images/inheritance-eb2a0d2f33730f7fcd601445c982b9840c33b307.svg @@ -0,0 +1,44 @@ + + +inheritance42f105934e + + +AggregatedCoverage + + +AggregatedCoverage + + + + + +PackageCoverage + + +PackageCoverage + + + + + +AggregatedCoverage->PackageCoverage + + + + + +Coverage + + +Coverage + + + + + +Coverage->AggregatedCoverage + + + + + \ No newline at end of file diff --git a/_images/inheritance-f1510255a95184d9d9c9975b9e50c727acfc9d1f.svg b/_images/inheritance-f1510255a95184d9d9c9975b9e50c727acfc9d1f.svg new file mode 100644 index 00000000..808c121b --- /dev/null +++ b/_images/inheritance-f1510255a95184d9d9c9975b9e50c727acfc9d1f.svg @@ -0,0 +1,14 @@ + + +inheritance030f0c49ab + + +Coverage + + +Coverage + + + + + \ No newline at end of file diff --git a/_images/inheritance-fa1d3dc487b212641f516005923935c425d12ac4.svg b/_images/inheritance-fa1d3dc487b212641f516005923935c425d12ac4.svg new file mode 100644 index 00000000..805a5eb5 --- /dev/null +++ b/_images/inheritance-fa1d3dc487b212641f516005923935c425d12ac4.svg @@ -0,0 +1,59 @@ + + +inheritance7b347f307c + + +DocStrCoverageError + + +DocStrCoverageError + + + + + +ReportExtensionError + + +ReportExtensionError + + + + + +ReportExtensionError->DocStrCoverageError + + + + + +ExtensionError + + +ExtensionError + + + + + +ExtensionError->ReportExtensionError + + + + + +SphinxError + + +SphinxError + + + + + +SphinxError->ExtensionError + + + + + \ No newline at end of file diff --git a/_images/inheritance-fa4215ea63cd4a86412a47cd26d1519f70fededd.svg b/_images/inheritance-fa4215ea63cd4a86412a47cd26d1519f70fededd.svg new file mode 100644 index 00000000..4a419e47 --- /dev/null +++ b/_images/inheritance-fa4215ea63cd4a86412a47cd26d1519f70fededd.svg @@ -0,0 +1,59 @@ + + +inheritancea6fd13e7e5 + + +ExtensionError + + +ExtensionError + + + + + +ReportExtensionError + + +ReportExtensionError + + + + + +ExtensionError->ReportExtensionError + + + + + +SphinxError + + +SphinxError + + + + + +SphinxError->ExtensionError + + + + + +UnittestError + + +UnittestError + + + + + +ReportExtensionError->UnittestError + + + + + \ No newline at end of file diff --git a/_images/inheritance-fdb05ba504e271925c08c6c0d497e7af57128a4d.svg b/_images/inheritance-fdb05ba504e271925c08c6c0d497e7af57128a4d.svg new file mode 100644 index 00000000..cd1f09dc --- /dev/null +++ b/_images/inheritance-fdb05ba504e271925c08c6c0d497e7af57128a4d.svg @@ -0,0 +1,44 @@ + + +inheritance1c172a31ab + + +AggregatedCoverage + + +AggregatedCoverage + + + + + +ModuleCoverage + + +ModuleCoverage + + + + + +AggregatedCoverage->ModuleCoverage + + + + + +Coverage + + +Coverage + + + + + +Coverage->AggregatedCoverage + + + + + \ No newline at end of file diff --git a/_modules/index.html b/_modules/index.html new file mode 100644 index 00000000..a331dbd6 --- /dev/null +++ b/_modules/index.html @@ -0,0 +1,162 @@ + + + + + + Overview: module code — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports.html b/_modules/sphinx_reports.html new file mode 100644 index 00000000..059911c7 --- /dev/null +++ b/_modules/sphinx_reports.html @@ -0,0 +1,409 @@ + + + + + + sphinx_reports — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**A Sphinx domain providing directives to add reports to the Sphinx-based documentation.**
+
+Supported reports:
+
+* :ref:`DOCCOV`
+* :ref:`CODECOV`
+* :ref:`UNITTEST`
+* :ref:`DEP`
+
+"""
+__author__ =    "Patrick Lehmann"
+__email__ =     "Paebbels@gmail.com"
+__copyright__ = "2023-2024, Patrick Lehmann"
+__license__ =   "Apache License, Version 2.0"
+__version__ =   "0.6.0"
+__keywords__ =  ["Python3", "Sphinx", "Extension", "Report", "doc-string", "interrogate"]
+
+from hashlib              import md5
+from pathlib              import Path
+from typing               import Any, Tuple, Dict, Optional as Nullable, TypedDict, List, Callable
+
+from docutils             import nodes
+from sphinx.addnodes      import pending_xref
+from sphinx.application   import Sphinx
+from sphinx.builders      import Builder
+from sphinx.domains       import Domain
+from sphinx.environment   import BuildEnvironment
+from pyTooling.Decorators import export
+
+from .                    import static as ResourcePackage
+from .Common              import ReadResourceFile
+
+
+
+[docs] +@export +class ReportDomain(Domain): + """ + A Sphinx extension providing a ``report`` domain to integrate reports and summaries into a Sphinx-based documentation. + + .. rubric:: New directives: + + * :rst:dir:`doc-coverage` + + .. rubric:: New roles: + + * *None* + + .. rubric:: New indices: + + * *None* + + .. rubric:: Configuration variables + + All configuration variables in :file:`conf.py` are prefixed with ``report_*``: + + * ``report_unittest_testsuites`` + * ``report_codecov_packages`` + * ``report_doccov_packages`` + + """ + + name = "report" #: The name of this domain + label = "rpt" #: The label of this domain + + dependencies: List[str] = [ + ] #: A list of other extensions this domain depends on. + + from sphinx_reports.CodeCoverage import CodeCoverage + from sphinx_reports.DocCoverage import DocStrCoverage + from sphinx_reports.Unittest import UnittestSummary + + directives = { + "code-coverage": CodeCoverage, + "dependecy": DocStrCoverage, + "doc-coverage": DocStrCoverage, + "unittest-summary": UnittestSummary, + } #: A dictionary of all directives in this domain. + + roles = { + # "design": DesignRole, + } #: A dictionary of all roles in this domain. + + indices = [ + # LibraryIndex, + ] #: A list of all indices in this domain. + + configValues: Dict[str, Tuple[Any, str, Any]] = { + **DocStrCoverage.configValues, + **CodeCoverage.configValues, + **UnittestSummary.configValues, + } #: A dictionary of all configuration values used by this domain. (name: (default, rebuilt, type)) + + initial_data = { + "reports": {} + } #: A dictionary of all global data fields used by this domain. + + @property + def Reports(self) -> Dict[str, Any]: + return self.data["reports"] + +
+[docs] + @staticmethod + def AddCSSFiles(sphinxApplication: Sphinx) -> None: + """ + Call back for Sphinx ``builder-inited`` event. + + This callback will copy the CSS file(s) to the build directory. + + .. seealso:: + + Sphinx *builder-inited* event + See https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events + + :param sphinxApplication: The Sphinx application. + """ + # Create a new static path for this extension + staticDirectory = (Path(sphinxApplication.outdir) / "_report_static").resolve() + staticDirectory.mkdir(exist_ok=True) + sphinxApplication.config.html_static_path.append(str(staticDirectory)) + + # Read the CSS content from package resources and hash it + cssFilename = "sphinx-reports.css" + cssContent = ReadResourceFile(ResourcePackage, cssFilename) + + # Compute md5 hash of CSS file + hash = md5(cssContent.encode("utf8")).hexdigest() + + # Write the CSS file into output directory + cssFile = staticDirectory / f"sphinx-reports.{hash}.css" + sphinxApplication.add_css_file(cssFile.name) + + if not cssFile.exists(): + # Purge old CSS files + for file in staticDirectory.glob("*.css"): + file.unlink() + + # Write CSS content + cssFile.write_text(cssContent, encoding="utf8")
+ + +
+[docs] + @staticmethod + def ReadReports(sphinxApplication: Sphinx) -> None: + """ + Call back for Sphinx ``builder-inited`` event. + + This callback will read the configuration variable ``vhdl_designs`` and parse the found VHDL source files. + + .. seealso:: + + Sphinx *builder-inited* event + See https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events + + :param sphinxApplication: The Sphinx application. + """ + print(f"Callback: builder-inited -> ReadReports") + print(f"[REPORT] Reading reports ...")
+ + + + callbacks: Dict[str, List[Callable]] = { + "builder-inited": [AddCSSFiles, ReadReports], + } #: A dictionary of all `events/callbacks <https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events>`__ used by this domain. + +
+[docs] + def resolve_xref( + self, + env: BuildEnvironment, + fromdocname: str, + builder: Builder, + typ: str, + target: str, + node: pending_xref, + contnode: nodes.Element + ) -> Nullable[nodes.Element]: + raise NotImplementedError()
+
+ + + +class setup_ReturnType(TypedDict): + version: str + env_version: int + parallel_read_safe: bool + parallel_write_safe: bool + + +
+[docs] +@export +def setup(sphinxApplication: Sphinx) -> setup_ReturnType: + """ + Extension setup function registering the ``report`` domain in Sphinx. + + It will execute these steps: + + * register domains, directives and roles. + * connect events (register callbacks) + * register configuration variables for :file:`conf.py` + + :param sphinxApplication: The Sphinx application. + :return: Dictionary containing the extension version and some properties. + """ + sphinxApplication.add_domain(ReportDomain) + + # Register callbacks + for eventName, callbacks in ReportDomain.callbacks.items(): + for callback in callbacks: + sphinxApplication.connect(eventName, callback) + + # Register configuration options supported/needed in Sphinx's 'conf.py' + for configName, (configDefault, configRebuilt, configTypes) in ReportDomain.configValues.items(): + sphinxApplication.add_config_value(f"{ReportDomain.name}_{configName}", configDefault, configRebuilt, configTypes) + + return { + "version": __version__, # version of the extension + "env_version": int(__version__.split(".")[0]), # version of the data structure stored in the environment + 'parallel_read_safe': False, # Not yet evaluated, thus false + 'parallel_write_safe': True, # Internal data structure is used read-only, thus no problems will occur by parallel writing. + }
+ + + +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/Adapter/Coverage.html b/_modules/sphinx_reports/Adapter/Coverage.html new file mode 100644 index 00000000..ba1ad8cb --- /dev/null +++ b/_modules/sphinx_reports/Adapter/Coverage.html @@ -0,0 +1,269 @@ + + + + + + sphinx_reports.Adapter.Coverage — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.Adapter.Coverage

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**A Sphinx extension providing code coverage details embedded in documentation pages.**
+"""
+from pathlib import Path
+
+from coverage.results             import Numbers
+from pyTooling.Configuration.JSON import Configuration
+from pyTooling.Decorators         import export, readonly
+
+from sphinx_reports.Common                 import ReportExtensionError
+from sphinx_reports.DataModel.CodeCoverage import PackageCoverage, ModuleCoverage, AggregatedCoverage
+
+
+
+[docs] +@export +class CodeCoverageError(ReportExtensionError): + pass
+ + + +
+[docs] +@export +class Analyzer: + _packageName: str + _coverageReport: Configuration + +
+[docs] + def __init__(self, packageName: str, jsonCoverageFile: Path) -> None: + if not jsonCoverageFile.exists(): + raise CodeCoverageError(f"JSON coverage report '{jsonCoverageFile}' not found.") from FileNotFoundError(jsonCoverageFile) + + self._packageName = packageName + self._coverageReport = Configuration(jsonCoverageFile)
+ + + # if int(self._coverageReport["format"]) != 2: + # raise CodeCoverageError(f"File format of '{jsonCoverageFile}' is not supported.") + + @readonly + def PackageName(self) -> str: + return self._packageName + + @readonly + def JSONCoverageFile(self) -> Path: + return self._coverageReport.ConfigFile + + @readonly + def CoverageReport(self) -> Configuration: + return self._coverageReport + + def Convert(self) -> PackageCoverage: + rootPackageCoverage = PackageCoverage(self._packageName, Path("__init__.py")) + + for statusRecord in self._coverageReport["files"]: + moduleFile = Path(statusRecord.Key) + coverageSummary = statusRecord["summary"] + + moduleName = moduleFile.stem + modulePath = moduleFile.parent.parts[1:] + + currentCoverageObject: AggregatedCoverage = rootPackageCoverage + for packageName in modulePath: + try: + currentCoverageObject = currentCoverageObject[packageName] + except KeyError: + currentCoverageObject = PackageCoverage(packageName, moduleFile, currentCoverageObject) + + if moduleName != "__init__": + currentCoverageObject = ModuleCoverage(moduleName, moduleFile, currentCoverageObject) + + currentCoverageObject._totalStatements = int(coverageSummary["num_statements"]) + currentCoverageObject._excludedStatements = int(coverageSummary["excluded_lines"]) + currentCoverageObject._coveredStatements = int(coverageSummary["covered_lines"]) + currentCoverageObject._missingStatements = int(coverageSummary["missing_lines"]) + + currentCoverageObject._totalBranches = int(coverageSummary["num_branches"]) + currentCoverageObject._coveredBranches = int(coverageSummary["covered_branches"]) + currentCoverageObject._partialBranches = int(coverageSummary["num_partial_branches"]) + currentCoverageObject._missingBranches = int(coverageSummary["missing_branches"]) + + currentCoverageObject._coverage = float(coverageSummary["percent_covered"]) / 100.0 + + return rootPackageCoverage
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/Adapter/DocStrCoverage.html b/_modules/sphinx_reports/Adapter/DocStrCoverage.html new file mode 100644 index 00000000..3de1c578 --- /dev/null +++ b/_modules/sphinx_reports/Adapter/DocStrCoverage.html @@ -0,0 +1,281 @@ + + + + + + sphinx_reports.Adapter.DocStrCoverage — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.Adapter.DocStrCoverage

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**A Sphinx extension providing documentation coverage details embedded in documentation pages.**
+"""
+from pathlib import Path
+from typing  import List
+
+from docstr_coverage                   import analyze, ResultCollection
+from docstr_coverage.result_collection import FileCount
+from pyTooling.Decorators              import export, readonly
+
+from sphinx_reports.Common                          import ReportExtensionError
+from sphinx_reports.DataModel.DocumentationCoverage import ModuleCoverage, PackageCoverage, AggregatedCoverage
+
+
+
+[docs] +@export +class DocStrCoverageError(ReportExtensionError): + pass
+ + + +
+[docs] +@export +class Analyzer: + _packageName: str + _searchDirectory: Path + _moduleFiles: List[Path] + _coverageReport: ResultCollection + +
+[docs] + def __init__(self, packageName: str, directory: Path) -> None: + self._searchDirectory = directory + self._packageName = packageName + self._moduleFiles = [] + + if directory.exists(): + self._moduleFiles.extend(directory.glob("**/*.py")) + else: + raise DocStrCoverageError(f"Package source directory '{directory}' does not exist.") \ + from FileNotFoundError(directory)
+ + + @readonly + def SearchDirectories(self) -> Path: + return self._searchDirectory + + @readonly + def PackageName(self) -> str: + return self._packageName + + @readonly + def ModuleFiles(self) -> List[Path]: + return self._moduleFiles + + @readonly + def CoverageReport(self) -> ResultCollection: + return self._coverageReport + + def Analyze(self) -> ResultCollection: + self._coverageReport: ResultCollection = analyze(self._moduleFiles, show_progress=False) + return self._coverageReport + + def Convert(self) -> PackageCoverage: + rootPackageCoverage = PackageCoverage(self._packageName, self._searchDirectory / "__init__.py") + + for key, value in self._coverageReport.files(): + path: Path = key.relative_to(self._searchDirectory) + perFileResult: FileCount = value.count_aggregate() + + moduleName = path.stem + modulePath = path.parent.parts + + currentCoverageObject: AggregatedCoverage = rootPackageCoverage + for packageName in modulePath: + try: + currentCoverageObject = currentCoverageObject[packageName] + except KeyError: + currentCoverageObject = PackageCoverage(packageName, path, currentCoverageObject) + + if moduleName != "__init__": + currentCoverageObject = ModuleCoverage(moduleName, path, currentCoverageObject) + + currentCoverageObject._expected = perFileResult.needed + currentCoverageObject._covered = perFileResult.found + currentCoverageObject._uncovered = perFileResult.missing + + if currentCoverageObject._expected != 0: + currentCoverageObject._coverage = currentCoverageObject._covered / currentCoverageObject._expected + else: + currentCoverageObject._coverage = 1.0 + + if currentCoverageObject._uncovered != currentCoverageObject._expected - currentCoverageObject._covered: + currentCoverageObject._coverage = -2.0 + + return rootPackageCoverage
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/Adapter/JUnit.html b/_modules/sphinx_reports/Adapter/JUnit.html new file mode 100644 index 00000000..3b209112 --- /dev/null +++ b/_modules/sphinx_reports/Adapter/JUnit.html @@ -0,0 +1,299 @@ + + + + + + sphinx_reports.Adapter.JUnit — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.Adapter.JUnit

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**A Sphinx extension providing uni test results embedded in documentation pages.**
+"""
+from datetime        import datetime, timedelta
+from pathlib         import Path
+from xml.dom         import minidom, Node
+from xml.dom.minidom import Element
+
+from pyTooling.Decorators              import export, readonly
+
+from sphinx_reports.Common             import ReportExtensionError
+from sphinx_reports.DataModel.Unittest import Testsuite, Testcase, TestsuiteSummary, Test, TestcaseState
+
+
+
+[docs] +@export +class UnittestError(ReportExtensionError): + pass
+ + + +
+[docs] +@export +class Analyzer: + _reportFile: Path + _documentElement: Element + _testsuiteSummary: TestsuiteSummary + +
+[docs] + def __init__(self, reportFile: Path): + self._reportFile = reportFile + + if not self._reportFile.exists(): + # FIXME: not found vs. does not exist + # text in inner exception needed? + # FileNotFoundError(f"File '{self._path!s}' not found.") + raise UnittestError(f"JUnit unittest report file '{self._reportFile}' not found.") from FileNotFoundError(self._reportFile) + + try: + self._documentElement = minidom.parse(str(self._reportFile)).documentElement + except Exception as ex: + raise UnittestError(f"Couldn't open '{self._reportFile}'.") from ex
+ + + def Convert(self) -> TestsuiteSummary: + self._ParseRootElement(self._documentElement) + + return self._testsuiteSummary + + def _ParseRootElement(self, root: Element) -> None: + name = root.getAttribute("name") if root.hasAttribute("name") else "root" + testsuiteRuntime = float(root.getAttribute("time")) if root.hasAttribute("time") else -1.0 + timestamp = datetime.fromisoformat(root.getAttribute("timestamp")) if root.hasAttribute("timestamp") else None + + self._testsuiteSummary = TestsuiteSummary(name, timedelta(seconds=testsuiteRuntime)) + + tests = root.getAttribute("tests") + skipped = root.getAttribute("skipped") + errors = root.getAttribute("errors") + failures = root.getAttribute("failures") + assertions = root.getAttribute("assertions") + + for rootNode in root.childNodes: + if rootNode.nodeName == "testsuite": + self._ParseTestsuite(rootNode) + + def _ParseTestsuite(self, testsuitesNode: Element) -> None: + for node in testsuitesNode.childNodes: + if node.nodeType == Node.ELEMENT_NODE: + if node.tagName == "testsuite": + self._ParseTestsuite(node) + elif node.tagName == "testcase": + self._ParseTestcase(node) + + def _ParseTestcase(self, testsuiteNode: Element) -> None: + className = testsuiteNode.getAttribute("classname") + name = testsuiteNode.getAttribute("name") + time = float(testsuiteNode.getAttribute("time")) + + concurrentSuite = self._testsuiteSummary + + testsuitePath = className.split(".") + for testsuiteName in testsuitePath: + try: + concurrentSuite = concurrentSuite[testsuiteName] + except KeyError: + new = Testsuite(testsuiteName, timedelta(seconds=time)) + concurrentSuite._testsuites[testsuiteName] = new + concurrentSuite = new + + testcase = Testcase(name, timedelta(seconds=time)) + concurrentSuite._testcases[name] = testcase + + for node in testsuiteNode.childNodes: + if node.nodeType == Node.ELEMENT_NODE: + if node.tagName == "skipped": + testcase._state = TestcaseState.Skipped + elif node.tagName == "failure": + testcase._state = TestcaseState.Failed + elif node.tagName == "error": + testcase._state = TestcaseState.Error + elif node.tagName == "system-out": + pass + elif node.tagName == "system-err": + pass + elif node.tagName == "properties": + pass + else: + raise UnittestError(f"Unknown element '{node.tagName}' in junit file.") + + if testcase._state is TestcaseState.Unknown: + testcase._state = TestcaseState.Passed
+ + +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/CodeCoverage.html b/_modules/sphinx_reports/CodeCoverage.html new file mode 100644 index 00000000..d2041c0a --- /dev/null +++ b/_modules/sphinx_reports/CodeCoverage.html @@ -0,0 +1,464 @@ + + + + + + sphinx_reports.CodeCoverage — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.CodeCoverage

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**Report code coverage as Sphinx documentation page(s).**
+"""
+from pathlib import Path
+from typing  import Dict, Tuple, Any, List, Iterable, Mapping, Generator, TypedDict, Union, Optional as Nullable
+
+from docutils             import nodes
+from pyTooling.Decorators import export
+
+from sphinx_reports.Common                 import ReportExtensionError, LegendPosition
+from sphinx_reports.Sphinx                 import strip, BaseDirective
+from sphinx_reports.DataModel.CodeCoverage import PackageCoverage, AggregatedCoverage
+from sphinx_reports.Adapter.Coverage       import Analyzer
+
+
+class package_DictType(TypedDict):
+	name:        str
+	json_report: str
+	fail_below:  int
+	levels:      Dict[Union[int, str], Dict[str, str]]
+
+
+
+[docs] +@export +class CodeCoverage(BaseDirective): + """ + This directive will be replaced by a table representing code coverage. + """ + has_content = False + required_arguments = 0 + optional_arguments = 2 + + option_spec = { + "packageid": strip, + "legend": strip, + } + + directiveName: str = "code-coverage" + configPrefix: str = "codecov" + configValues: Dict[str, Tuple[Any, str, Any]] = { + f"{configPrefix}_packages": ({}, "env", Dict) + } #: A dictionary of all configuration values used by this domain. (name: (default, rebuilt, type)) + + _packageID: str + _legend: LegendPosition + _packageName: str + _jsonReport: Path + _failBelow: float + _levels: Dict[Union[int, str], Dict[str, str]] + _coverage: PackageCoverage + + def _CheckOptions(self) -> None: + # Parse all directive options or use default values + self._packageID = self._ParseStringOption("packageid") + self._legend = self._ParseLegendOption("legend", LegendPosition.bottom) + + def _CheckConfiguration(self) -> None: + from sphinx_reports import ReportDomain + + # Check configuration fields and load necessary values + try: + allPackages: Dict[str, package_DictType] = self.config[f"{ReportDomain.name}_{self.configPrefix}_packages"] + except (KeyError, AttributeError) as ex: + raise ReportExtensionError(f"Configuration option '{ReportDomain.name}_{self.configPrefix}_packages' is not configured.") from ex + + try: + packageConfiguration = allPackages[self._packageID] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages: No configuration found for '{self._packageID}'.") from ex + + try: + self._packageName = packageConfiguration["name"] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.name: Configuration is missing.") from ex + + try: + self._jsonReport = Path(packageConfiguration["json_report"]) + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.json_report: Configuration is missing.") from ex + + if not self._jsonReport.exists(): + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.json_report: Coverage report file '{self._jsonReport}' doesn't exist.") from FileNotFoundError(self._jsonReport) + + try: + self._failBelow = int(packageConfiguration["fail_below"]) / 100 + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.fail_below: Configuration is missing.") from ex + except ValueError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.fail_below: '{packageConfiguration['fail_below']}' is not an integer in range 0..100.") from ex + + if not (0.0 <= self._failBelow <= 100.0): + raise ReportExtensionError( + f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.fail_below: Is out of range 0..100.") + + try: + levels = packageConfiguration["levels"] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels: Configuration is missing.") from ex + + if 100 not in packageConfiguration["levels"]: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels[100]: Configuration is missing.") + + if "error" not in packageConfiguration["levels"]: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels[error]: Configuration is missing.") + + self._levels = {} + for level, levelConfig in levels.items(): + try: + if isinstance(level, str): + if level != "error": + raise ReportExtensionError( + f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels: Level is a keyword, but not 'error'.") + elif not (0.0 <= int(level) <= 100.0): + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels: Level is out of range 0..100.") + except ValueError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels: Level is not a keyword or an integer in range 0..100.") from ex + + try: + cssClass = levelConfig["class"] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels[level].class: CSS class is missing.") from ex + + try: + description = levelConfig["desc"] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels[level].desc: Description is missing.") from ex + + self._levels[level] = {"class": cssClass, "desc": description} + + def _ConvertToColor(self, currentLevel: float, configKey: str) -> str: + if currentLevel < 0.0: + return self._levels["error"][configKey] + + for levelLimit, levelConfig in self._levels.items(): + if isinstance(levelLimit, int) and (currentLevel * 100) < levelLimit: + return levelConfig[configKey] + + return self._levels[100][configKey] + + def _GenerateCoverageTable(self) -> nodes.table: + # Create a table and table header with 10 columns + table, tableGroup = self._PrepareTable( + identifier=self._packageID, + columns=[ + ("Package", [ + (" Module", 500) + ], None), + ("Statments", [ + ("Total", 100), + ("Excluded", 100), + ("Covered", 100), + ("Missing", 100) + ], None), + ("Branches", [ + ("Total", 100), + ("Covered", 100), + ("Partial", 100), + ("Missing", 100) + ], None), + ("Coverage", [ + ("in %", 100) + ], None) + ], + classes=["report-codecov-table"] + ) + tableBody = nodes.tbody() + tableGroup += tableBody + + def sortedValues(d: Mapping[str, AggregatedCoverage]) -> Generator[AggregatedCoverage, None, None]: + for key in sorted(d.keys()): + yield d[key] + + def renderlevel(tableBody: nodes.tbody, packageCoverage: PackageCoverage, level: int = 0) -> None: + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"{' '*level}📦{packageCoverage.Name}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.TotalStatements}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.ExcludedStatements}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.CoveredStatements}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.MissingStatements}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.TotalBranches}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.CoveredBranches}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.PartialBranches}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.MissingBranches}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.Coverage:.1%}")), + classes=["report-doccov-table-row", self._ConvertToColor(packageCoverage.Coverage, "class")], + ) + + for package in sortedValues(packageCoverage._packages): + renderlevel(tableBody, package, level + 1) + + for module in sortedValues(packageCoverage._modules): + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"{' '*(level+1)}  {module.Name}")), + nodes.entry("", nodes.paragraph(text=f"{module.TotalStatements}")), + nodes.entry("", nodes.paragraph(text=f"{module.ExcludedStatements}")), + nodes.entry("", nodes.paragraph(text=f"{module.CoveredStatements}")), + nodes.entry("", nodes.paragraph(text=f"{module.MissingStatements}")), + nodes.entry("", nodes.paragraph(text=f"{module.TotalBranches}")), + nodes.entry("", nodes.paragraph(text=f"{module.CoveredBranches}")), + nodes.entry("", nodes.paragraph(text=f"{module.PartialBranches}")), + nodes.entry("", nodes.paragraph(text=f"{module.MissingBranches}")), + nodes.entry("", nodes.paragraph(text=f"{module.Coverage :.1%}")), + classes=["report-doccov-table-row", self._ConvertToColor(module.Coverage, "class")], + ) + + renderlevel(tableBody, self._coverage) + + # Add a summary row + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"Overall ({self._coverage.FileCount} files):")), + nodes.entry("", nodes.paragraph(text=f"")), # {self._coverage.AggregatedExpected}")), + nodes.entry("", nodes.paragraph(text=f"")), # {self._coverage.AggregatedCovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {self._coverage.AggregatedCovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {self._coverage.AggregatedCovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {self._coverage.AggregatedCovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {self._coverage.AggregatedCovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {self._coverage.AggregatedCovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {self._coverage.AggregatedUncovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {self._coverage.AggregatedCoverage:.1%}")), + # classes=[self._ConvertToColor(self._coverage.coverage(), "class")] + classes=["report-doccov-summary-row", self._ConvertToColor(self._coverage.Coverage, "class")] # self._coverage.AggregatedCoverage, "class")] + ) + + return table + + def _CreateLegend(self, identifier: str, classes: Iterable[str]) -> List[nodes.Element]: + rubric = nodes.rubric("", text="Legend") + + table = nodes.table("", id=identifier, classes=classes) + + tableGroup = nodes.tgroup(cols=2) + table += tableGroup + + tableRow = nodes.row() + tableGroup += nodes.colspec(colwidth=300) + tableRow += nodes.entry("", nodes.paragraph(text="%")) + tableGroup += nodes.colspec(colwidth=300) + tableRow += nodes.entry("", nodes.paragraph(text="Coverage Level")) + tableGroup += nodes.thead("", tableRow) + + tableBody = nodes.tbody() + tableGroup += tableBody + + for level, config in self._levels.items(): + if isinstance(level, int): + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"≤{level}%")), + nodes.entry("", nodes.paragraph(text=config["desc"])), + classes=["report-doccov-legend-row", self._ConvertToColor((level - 1) / 100, "class")] + ) + + return [rubric, table] + +
+[docs] + def run(self) -> List[nodes.Node]: + self._CheckOptions() + self._CheckConfiguration() + + # Assemble a list of Python source files + analyzer = Analyzer(self._packageName, self._jsonReport) + self._coverage = analyzer.Convert() + # self._coverage.Aggregate() + + container = nodes.container() + + if LegendPosition.top in self._legend: + container += self._CreateLegend(identifier="legend1", classes=["report-doccov-legend"]) + + container += self._GenerateCoverageTable() + + if LegendPosition.bottom in self._legend: + container += self._CreateLegend(identifier="legend2", classes=["report-doccov-legend"]) + + return [container]
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/Common.html b/_modules/sphinx_reports/Common.html new file mode 100644 index 00000000..0ee09668 --- /dev/null +++ b/_modules/sphinx_reports/Common.html @@ -0,0 +1,228 @@ + + + + + + sphinx_reports.Common — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.Common

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**Common exceptions, classes and helper functions.**
+"""
+from enum                        import Flag
+from importlib.resources         import files
+from sys                         import version_info
+from types                       import ModuleType
+from typing                      import List, Union
+
+from pyTooling.Decorators        import export
+from sphinx.errors               import ExtensionError
+
+
+
+[docs] +@export +class ReportExtensionError(ExtensionError): + # WORKAROUND: for Python <3.11 + # Implementing a dummy method for Python versions before + __notes__: List[str] + if version_info < (3, 11): # pragma: no cover + def add_note(self, message: str) -> None: + try: + self.__notes__.append(message) + except AttributeError: + self.__notes__ = [message]
+ + + +
+[docs] +@export +class LegendPosition(Flag): + no_legend = 0 + top = 1 + bottom = 2 + both = 3
+ + + +
+[docs] +@export +def ReadResourceFile(module: Union[str, ModuleType], filename: str) -> str: + return files(module).joinpath(filename).read_text()
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/DataModel/CodeCoverage.html b/_modules/sphinx_reports/DataModel/CodeCoverage.html new file mode 100644 index 00000000..16619242 --- /dev/null +++ b/_modules/sphinx_reports/DataModel/CodeCoverage.html @@ -0,0 +1,346 @@ + + + + + + sphinx_reports.DataModel.CodeCoverage — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.DataModel.CodeCoverage

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**Abstract documentation coverage data model for Python code.**
+"""
+from pathlib import Path
+from typing  import Optional as Nullable, Dict, Union
+
+from pyTooling.Decorators import export, readonly
+
+
+
+[docs] +@export +class Coverage: + _name: str + _parent: Nullable["Coverage"] + +
+[docs] + def __init__(self, name: str, parent: Nullable["Coverage"] = None) -> None: + self._name = name + self._parent = parent
+ + + @readonly + def Name(self) -> str: + return self._name + + @readonly + def Parent(self) -> Nullable["Coverage"]: + return self._parent
+ + + +
+[docs] +@export +class AggregatedCoverage(Coverage): + _file: Path + + _totalStatements: int + _excludedStatements: int + _coveredStatements: int + _missingStatements: int + _totalBranches: int + _partialBranches: int + + _coverage: float + +
+[docs] + def __init__(self, name: str, file: Path, parent: Nullable["Coverage"] = None) -> None: + super().__init__(name, parent) + self._file = file + + self._totalStatements = 0 + self._excludedStatements = 0 + self._coveredStatements = 0 + self._missingStatements = 0 + + self._totalBranches = 0 + self._coveredBranches = 0 + self._partialBranches = 0 + self._missingBranches = 0 + + self._coverage = -1.0
+ + + @readonly + def File(self) -> Path: + return self._file + + @readonly + def TotalStatements(self) -> int: + return self._totalStatements + + @readonly + def ExcludedStatements(self) -> int: + return self._excludedStatements + + @readonly + def CoveredStatements(self) -> int: + return self._coveredStatements + + @readonly + def MissingStatements(self) -> int: + return self._missingStatements + + @readonly + def TotalBranches(self) -> int: + return self._totalBranches + + @readonly + def CoveredBranches(self) -> int: + return self._coveredBranches + + @readonly + def PartialBranches(self) -> int: + return self._partialBranches + + @readonly + def MissingBranches(self) -> int: + return self._missingBranches + + @readonly + def Coverage(self) -> float: + return self._coverage
+ + + +
+[docs] +@export +class ModuleCoverage(AggregatedCoverage): +
+[docs] + def __init__(self, name: str, file: Path, parent: Nullable["PackageCoverage"] = None) -> None: + super().__init__(name, file, parent) + + if parent is not None: + parent._modules[name] = self
+
+ + + +
+[docs] +@export +class PackageCoverage(AggregatedCoverage): + _fileCount: int + + _modules: Dict[str, ModuleCoverage] + _packages: Dict[str, "PackageCoverage"] + +
+[docs] + def __init__(self, name: str, file: Path, parent: Nullable["PackageCoverage"] = None) -> None: + super().__init__(name, file, parent) + + if parent is not None: + parent._packages[name] = self + + self._fileCount = 1 + self._modules = {} + self._packages = {}
+ + + @readonly + def FileCount(self) -> int: + return self._fileCount + + @readonly + def Modules(self) -> Dict[str, ModuleCoverage]: + return self._modules + + @readonly + def Packages(self) -> Dict[str, "PackageCoverage"]: + return self._packages + + def __getitem__(self, key: str) -> Union["PackageCoverage", ModuleCoverage]: + try: + return self._modules[key] + except KeyError: + return self._packages[key]
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/DataModel/DocumentationCoverage.html b/_modules/sphinx_reports/DataModel/DocumentationCoverage.html new file mode 100644 index 00000000..88e0a6a8 --- /dev/null +++ b/_modules/sphinx_reports/DataModel/DocumentationCoverage.html @@ -0,0 +1,614 @@ + + + + + + sphinx_reports.DataModel.DocumentationCoverage — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.DataModel.DocumentationCoverage

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**Abstract documentation coverage data model for Python code.**
+"""
+
+from enum    import Flag
+from pathlib import Path
+from typing import Optional as Nullable, Iterable, Dict, Union, Tuple
+
+from pyTooling.Decorators import export, readonly
+
+
+
+[docs] +@export +class CoverageState(Flag): + Unknown = 0 + Covered = 1 + Empty = 2 + + Weak = 16 + Detailed = 32 + + Parameters = 128 + ReturnValue = 256 + Exceptions = 512 + TypeHints = 1024 + + Ignored = 4096 + Excluded = 8192
+ + + +
+[docs] +@export +class Coverage: + _name: str + _parent: Nullable["Coverage"] + + _total: int + _excluded: int + _ignored: int + _expected: int + _covered: int + _uncovered: int + + _coverage: float + +
+[docs] + def __init__(self, name: str, parent: Nullable["Coverage"] = None) -> None: + self._name = name + self._parent = parent + + self._total = 0 + self._excluded = 0 + self._ignored = 0 + self._expected = 0 + self._covered = 0 + self._uncovered = 0 + + self._coverage = -1.0
+ + + @readonly + def Name(self) -> str: + return self._name + + @readonly + def Parent(self) -> Nullable["Coverage"]: + return self._parent + + @readonly + def Total(self) -> int: + return self._total + + @readonly + def Excluded(self) -> int: + return self._excluded + + @readonly + def Ignored(self) -> int: + return self._ignored + + @readonly + def Expected(self) -> int: + return self._expected + + @readonly + def Covered(self) -> int: + return self._covered + + @readonly + def Uncovered(self) -> int: + return self._uncovered + + @readonly + def Coverage(self) -> float: + return self._coverage + + def CalculateCoverage(self) -> None: + self._uncovered = self._expected - self._covered + if self._expected != 0: + self._coverage = self._covered / self._expected + else: + self._coverage = 1.0 + + def _CountCoverage(self, iterator: Iterable[CoverageState]) -> Tuple[int, int, int, int, int]: + total = 0 + excluded = 0 + ignored = 0 + expected = 0 + covered = 0 + for coverageState in iterator: + if coverageState is CoverageState.Unknown: + raise Exception(f"") + + total += 1 + + if CoverageState.Excluded in coverageState: + excluded += 1 + elif CoverageState.Ignored in coverageState: + ignored += 1 + + expected += 1 + if CoverageState.Covered in coverageState: + covered += 1 + + return total, excluded, ignored, expected, covered
+ + + +
+[docs] +@export +class AggregatedCoverage(Coverage): + _file: Path + _aggregatedTotal: int + _aggregatedExcluded: int + _aggregatedIgnored: int + _aggregatedExpected: int + _aggregatedCovered: int + _aggregatedUncovered: int + + _aggregatedCoverage: float + +
+[docs] + def __init__(self, name: str, file: Path, parent: Nullable["Coverage"] = None) -> None: + super().__init__(name, parent) + self._file = file
+ + + @readonly + def File(self) -> Path: + return self._file + + @readonly + def AggregatedTotal(self) -> int: + return self._aggregatedTotal + + @readonly + def AggregatedExcluded(self) -> int: + return self._aggregatedExcluded + + @readonly + def AggregatedIgnored(self) -> int: + return self._aggregatedIgnored + + @readonly + def AggregatedExpected(self) -> int: + return self._aggregatedExpected + + @readonly + def AggregatedCovered(self) -> int: + return self._aggregatedCovered + + @readonly + def AggregatedUncovered(self) -> int: + return self._aggregatedUncovered + + @readonly + def AggregatedCoverage(self) -> float: + return self._aggregatedCoverage + + def Aggregate(self) -> None: + assert self._aggregatedUncovered == self._aggregatedExpected - self._aggregatedCovered + + if self._aggregatedExpected != 0: + self._aggregatedCoverage = self._aggregatedCovered / self._aggregatedExpected + else: + self._aggregatedCoverage = 1.0
+ + + +
+[docs] +@export +class ClassCoverage(Coverage): + _fields: Dict[str, CoverageState] + _methods: Dict[str, CoverageState] + _classes: Dict[str, "ClassCoverage"] + +
+[docs] + def __init__(self, name: str, parent: Union["PackageCoverage", "ClassCoverage", None] = None) -> None: + super().__init__(name, parent) + + if parent is not None: + parent._classes[name] = self + + self._fields = {} + self._methods = {} + self._classes = {}
+ + + @readonly + def Fields(self) -> Dict[str, CoverageState]: + return self._fields + + @readonly + def Methods(self) -> Dict[str, CoverageState]: + return self._methods + + @readonly + def Classes(self) -> Dict[str, "ClassCoverage"]: + return self._classes + + def CalculateCoverage(self) -> None: + for cls in self._classes.values(): + cls.CalculateCoverage() + + self._total, self._excluded, self._ignored, self._expected, self._covered = \ + self._CountCoverage(zip( + self._fields.values(), + self._methods.values() + )) + + super().CalculateCoverage() + +
+[docs] + def __str__(self) -> str: + return f"<ClassCoverage - tot:{self._total}, ex:{self._excluded}, ig:{self._ignored}, exp:{self._expected}, cov:{self._covered}, un:{self._uncovered} => {self._coverage:.1%}>"
+
+ + + +
+[docs] +@export +class ModuleCoverage(AggregatedCoverage): + _variables: Dict[str, CoverageState] + _functions: Dict[str, CoverageState] + _classes: Dict[str, ClassCoverage] + +
+[docs] + def __init__(self, name: str, file: Path, parent: Nullable["PackageCoverage"] = None) -> None: + super().__init__(name, file, parent) + + if parent is not None: + parent._modules[name] = self + + self._file = file + self._variables = {} + self._functions = {} + self._classes = {}
+ + + @readonly + def Variables(self) -> Dict[str, CoverageState]: + return self._variables + + @readonly + def Functions(self) -> Dict[str, CoverageState]: + return self._functions + + @readonly + def Classes(self) -> Dict[str, ClassCoverage]: + return self._classes + + def CalculateCoverage(self) -> None: + for cls in self._classes.values(): + cls.CalculateCoverage() + + self._total, self._excluded, self._ignored, self._expected, self._covered = \ + self._CountCoverage(zip( + self._variables.values(), + self._functions.values() + )) + + super().CalculateCoverage() + + def Aggregate(self) -> None: + self._aggregatedTotal = self._total + self._aggregatedExcluded = self._excluded + self._aggregatedIgnored = self._ignored + self._aggregatedExpected = self._expected + self._aggregatedCovered = self._covered + self._aggregatedUncovered = self._uncovered + + for cls in self._classes.values(): + self._aggregatedTotal += cls._total + self._aggregatedExcluded += cls._excluded + self._aggregatedIgnored += cls._ignored + self._aggregatedExpected += cls._expected + self._aggregatedCovered += cls._covered + self._aggregatedUncovered += cls._uncovered + + super().Aggregate() + +
+[docs] + def __str__(self) -> str: + return f"<ModuleCoverage - tot:{self._total}|{self._aggregatedTotal}, ex:{self._excluded}|{self._aggregatedExcluded}, ig:{self._ignored}|{self._aggregatedIgnored}, exp:{self._expected}|{self._aggregatedExpected}, cov:{self._covered}|{self._aggregatedCovered}, un:{self._uncovered}|{self._aggregatedUncovered} => {self._coverage:.1%}|{self._aggregatedCoverage:.1%}>"
+
+ + + +
+[docs] +@export +class PackageCoverage(AggregatedCoverage): + _fileCount: int + _variables: Dict[str, CoverageState] + _functions: Dict[str, CoverageState] + _classes: Dict[str, ClassCoverage] + _modules: Dict[str, ModuleCoverage] + _packages: Dict[str, "PackageCoverage"] + +
+[docs] + def __init__(self, name: str, file: Path, parent: Nullable["PackageCoverage"] = None) -> None: + super().__init__(name, file, parent) + + if parent is not None: + parent._packages[name] = self + + self._file = file + self._fileCount = 1 + self._variables = {} + self._functions = {} + self._classes = {} + self._modules = {} + self._packages = {}
+ + + @readonly + def FileCount(self) -> int: + return self._fileCount + + @readonly + def Variables(self) -> Dict[str, CoverageState]: + return self._variables + + @readonly + def Functions(self) -> Dict[str, CoverageState]: + return self._functions + + @readonly + def Classes(self) -> Dict[str, ClassCoverage]: + return self._classes + + @readonly + def Modules(self) -> Dict[str, ModuleCoverage]: + return self._modules + + @readonly + def Packages(self) -> Dict[str, "PackageCoverage"]: + return self._packages + + def __getitem__(self, key: str) -> Union["PackageCoverage", ModuleCoverage]: + try: + return self._modules[key] + except KeyError: + return self._packages[key] + + def CalculateCoverage(self) -> None: + for cls in self._classes.values(): + cls.CalculateCoverage() + + for mod in self._modules.values(): + mod.CalculateCoverage() + + for pkg in self._packages.values(): + pkg.CalculateCoverage() + + self._total, self._excluded, self._ignored, self._expected, self._covered = \ + self._CountCoverage(zip( + self._variables.values(), + self._functions.values() + )) + + super().CalculateCoverage() + + def Aggregate(self) -> None: + self._fileCount = len(self._modules) + 1 + self._aggregatedTotal = self._total + self._aggregatedExcluded = self._excluded + self._aggregatedIgnored = self._ignored + self._aggregatedExpected = self._expected + self._aggregatedCovered = self._covered + self._aggregatedUncovered = self._uncovered + + for pkg in self._packages.values(): + pkg.Aggregate() + self._fileCount += pkg._fileCount + self._aggregatedTotal += pkg._total + self._aggregatedExcluded += pkg._excluded + self._aggregatedIgnored += pkg._ignored + self._aggregatedExpected += pkg._expected + self._aggregatedCovered += pkg._covered + self._aggregatedUncovered += pkg._uncovered + + for mod in self._modules.values(): + mod.Aggregate() + self._aggregatedTotal += mod._total + self._aggregatedExcluded += mod._excluded + self._aggregatedIgnored += mod._ignored + self._aggregatedExpected += mod._expected + self._aggregatedCovered += mod._covered + self._aggregatedUncovered += mod._uncovered + + super().Aggregate() + +
+[docs] + def __str__(self) -> str: + return f"<PackageCoverage - tot:{self._total}|{self._aggregatedTotal}, ex:{self._excluded}|{self._aggregatedExcluded}, ig:{self._ignored}|{self._aggregatedIgnored}, exp:{self._expected}|{self._aggregatedExpected}, cov:{self._covered}|{self._aggregatedCovered}, un:{self._uncovered}|{self._aggregatedUncovered} => {self._coverage:.1%}|{self._aggregatedCoverage:.1%}>"
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/DataModel/Unittest.html b/_modules/sphinx_reports/DataModel/Unittest.html new file mode 100644 index 00000000..c43a6c61 --- /dev/null +++ b/_modules/sphinx_reports/DataModel/Unittest.html @@ -0,0 +1,458 @@ + + + + + + sphinx_reports.DataModel.Unittest — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.DataModel.Unittest

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**Abstract documentation coverage data model for Python code.**
+"""
+from datetime import timedelta
+from enum     import Flag
+from typing   import Optional as Nullable, Dict, Union, Tuple
+
+from pyTooling.Decorators import export, readonly
+
+from sphinx_reports.Common import ReportExtensionError
+
+
+
+[docs] +@export +class UnittestError(ReportExtensionError): + pass
+ + + +
+[docs] +@export +class TestcaseState(Flag): + Unknown = 0 + Failed = 1 + Error = 2 + Skipped = 3 + Passed = 4
+ + + +
+[docs] +@export +class Base: + _name: str + _state: TestcaseState + _time: timedelta + +
+[docs] + def __init__(self, name: str, time: timedelta) -> None: + self._name = name + self._state = TestcaseState.Unknown + self._time = time
+ + + @readonly + def Name(self) -> str: + return self._name + + @readonly + def State(self) -> TestcaseState: + return self._state + + @readonly + def Time(self) -> timedelta: + return self._time
+ + + +
+[docs] +@export +class Test(Base): +
+[docs] + def __init__(self, name: str) -> None: + super().__init__(name)
+
+ + + +
+[docs] +@export +class Testcase(Base): + _tests: Dict[str, Test] + + _assertions: int + +
+[docs] + def __init__(self, name: str, time: timedelta) -> None: + super().__init__(name, time) + + self._tests = {} + self._assertions = 0
+ + + @readonly + def Assertions(self) -> int: + return self._assertions
+ + + +
+[docs] +@export +class TestsuiteBase(Base): + _testsuites: Dict[str, "Testsuite"] + + _tests: int + _skipped: int + _errored: int + _failed: int + _passed: int + +
+[docs] + def __init__(self, name: str, time: timedelta) -> None: + super().__init__(name, time) + + self._testsuites = {} + + self._tests = 0 + self._skipped = 0 + self._errored = 0 + self._failed = 0 + self._passed = 0
+ + + def __getitem__(self, key: str) -> "Testsuite": + return self._testsuites[key] + + def __contains__(self, key: str) -> bool: + return key in self._testsuites + + @readonly + def Testsuites(self) -> Dict[str, "Testsuite"]: + return self._testsuites + + @readonly + def Tests(self) -> int: + return self._tests + + @readonly + def Skipped(self) -> int: + return self._skipped + + @readonly + def Errored(self) -> int: + return self._errored + + @readonly + def Failed(self) -> int: + return self._failed + + @readonly + def Passed(self) -> int: + return self._passed + + def Aggregate(self) -> Tuple[int, int, int, int, int]: + tests = 0 + skipped = 0 + errored = 0 + failed = 0 + passed = 0 + + for testsuite in self._testsuites.values(): + t, s, e, f, p = testsuite.Aggregate() + tests += t + skipped += s + errored += e + failed += f + passed += p + + return tests, skipped, errored, failed, passed
+ + + +
+[docs] +@export +class Testsuite(TestsuiteBase): + _testcases: Dict[str, Testcase] + +
+[docs] + def __init__(self, name: str, time: timedelta) -> None: + super().__init__(name, time) + + self._testcases = {}
+ + + def __getitem__(self, key: str) -> Union["Testsuite", Testcase]: + try: + return self._testsuites[key] + except KeyError: + return self._testcases[key] + + def __contains__(self, key: str) -> bool: + if key not in self._testsuites: + return key in self._testcases + + return False + + @readonly + def Testcases(self) -> Dict[str, Testcase]: + return self._testcases + + def Aggregate(self) -> Tuple[int, int, int, int, int]: + tests, skipped, errored, failed, passed = super().Aggregate() + + for testcase in self._testcases.values(): + if testcase._state is TestcaseState.Passed: + tests += 1 + passed += 1 + elif testcase._state is TestcaseState.Failed: + tests += 1 + failed += 1 + elif testcase._state is TestcaseState.Skipped: + tests += 1 + skipped += 1 + elif testcase._state is TestcaseState.Error: + tests += 1 + errored += 1 + elif testcase._state is TestcaseState.Unknown: + raise UnittestError(f"Found testcase '{testcase._name}' with unknown state.") + + self._tests = tests + self._skipped = skipped + self._errored = errored + self._failed = failed + self._passed = passed + + if errored > 0: + self._state = TestcaseState.Error + elif failed > 0: + self._state = TestcaseState.Failed + elif tests - skipped == passed: + self._state = TestcaseState.Passed + elif tests == skipped: + self._state = TestcaseState.Skipped + else: + self._state = TestcaseState.Unknown + + return tests, skipped, errored, failed, passed
+ + + +
+[docs] +@export +class TestsuiteSummary(TestsuiteBase): + _time: float + +
+[docs] + def __init__(self, name: str, time: timedelta): + super().__init__(name, time)
+ + + def Aggregate(self) -> Tuple[int, int, int, int, int]: + tests, skipped, errored, failed, passed = super().Aggregate() + + self._tests = tests + self._skipped = skipped + self._errored = errored + self._failed = failed + self._passed = passed + + if errored > 0: + self._state = TestcaseState.Error + elif failed > 0: + self._state = TestcaseState.Failed + elif tests - skipped == passed: + self._state = TestcaseState.Passed + elif tests == skipped: + self._state = TestcaseState.Skipped + else: + self._state = TestcaseState.Unknown + + return tests, skipped, errored, failed, passed
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/DocCoverage.html b/_modules/sphinx_reports/DocCoverage.html new file mode 100644 index 00000000..0db673a3 --- /dev/null +++ b/_modules/sphinx_reports/DocCoverage.html @@ -0,0 +1,445 @@ + + + + + + sphinx_reports.DocCoverage — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.DocCoverage

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**Report documentation coverage as Sphinx documentation page(s).**
+"""
+from pathlib import Path
+from typing import Dict, Tuple, Any, List, Iterable, Mapping, Generator, TypedDict, Union
+
+from docutils             import nodes
+from pyTooling.Decorators import export
+
+from sphinx_reports.Common                          import ReportExtensionError, LegendPosition
+from sphinx_reports.Sphinx                          import strip, BaseDirective
+from sphinx_reports.DataModel.DocumentationCoverage import PackageCoverage, AggregatedCoverage
+from sphinx_reports.Adapter.DocStrCoverage          import Analyzer
+
+
+class package_DictType(TypedDict):
+	name: str
+	directory: str
+	fail_below: int
+	levels: Dict[Union[int, str], Dict[str, str]]
+
+
+
+[docs] +@export +class DocCoverage(BaseDirective): + """ + This directive will be replaced by a table representing documentation coverage. + """ + has_content = False + required_arguments = 0 + optional_arguments = 2 + + option_spec = { + "packageid": strip, + "legend": strip, + } + + directiveName: str = "docstr-coverage" + configPrefix: str = "doccov" + configValues: Dict[str, Tuple[Any, str, Any]] = { + f"{configPrefix}_packages": ({}, "env", Dict) + } #: A dictionary of all configuration values used by this domain. (name: (default, rebuilt, type)) + + _packageID: str + _legend: LegendPosition + _packageName: str + _directory: Path + _failBelow: float + _levels: Dict[Union[int, str], Dict[str, str]] + _coverage: PackageCoverage + + def _CheckOptions(self) -> None: + # Parse all directive options or use default values + self._packageID = self._ParseStringOption("packageid") + self._legend = self._ParseLegendOption("legend", LegendPosition.bottom) + + def _CheckConfiguration(self) -> None: + from sphinx_reports import ReportDomain + + # Check configuration fields and load necessary values + try: + allPackages: Dict[str, package_DictType] = self.config[f"{ReportDomain.name}_{self.configPrefix}_packages"] + except (KeyError, AttributeError) as ex: + raise ReportExtensionError(f"Configuration option '{ReportDomain.name}_{self.configPrefix}_packages' is not configured.") from ex + + try: + packageConfiguration = allPackages[self._packageID] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages: No configuration found for '{self._packageID}'.") from ex + + try: + self._packageName = packageConfiguration["name"] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.name: Configuration is missing.") from ex + + try: + self._directory = Path(packageConfiguration["directory"]) + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.directory: Configuration is missing.") from ex + + if not self._directory.exists(): + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.directory: Directory '{self._directory}' doesn't exist.") from FileNotFoundError(self._directory) + + try: + self._failBelow = int(packageConfiguration["fail_below"]) / 100 + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.fail_below: Configuration is missing.") from ex + except ValueError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.fail_below: '{packageConfiguration['fail_below']}' is not an integer in range 0..100.") from ex + + if not (0.0 <= self._failBelow <= 100.0): + raise ReportExtensionError( + f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.fail_below: Is out of range 0..100.") + + try: + levels = packageConfiguration["levels"] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels: Configuration is missing.") from ex + + if 100 not in packageConfiguration["levels"]: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels[100]: Configuration is missing.") + + if "error" not in packageConfiguration["levels"]: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels[error]: Configuration is missing.") + + self._levels = {} + for level, levelConfig in levels.items(): + try: + if isinstance(level, str): + if level != "error": + raise ReportExtensionError( + f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels: Level is a keyword, but not 'error'.") + elif not (0.0 <= int(level) <= 100.0): + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels: Level is out of range 0..100.") + except ValueError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels: Level is not a keyword or an integer in range 0..100.") from ex + + try: + cssClass = levelConfig["class"] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels[level].class: CSS class is missing.") from ex + + try: + description = levelConfig["desc"] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_packages:{self._packageID}.levels[level].desc: Description is missing.") from ex + + self._levels[level] = {"class": cssClass, "desc": description} + + def _ConvertToColor(self, currentLevel: float, configKey: str) -> str: + if currentLevel < 0.0: + return self._levels["error"][configKey] + + for levelLimit, levelConfig in self._levels.items(): + if isinstance(levelLimit, int) and (currentLevel * 100) < levelLimit: + return levelConfig[configKey] + + return self._levels[100][configKey] + + def _GenerateCoverageTable(self) -> nodes.table: + # Create a table and table header with 5 columns + table, tableGroup = self._PrepareTable( + identifier=self._packageID, + columns=[ + ("Filename", None, 500), + ("Total", None, 100), + ("Covered", None, 100), + ("Missing", None, 100), + ("Coverage in %", None, 100) + ], + classes=["report-doccov-table"] + ) + tableBody = nodes.tbody() + tableGroup += tableBody + + def sortedValues(d: Mapping[str, AggregatedCoverage]) -> Generator[AggregatedCoverage, None, None]: + for key in sorted(d.keys()): + yield d[key] + + def renderlevel(tableBody: nodes.tbody, packageCoverage: PackageCoverage, level: int = 0) -> None: + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"{' '*level}📦{packageCoverage.Name}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.Expected}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.Covered}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.Uncovered}")), + nodes.entry("", nodes.paragraph(text=f"{packageCoverage.Coverage:.1%}")), + classes=["report-doccov-table-row", self._ConvertToColor(packageCoverage.Coverage, "class")], + ) + + for package in sortedValues(packageCoverage._packages): + renderlevel(tableBody, package, level + 1) + + for module in sortedValues(packageCoverage._modules): + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"{' '*(level+1)}  {module.Name}")), + nodes.entry("", nodes.paragraph(text=f"{module.Expected}")), + nodes.entry("", nodes.paragraph(text=f"{module.Covered}")), + nodes.entry("", nodes.paragraph(text=f"{module.Uncovered}")), + nodes.entry("", nodes.paragraph(text=f"{module.Coverage :.1%}")), + classes=["report-doccov-table-row", self._ConvertToColor(module.Coverage, "class")], + ) + + renderlevel(tableBody, self._coverage) + + # Add a summary row + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"Overall ({self._coverage.FileCount} files):")), + nodes.entry("", nodes.paragraph(text=f"{self._coverage.AggregatedExpected}")), + nodes.entry("", nodes.paragraph(text=f"{self._coverage.AggregatedCovered}")), + nodes.entry("", nodes.paragraph(text=f"{self._coverage.AggregatedUncovered}")), + nodes.entry("", nodes.paragraph(text=f"{self._coverage.AggregatedCoverage:.1%}"), + # classes=[self._ConvertToColor(self._coverage.coverage(), "class")] + ), + classes=["report-doccov-summary-row", self._ConvertToColor(self._coverage.AggregatedCoverage, "class")] + ) + + return table + + def _CreateLegend(self, identifier: str, classes: Iterable[str]) -> List[nodes.Element]: + rubric = nodes.rubric("", text="Legend") + + table = nodes.table("", id=identifier, classes=classes) + + tableGroup = nodes.tgroup(cols=2) + table += tableGroup + + tableRow = nodes.row() + tableGroup += nodes.colspec(colwidth=300) + tableRow += nodes.entry("", nodes.paragraph(text="%")) + tableGroup += nodes.colspec(colwidth=300) + tableRow += nodes.entry("", nodes.paragraph(text="Coverage Level")) + tableGroup += nodes.thead("", tableRow) + + tableBody = nodes.tbody() + tableGroup += tableBody + + for level, config in self._levels.items(): + if isinstance(level, int): + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"≤{level}%")), + nodes.entry("", nodes.paragraph(text=config["desc"])), + classes=["report-doccov-legend-row", self._ConvertToColor((level - 1) / 100, "class")] + ) + + return [rubric, table]
+ + + +
+[docs] +@export +class DocStrCoverage(DocCoverage): +
+[docs] + def run(self) -> List[nodes.Node]: + self._CheckOptions() + self._CheckConfiguration() + + # Assemble a list of Python source files + analyzer = Analyzer(self._packageName, self._directory) + analyzer.Analyze() + self._coverage = analyzer.Convert() + # self._coverage.CalculateCoverage() + self._coverage.Aggregate() + + container = nodes.container() + + if LegendPosition.top in self._legend: + container += self._CreateLegend(identifier="legend1", classes=["report-doccov-legend"]) + + container += self._GenerateCoverageTable() + + if LegendPosition.bottom in self._legend: + container += self._CreateLegend(identifier="legend2", classes=["report-doccov-legend"]) + + return [container]
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/Sphinx.html b/_modules/sphinx_reports/Sphinx.html new file mode 100644 index 00000000..4c2e5c2c --- /dev/null +++ b/_modules/sphinx_reports/Sphinx.html @@ -0,0 +1,332 @@ + + + + + + sphinx_reports.Sphinx — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.Sphinx

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**Helper functions and derived classes from Sphinx.**
+"""
+from re     import match as re_match
+from typing import Optional as Nullable, Tuple, List, Dict
+
+from docutils import nodes
+from pyTooling.Decorators import export
+from sphinx.directives    import ObjectDescription
+
+from sphinx_reports.Common import ReportExtensionError, LegendPosition
+
+
+
+[docs] +@export +def strip(option: str) -> str: + return option.strip().lower()
+ + + +
+[docs] +@export +class BaseDirective(ObjectDescription): + has_content: bool = False + """ + A boolean; ``True`` if content is allowed. + + Client code must handle the case where content is required but not supplied (an empty content list will be supplied). + """ + + required_arguments = 0 + """Number of required directive arguments.""" + + optional_arguments = 0 + """Number of optional arguments after the required arguments.""" + + final_argument_whitespace = False + """A boolean, indicating if the final argument may contain whitespace.""" + + option_spec = {} + """ + Mapping of option names to validator functions. + + A dictionary, mapping known option names to conversion functions such as :class:`int` or :class:`float` + (default: {}, no options). Several conversion functions are defined in the ``directives/__init__.py`` module. + + Option conversion functions take a single parameter, the option argument (a string or :class:`None`), validate it + and/or convert it to the appropriate form. Conversion functions may raise :exc:`ValueError` and + :exc:`TypeError` exceptions. + """ + + directiveName: str + + def _ParseBooleanOption(self, optionName: str, default: Nullable[bool] = None) -> bool: + try: + option = self.options[optionName] + except KeyError as ex: + if default is not None: + return default + else: + raise ReportExtensionError(f"{self.directiveName}: Required option '{optionName}' not found for directive.") from ex + + if option in ("yes", "true"): + return True + elif option in ("no", "false"): + return False + else: + raise ReportExtensionError(f"{self.directiveName}::{optionName}: '{option}' not supported for a boolean value (yes/true, no/false).") + + def _ParseStringOption(self, optionName: str, default: Nullable[str] = None, regexp: str = "\\w+") -> str: + try: + option: str = self.options[optionName] + except KeyError as ex: + if default is not None: + return default + else: + raise ReportExtensionError(f"{self.directiveName}: Required option '{optionName}' not found for directive.") from ex + + if re_match(regexp, option): + return option + else: + raise ReportExtensionError(f"{self.directiveName}::{optionName}: '{option}' not an accepted value for regexp '{regexp}'.") + + def _ParseLegendOption(self, optionName: str, default: Nullable[LegendPosition] = None) -> LegendPosition: + try: + option = self.options[optionName].lower() + except KeyError as ex: + if default is not None: + return default + else: + raise ReportExtensionError(f"{self.directiveName}: Required option '{optionName}' not found for directive.") from ex + + try: + return LegendPosition[option] + except KeyError as ex: + raise ReportExtensionError(f"{self.directiveName}::{optionName}: Value '{option}' is not a valid member of 'LegendPosition'.") from ex + + def _PrepareTable(self, columns: List[Tuple[str, Nullable[List[Tuple[str, int]]], Nullable[int]]], identifier: str, classes: List[str]) -> Tuple[nodes.table, nodes.tgroup]: + table = nodes.table("", identifier=identifier, classes=classes) + + hasSecondHeaderRow = False + columnCount = 0 + for groupColumn in columns: + if groupColumn[1] is not None: + columnCount += len(groupColumn[1]) + hasSecondHeaderRow = True + else: + columnCount += 1 + + tableGroup = nodes.tgroup(cols=columnCount) + table += tableGroup + + # Setup column specifications + for _, more, width in columns: + if more is None: + tableGroup += nodes.colspec(colwidth=width) + else: + for _, width in more: + tableGroup += nodes.colspec(colwidth=width) + + # Setup primary header row + headerRow = nodes.row() + for columnTitle, more, _ in columns: + if more is None: + headerRow += nodes.entry("", nodes.paragraph(text=columnTitle), morerows=1) + else: + morecols = len(more) - 1 + headerRow += nodes.entry("", nodes.paragraph(text=columnTitle), morecols=morecols) + for i in range(morecols): + headerRow += None + + tableHeader = nodes.thead("", headerRow) + tableGroup += tableHeader + + # If present, setup secondary header row + if hasSecondHeaderRow: + tableRow = nodes.row() + for columnTitle, more, _ in columns: + if more is None: + tableRow += None + else: + for columnTitle, _ in more: + tableRow += nodes.entry("", nodes.paragraph(text=columnTitle)) + + tableHeader += tableRow + + return table, tableGroup
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_modules/sphinx_reports/Unittest.html b/_modules/sphinx_reports/Unittest.html new file mode 100644 index 00000000..c42e98e3 --- /dev/null +++ b/_modules/sphinx_reports/Unittest.html @@ -0,0 +1,382 @@ + + + + + + sphinx_reports.Unittest — sphinx_reports 0.6.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for sphinx_reports.Unittest

+# ==================================================================================================================== #
+#            _     _                                           _                                                       #
+#  ___ _ __ | |__ (_)_ __ __  __     _ __ ___ _ __   ___  _ __| |_ ___                                                 #
+# / __| '_ \| '_ \| | '_ \\ \/ /____| '__/ _ \ '_ \ / _ \| '__| __/ __|                                                #
+# \__ \ |_) | | | | | | | |>  <_____| | |  __/ |_) | (_) | |  | |_\__ \                                                #
+# |___/ .__/|_| |_|_|_| |_/_/\_\    |_|  \___| .__/ \___/|_|   \__|___/                                                #
+#     |_|                                    |_|                                                                       #
+# ==================================================================================================================== #
+# Authors:                                                                                                             #
+#   Patrick Lehmann                                                                                                    #
+#                                                                                                                      #
+# License:                                                                                                             #
+# ==================================================================================================================== #
+# Copyright 2023-2024 Patrick Lehmann - Bötzingen, Germany                                                             #
+#                                                                                                                      #
+# Licensed under the Apache License, Version 2.0 (the "License");                                                      #
+# you may not use this file except in compliance with the License.                                                     #
+# You may obtain a copy of the License at                                                                              #
+#                                                                                                                      #
+#   http://www.apache.org/licenses/LICENSE-2.0                                                                         #
+#                                                                                                                      #
+# Unless required by applicable law or agreed to in writing, software                                                  #
+# distributed under the License is distributed on an "AS IS" BASIS,                                                    #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                             #
+# See the License for the specific language governing permissions and                                                  #
+# limitations under the License.                                                                                       #
+#                                                                                                                      #
+# SPDX-License-Identifier: Apache-2.0                                                                                  #
+# ==================================================================================================================== #
+#
+"""
+**Report unit test results as Sphinx documentation page(s).**
+"""
+from datetime import timedelta
+from pathlib  import Path
+from typing   import Dict, Tuple, Any, List, Mapping, Generator, TypedDict
+
+from docutils             import nodes
+from pyTooling.Decorators import export
+
+from sphinx_reports.Common             import ReportExtensionError
+from sphinx_reports.Sphinx             import strip, BaseDirective
+from sphinx_reports.DataModel.Unittest import Testsuite, TestsuiteSummary, Testcase, TestcaseState
+from sphinx_reports.Adapter.JUnit      import Analyzer
+
+
+class report_DictType(TypedDict):
+	xml_report: str
+
+
+
+[docs] +@export +class UnittestSummary(BaseDirective): + """ + This directive will be replaced by a table representing unit test results. + """ + has_content = False + required_arguments = 0 + optional_arguments = 1 + + option_spec = { + "reportid": strip, + } + + directiveName: str = "unittest-summary" + configPrefix: str = "unittest" + configValues: Dict[str, Tuple[Any, str, Any]] = { + f"{configPrefix}_testsuites": ({}, "env", Dict) + } #: A dictionary of all configuration values used by this domain. (name: (default, rebuilt, type)) + + _reportID: str + _xmlReport: Path + _testsuite: TestsuiteSummary + + def _CheckOptions(self) -> None: + # Parse all directive options or use default values + self._reportID = self._ParseStringOption("reportid") + + def _CheckConfiguration(self) -> None: + from sphinx_reports import ReportDomain + + # Check configuration fields and load necessary values + try: + allTestsuites: Dict[str, report_DictType] = self.config[f"{ReportDomain.name}_{self.configPrefix}_testsuites"] + except (KeyError, AttributeError) as ex: + raise ReportExtensionError(f"Configuration option '{ReportDomain.name}_{self.configPrefix}_testsuites' is not configured.") from ex + + try: + testsuiteConfiguration = allTestsuites[self._reportID] + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_testsuites: No configuration found for '{self._reportID}'.") from ex + + try: + self._xmlReport = Path(testsuiteConfiguration["xml_report"]) + except KeyError as ex: + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_testsuites:{self._reportID}.xml_report: Configuration is missing.") from ex + + if not self._xmlReport.exists(): + raise ReportExtensionError(f"conf.py: {ReportDomain.name}_{self.configPrefix}_testsuites:{self._reportID}.xml_report: Unittest report file '{self._xmlReport}' doesn't exist.") from FileNotFoundError(self._xmlReport) + + def _GenerateTestSummaryTable(self) -> nodes.table: + # Create a table and table header with 8 columns + table, tableGroup = self._PrepareTable( + identifier=self._reportID, + columns=[ + ("Testsuite / Testcase", None, 500), + ("Testcases", None, 100), + ("Skipped", None, 100), + ("Errored", None, 100), + ("Failed", None, 100), + ("Passed", None, 100), + ("Assertions", None, 100), + ("Runtime (HH:MM:SS.sss)", None, 100), + ], + classes=["report-unittest-table"] + ) + tableBody = nodes.tbody() + tableGroup += tableBody + + def sortedValues(d: Mapping[str, Testsuite]) -> Generator[Testsuite, None, None]: + for key in sorted(d.keys()): + yield d[key] + + def stateToSymbol(state: TestcaseState) -> str: + if state is TestcaseState.Passed: + return "✅" + elif state is TestcaseState.Unknown: + return "❓" + else: + return "❌" + + def timeformat(delta: timedelta) -> str: + # Compute by hand, because timedelta._to_microseconds is not officially documented + microseconds = (delta.days * 86_400 + delta.seconds) * 1_000_000 + delta.microseconds + milliseconds = (microseconds + 500) // 1000 + seconds = milliseconds // 1000 + minutes = seconds // 60 + hours = minutes // 60 + return f"{hours:02}:{minutes % 60:02}:{seconds % 60:02}.{milliseconds % 1000:03}" + + def renderRoot(tableBody: nodes.tbody, testsuite: TestsuiteSummary) -> None: + for ts in sortedValues(testsuite._testsuites): + renderTestsuite(tableBody, ts, 0) + + def renderTestsuite(tableBody: nodes.tbody, testsuite: Testsuite, level: int) -> None: + state = stateToSymbol(testsuite._state) + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"{'  '*level}{state}{testsuite.Name}")), + nodes.entry("", nodes.paragraph(text=f"{testsuite.Tests}")), + nodes.entry("", nodes.paragraph(text=f"{testsuite.Skipped}")), + nodes.entry("", nodes.paragraph(text=f"{testsuite.Errored}")), + nodes.entry("", nodes.paragraph(text=f"{testsuite.Failed}")), + nodes.entry("", nodes.paragraph(text=f"{testsuite.Passed}")), + nodes.entry("", nodes.paragraph(text=f"")), # {testsuite.Uncovered}")), + nodes.entry("", nodes.paragraph(text=f"{timeformat(testsuite.Time)}")), + classes=["report-unittest-table-row"], + ) + + for ts in sortedValues(testsuite._testsuites): + renderTestsuite(tableBody, ts, level + 1) + + for testcase in sortedValues(testsuite._testcases): + renderTestcase(tableBody, testcase, level + 1) + + def renderTestcase(tableBody: nodes.tbody, testcase: Testcase, level: int) -> None: + state = stateToSymbol(testcase._state) + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"{'  '*level}{state}{testcase.Name}")), + nodes.entry("", nodes.paragraph(text=f"")), # {testsuite.Expected}")), + nodes.entry("", nodes.paragraph(text=f"")), # {testsuite.Covered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {testsuite.Uncovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {testsuite.Uncovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {testsuite.Uncovered}")), + nodes.entry("", nodes.paragraph(text=f"{testcase.Assertions}")), + nodes.entry("", nodes.paragraph(text=f"{timeformat(testcase.Time)}")), + classes=["report-unittest-table-row"], + ) + + for test in sortedValues(testcase._tests): + state = stateToSymbol(test._state) + tableBody += nodes.row( + "", + nodes.entry("", nodes.paragraph(text=f"{'  '*(level+1)}{state}{test.Name}")), + nodes.entry("", nodes.paragraph(text=f"")), # {test.Expected}")), + nodes.entry("", nodes.paragraph(text=f"")), # {test.Covered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {test.Covered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {test.Covered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {test.Covered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {test.Uncovered}")), + nodes.entry("", nodes.paragraph(text=f"")), # {test.Coverage :.1%}")), + classes=["report-unittest-table-row"], + ) + + renderRoot(tableBody, self._testsuite) + + # # Add a summary row + # tableBody += nodes.row( + # "", + # nodes.entry("", nodes.paragraph(text=f"Overall ({self._testsuite.FileCount} files):")), + # nodes.entry("", nodes.paragraph(text=f"{self._testsuite.Expected}")), + # nodes.entry("", nodes.paragraph(text=f"{self._testsuite.Covered}")), + # nodes.entry("", nodes.paragraph(text=f"{self._testsuite.Uncovered}")), + # nodes.entry("", nodes.paragraph(text=f"{self._testsuite.Coverage:.1%}"), + # # classes=[self._ConvertToColor(self._coverage.coverage(), "class")] + # ), + # classes=["report-unittest-summary-row"] + # ) + + return table + +
+[docs] + def run(self) -> List[nodes.Node]: + self._CheckOptions() + self._CheckConfiguration() + + # Assemble a list of Python source files + analyzer = Analyzer(self._xmlReport) + self._testsuite = analyzer.Convert() + self._testsuite.Aggregate() + + container = nodes.container() + container += self._GenerateTestSummaryTable() + + return [container]
+
+ +
+ +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_report_static/sphinx-reports.e44b1595f1e09d5e109d001839ba3f42.css b/_report_static/sphinx-reports.e44b1595f1e09d5e109d001839ba3f42.css new file mode 100644 index 00000000..02468d35 --- /dev/null +++ b/_report_static/sphinx-reports.e44b1595f1e09d5e109d001839ba3f42.css @@ -0,0 +1,48 @@ +/* + * Disable odd/even coloring for docutils tables if it's a coverage table. + * Otherwise, the 'nth-child' rule will always override row colors indicating the coverage level. + */ +.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td { + background-color: unset; +} + +/* + * Coloring for 0..30, 30..50, 50..80, 80..90, 90.100% coverage + */ +/* very good */ +.report-cov-below100 { + background: rgba(0, 200, 82, .4); +} +/* good */ +.report-cov-below90 { + background: rgba(0, 200, 82, .2); +} +/* modest */ +.report-cov-below80 { + background: rgba(255, 145, 0, .2); +} +/* bad */ +.report-cov-below50 { + background: rgba(255, 82, 82, .2); +} +/* very bad */ +.report-cov-below30 { + background: rgba(101, 31, 255, .2); +} +/* internal error */ +.report-cov-error{ + background: rgba(255, 0, 0, .4); +} + +.report-dep-summary-row { + font-weight: bold; +} +.report-codecov-summary-row { + font-weight: bold; +} +.report-doccov-summary-row { + font-weight: bold; +} +.report-unittest-summary-row { + font-weight: bold; +} diff --git a/_sources/CodeCov/index.rst.txt b/_sources/CodeCov/index.rst.txt new file mode 100644 index 00000000..7e68661c --- /dev/null +++ b/_sources/CodeCov/index.rst.txt @@ -0,0 +1,139 @@ +.. _CODECOV: + +Code Coverage +############# + +:term:`Code Coverage` checks if a source code was used during execution. Usually, testcases are run by a testcase +execution framework like `pytest `__, which also offers to instrument the code for +code coverage collection using the ``pytest-cov`` plugin. For Python, coverage collection is usually based on +`Coverage.py `__, which supports statement and branch coverage collection. + + +.. _CODECOV/Quick: + +Quick Configuration +******************* + +See the :ref:`overview page ` on how to setup and enable the Sphinx extension in general. + +.. note:: This is a quick and minimal configuration. See below detailed explanations. + +1. Configure one or more coverage analysis reports in :file:`conf.py` by adding a new 'section' defining some + configuration variables. Each analysis report is identified by an ID, which is later referred to by the report + directive. Here, the ID is called ``src`` (dictionary key). Each analysis report needs 4 configuration entries: + + ``name`` + Name of the Python package[#PkgNameVsPkgDir]_. + + ``json_report`` + The code coverage report as JSON file as generated by *Coverage.py*. + + ``fail_below`` + An integer value in range 0..100, for when a code coverage is considered FAILED. + + ``levels`` + A dictionary of coverage limits, their description and CSS style classes. + + .. code-block:: Python + + # ============================================================================== + # Sphinx-reports - CodeCov + # ============================================================================== + report_codecov_packages = { + "src": { + "name": "myPackage", + "json_report": "../report/coverage/coverage.json", + "fail_below": 80, + "levels": { + 30: {"class": "report-cov-below30", "desc": "almost unused"}, + 50: {"class": "report-cov-below50", "desc": "poorly used"}, + 80: {"class": "report-cov-below80", "desc": "medium used"}, + 90: {"class": "report-cov-below90", "desc": "well well"}, + 100: {"class": "report-cov-below100", "desc": "excellent used"}, + "error": {"class": "report-cov-error", "desc": "internal error"}, + }, + } + } + +2. Add the :rst:dir:`code-coverage` directive into your Restructured Text (ReST) document. + + .. code-block:: ReST + + .. report:code-coverage:: + :packageid: src + + +.. _CODECOV/Example: + +Example Document +**************** + +The following ``coverage/index`` document is an example on how this documentation uses the :rst:dir:`code-coverage` +directive. The first file consists of three parts: At first, a headline; at second second a short introduction paragraph +and at third, the report generating directive. The second file shows how to integrate that document into the navigation +bar. + +.. admonition:: :file:`coverage/index.rst` + + .. code-block:: ReST + + Code Coverage Report + #################### + + Code coverage generated by `Coverage.py `__. + + .. report:code-coverage:: + :packageid: src + +.. admonition:: :file:`index.rst` + + .. code-block:: ReST + + .. toctree:: + :caption: References and Reports + :hidden: + + sphinx_reports/sphinx_reports + unittests/index + coverage/index + Doc. Coverage Report + Static Type Check Report ➚ + + .. toctree:: + :caption: Appendix + :hidden: + + +.. _CODECOV/Directives: + +Directives +********** + +.. rst:directive:: code-coverage + + Add a table summarizing the code coverage per Python source code file (packages and/or modules). + + .. rst:directive:option:: packageid + + An identifier referencing a dictionary entry in the configuration variable ``report_codecov_packages`` defined in + :file:`conf.py`. + + .. rst:directive:option:: legend + + Describes if and where to add a legend. Possible values: ``no_legend``, ``top``, ``bottom``, ``both``. + + +.. _CODECOV/Roles: + +Roles +***** + +*There are no roles defined.* + +--------------------------------- + +.. rubric:: Footnotes + +.. [#PkgNameVsPkgDir] Toplevel Python packages can reside in a directory not matching the package name. This is possible + because the toplevel package name is set in the package installation description. This is not good practice, but + possible and unfortunately widely used. E.g. ``src`` as directory name. See setuptools, etc. for more details. diff --git a/_sources/Dependency.rst.txt b/_sources/Dependency.rst.txt new file mode 100644 index 00000000..00a70d4c --- /dev/null +++ b/_sources/Dependency.rst.txt @@ -0,0 +1,261 @@ +.. _DEP: + +Dependencies +############ + +.. |img-pyTooling-lib-status| image:: https://img.shields.io/librariesio/release/pypi/sphinx-reports + :alt: Libraries.io status for latest release + :height: 22 + :target: https://libraries.io/github/pyTooling/sphinx-reports +.. |img-pyTooling-vul-status| image:: https://img.shields.io/snyk/vulnerabilities/github/pyTooling/sphinx-reports + :alt: Snyk Vulnerabilities for GitHub Repo + :height: 22 + :target: https://img.shields.io/snyk/vulnerabilities/github/pyTooling/sphinx-reports + ++------------------------------------------+------------------------------------------+ +| `Libraries.io `_ | Vulnerabilities Summary | ++==========================================+==========================================+ +| |img-pyTooling-lib-status| | |img-pyTooling-vul-status| | ++------------------------------------------+------------------------------------------+ + + +.. _DEP/package: + +sphinx-reports Package (Mandatory) +********************************** + +.. rubric:: Manually Installing Package Requirements + +Use the :file:`requirements.txt` file to install all dependencies via ``pip3`` or install the package directly from +PyPI (see :ref:`INSTALL`). + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. code-block:: bash + + pip3 install -U -r requirements.txt + + .. tab-item:: Windows + :sync: Windows + + .. code-block:: powershell + + pip install -U -r requirements.txt + + +.. rubric:: Dependency List + +When installed as ``pyTooling``: + ++-----------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++=================================================================+=============+===========================================================================================+========================================================================================================================================================+ +| `pyTooling `__ | ≥5.0.0 | `Apache License, 2.0 `__ | *None* | ++-----------------------------------------------------------------+-------------+-------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+ + +.. TODO:: document the dependency to + + * Sphinx + * docstr_coverage + * interrogate + + +.. _DEP/testing: + +Unit Testing (Optional) +*********************** + +Unit Testing / Coverage / Type Checking (Optional) +================================================== + +Additional Python packages needed for testing, code coverage collection and static type checking. These packages are +only needed for developers or on a CI server, thus sub-dependencies are not evaluated further. + + +.. rubric:: Manually Installing Test Requirements + +Use the :file:`tests/requirements.txt` file to install all dependencies via ``pip3``. The file will recursively install +the mandatory dependencies too. + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. code-block:: bash + + pip install -U -r tests/requirements.txt + + .. tab-item:: Windows + :sync: Windows + + .. code-block:: powershell + + pip3 install -U -r tests\requirements.txt + +.. rubric:: Dependency List - Unit Testing + ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++=====================================================================+=============+========================================================================================+======================+ +| `pytest `__ | ≥7.4.0 | `MIT `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `pytest-cov `__ | ≥4.1.0 | `MIT `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `Coverage `__ | ≥7.4 | `Apache License, 2.0 `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `mypy `__ | ≥1.8.0 | `MIT `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `typing-extensions `__ | ≥4.9.0 | `PSF-2.0 `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ +| `lxml `__ | ≥5.0 | `BSD 3-Clause `__ | *Not yet evaluated.* | ++---------------------------------------------------------------------+-------------+----------------------------------------------------------------------------------------+----------------------+ + + +.. _DEP/documentation: + +Sphinx Documentation (Optional) +******************************* + +Additional Python packages needed for documentation generation. These packages are only needed for developers or on a +CI server, thus sub-dependencies are not evaluated further. + + +.. rubric:: Manually Installing Documentation Requirements + +Use the :file:`doc/requirements.txt` file to install all dependencies via ``pip3``. The file will recursively install +the mandatory dependencies too. + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. code-block:: bash + + pip install -U -r doc/requirements.txt + + .. tab-item:: Windows + :sync: Windows + + .. code-block:: powershell + + pip3 install -U -r doc\requirements.txt + + +.. rubric:: Dependency List + ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++=================================================================================================+==============+==========================================================================================================+======================================================================================================================================================+ +| `pyTooling `__ | ≥5.0.0 | `Apache License, 2.0 `__ | *None* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `Sphinx `__ | ≥5.3.0 | `BSD 3-Clause `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `sphinxcontrib-mermaid `__ | ≥0.9.2 | `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_design `__ | ≥0.5.0 | `MIT `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `sphinx-copybutton `__ | ≥0.5.2 | `MIT `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `sphinx_autodoc_typehints `__ | ≥1.25.2 | `MIT `__ | *Not yet evaluated.* | ++-------------------------------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ + +.. TODO:: document the usage of + + * autoapi + * sphinxcontrib-mermaid + * theme v2? + * sphinx-design + + +.. _DEP/packaging: + +Packaging (Optional) +******************** + +Additional Python packages needed for installation package generation. These packages are only needed for developers or +on a CI server, thus sub-dependencies are not evaluated further. + + +.. rubric:: Manually Installing Packaging Requirements + +Use the :file:`build/requirements.txt` file to install all dependencies via ``pip3``. The file will recursively +install the mandatory dependencies too. + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. code-block:: bash + + pip install -U -r build/requirements.txt + + .. tab-item:: Windows + :sync: Windows + + .. code-block:: powershell + + pip3 install -U -r build\requirements.txt + + +.. rubric:: Dependency List + ++----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++============================================================================+==============+==========================================================================================================+======================================================================================================================================================+ +| `pyTooling `__ | ≥5.0.0 | `Apache License, 2.0 `__ | *None* | ++----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ +| `wheel `__ | ≥0.40.0 | `MIT `__ | *Not yet evaluated.* | ++----------------------------------------------------------------------------+--------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------+ + + +.. _DEP/publishing: + +Publishing (CI-Server only) +*************************** + +Additional Python packages needed for publishing the generated installation package to e.g, PyPI or any equivalent +services. These packages are only needed for maintainers or on a CI server, thus sub-dependencies are not evaluated +further. + + +.. rubric:: Manually Installing Publishing Requirements + +Use the :file:`dist/requirements.txt` file to install all dependencies via ``pip3``. The file will recursively +install the mandatory dependencies too. + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. code-block:: bash + + pip install -U -r dist/requirements.txt + + .. tab-item:: Windows + :sync: Windows + + .. code-block:: powershell + + pip3 install -U -r dist\requirements.txt + + +.. rubric:: Dependency List + ++----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+ +| **Package** | **Version** | **License** | **Dependencies** | ++==========================================================+==============+===========================================================================================+======================+ +| `wheel `__ | ≥0.40.0 | `MIT `__ | *Not yet evaluated.* | ++----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+ +| `Twine `__ | ≥4.0.2 | `Apache License, 2.0 `__ | *Not yet evaluated.* | ++----------------------------------------------------------+--------------+-------------------------------------------------------------------------------------------+----------------------+ diff --git a/_sources/Doc-License.rst.txt b/_sources/Doc-License.rst.txt new file mode 100644 index 00000000..ca0c2560 --- /dev/null +++ b/_sources/Doc-License.rst.txt @@ -0,0 +1,353 @@ +.. _DOCLICENSE: + +.. note:: This is a local copy of the `Creative Commons - Attribution 4.0 International (CC BY 4.0) `__. + +.. attention:: This **CC BY 4.0** license applies only to the **documentation** of this project. + + +Creative Commons Attribution 4.0 International +############################################## + +Creative Commons Corporation (“Creative Commons”) is not a law firm and does not +provide legal services or legal advice. Distribution of Creative Commons public +licenses does not create a lawyer-client or other relationship. Creative Commons +makes its licenses and related information available on an “as-is” basis. +Creative Commons gives no warranties regarding its licenses, any material +licensed under their terms and conditions, or any related information. Creative +Commons disclaims all liability for damages resulting from their use to the +fullest extent possible. + +.. topic:: Using Creative Commons Public Licenses + + Creative Commons public licenses provide a standard set of terms and conditions + that creators and other rights holders may use to share original works of + authorship and other material subject to copyright and certain other rights + specified in the public license below. The following considerations are for + informational purposes only, are not exhaustive, and do not form part of our + licenses. + + * **Considerations for licensors:** Our public licenses are intended for use + by those authorized to give the public permission to use material in ways + otherwise restricted by copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms and conditions + of the license they choose before applying it. Licensors should also secure + all rights necessary before applying our licenses so that the public can reuse + the material as expected. Licensors should clearly mark any material not + subject to the license. This includes other CC-licensed material, or material + used under an exception or limitation to copyright. + `More considerations for licensors `__. + + * **Considerations for the public:** By using one of our public licenses, a + licensor grants the public permission to use the licensed material under + specified terms and conditions. If the licensor’s permission is not necessary + for any reason–for example, because of any applicable exception or limitation + to copyright–then that use is not regulated by the license. Our licenses grant + only permissions under copyright and certain other rights that a licensor has + authority to grant. Use of the licensed material may still be restricted for + other reasons, including because others have copyright or other rights in the + material. A licensor may make special requests, such as asking that all + changes be marked or described. Although not required by our licenses, you are + encouraged to respect those requests where reasonable. + `More considerations for the public `__. + +:xlarge:`Creative Commons Attribution 4.0 International Public License` + +By exercising the Licensed Rights (defined below), You accept and agree to be +bound by the terms and conditions of this Creative Commons Attribution 4.0 +International Public License ("Public License"). To the extent this Public +License may be interpreted as a contract, You are granted the Licensed Rights +in consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the Licensor +receives from making the Licensed Material available under these terms and +conditions. + +Section 1 – Definitions. +======================== + +a. **Adapted Material** means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material and in + which the Licensed Material is translated, altered, arranged, transformed, or + otherwise modified in a manner requiring permission under the Copyright and + Similar Rights held by the Licensor. For purposes of this Public License, + where the Licensed Material is a musical work, performance, or sound + recording, Adapted Material is always produced where the Licensed Material + is synched in timed relation with a moving image. + +b. **Adapter's License** means the license You apply to Your Copyright and + Similar Rights in Your contributions to Adapted Material in accordance with + the terms and conditions of this Public License. + +c. **Copyright and Similar Rights** means copyright and/or similar rights + closely related to copyright including, without limitation, performance, + broadcast, sound recording, and Sui Generis Database Rights, without regard + to how the rights are labeled or categorized. For purposes of this Public + License, the rights specified in Section 2(b)(1)-(2) are not Copyright and + Similar Rights. + +d. **Effective Technological Measures** means those measures that, in the + absence of proper authority, may not be circumvented under laws fulfilling + obligations under Article 11 of the WIPO Copyright Treaty adopted on + December 20, 1996, and/or similar international agreements. + +e. **Exceptions and Limitations** means fair use, fair dealing, and/or any + other exception or limitation to Copyright and Similar Rights that applies to + Your use of the Licensed Material. + +f. **Licensed Material** means the artistic or literary work, database, or + other material to which the Licensor applied this Public License. + +g. **Licensed Rights** means the rights granted to You subject to the terms + and conditions of this Public License, which are limited to all Copyright and + Similar Rights that apply to Your use of the Licensed Material and that the + Licensor has authority to license. + +h. **Licensor** means the individual(s) or entity(ies) granting rights under + this Public License. + +i. **Share** means to provide material to the public by any means or process + that requires permission under the Licensed Rights, such as reproduction, + public display, public performance, distribution, dissemination, + communication, or importation, and to make material available to the public + including in ways that members of the public may access the material from a + place and at a time individually chosen by them. + +j. **Sui Generis Database Rights** means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of the + Council of 11 March 1996 on the legal protection of databases, as amended + and/or succeeded, as well as other essentially equivalent rights anywhere + in the world. + +k. **You** means the individual or entity exercising the Licensed Rights + under this Public License. **Your** has a corresponding meaning. + +Section 2 – Scope. +================== + +a. **License grant.** + + 1. Subject to the terms and conditions of this Public License, the Licensor + hereby grants You a worldwide, royalty-free, non-sublicensable, + non-exclusive, irrevocable license to exercise the Licensed Rights in the + Licensed Material to: + + A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + + 2. :underline:`Exceptions and Limitations.` For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public License does not + apply, and You do not need to comply with its terms and conditions. + + 3. :underline:`Term.` The term of this Public License is specified in Section 6(a). + + 4. :underline:`Media and formats`; :underline:`technical modifications allowed.` The Licensor + authorizes You to exercise the Licensed Rights in all media and formats + whether now known or hereafter created, and to make technical + modifications necessary to do so. The Licensor waives and/or agrees not to + assert any right or authority to forbid You from making technical + modifications necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective Technological + Measures. For purposes of this Public License, simply making modifications + authorized by this Section 2(a)(4) never produces Adapted Material. + + 5. :underline:`Downstream recipients.` + + A. :underline:`Offer from the Licensor – Licensed Material.` Every recipient of + the Licensed Material automatically receives an offer from the + Licensor to exercise the Licensed Rights under the terms and + conditions of this Public License. + + B. :underline:`No downstream restrictions.` You may not offer or impose any + additional or different terms or conditions on, or apply any Effective + Technological Measures to, the Licensed Material if doing so restricts + exercise of the Licensed Rights by any recipient of the Licensed + Material. + + 6. :underline:`No endorsement.` Nothing in this Public License constitutes or may + be construed as permission to assert or imply that You are, or that Your + use of the Licensed Material is, connected with, or sponsored, endorsed, + or granted official status by, the Licensor or others designated to + receive attribution as provided in Section 3(a)(1)(A)(i). + +b. **Other rights.** + + 1. Moral rights, such as the right of integrity, are not licensed under this + Public License, nor are publicity, privacy, and/or other similar + personality rights; however, to the extent possible, the Licensor waives + and/or agrees not to assert any such rights held by the Licensor to the + limited extent necessary to allow You to exercise the Licensed Rights, but + not otherwise. + + 2. Patent and trademark rights are not licensed under this Public License. + + 3. To the extent possible, the Licensor waives any right to collect royalties + from You for the exercise of the Licensed Rights, whether directly or + through a collecting society under any voluntary or waivable statutory or + compulsory licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + +Section 3 – License Conditions. +=============================== + +Your exercise of the Licensed Rights is expressly made subject to the following conditions. + +a. **Attribution.** + + 1. If You Share the Licensed Material (including in modified form), You must: + + A. retain the following if it is supplied by the Licensor with the + Licensed Material: + + i. identification of the creator(s) of the Licensed Material and any + others designated to receive attribution, in any reasonable manner + requested by the Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + + v. a URI or hyperlink to the Licensed Material to the extent reasonably + practicable; + + B. indicate if You modified the Licensed Material and retain an + indication of any previous modifications; and + + C. indicate the Licensed Material is licensed under this Public License, + and include the text of, or the URI or hyperlink to, this Public + License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner + based on the medium, means, and context in which You Share the Licensed + Material. For example, it may be reasonable to satisfy the conditions by + providing a URI or hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the information + required by Section 3(a)(1)(A) to the extent reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's License You apply + must not prevent recipients of the Adapted Material from complying with + this Public License. + +Section 4 – Sui Generis Database Rights. +======================================== + +Where the Licensed Rights include Sui Generis Database Rights that apply to Your +use of the Licensed Material: + +a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, + reuse, reproduce, and Share all or a substantial portion of the contents of + the database; + +b. if You include all or a substantial portion of the database contents in a + database in which You have Sui Generis Database Rights, then the database + in which You have Sui Generis Database Rights (but not its individual + contents) is Adapted Material; and + +c. You must comply with the conditions in Section 3(a) if You Share all or a + substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not replace +Your obligations under this Public License where the Licensed Rights include +other Copyright and Similar Rights. + +Section 5 – Disclaimer of Warranties and Limitation of Liability. +================================================================= + +a. **Unless otherwise separately undertaken by the Licensor, to the extent + possible, the Licensor offers the Licensed Material as-is and as-available, + and makes no representations or warranties of any kind concerning the + Licensed Material, whether express, implied, statutory, or other. This + includes, without limitation, warranties of title, merchantability, + fitness for a particular purpose, non-infringement, absence of latent or + other defects, accuracy, or the presence or absence of errors, whether or + not known or discoverable. Where disclaimers of warranties are not allowed + in full or in part, this disclaimer may not apply to You.** + +b. **To the extent possible, in no event will the Licensor be liable to You + on any legal theory (including, without limitation, negligence) or + otherwise for any direct, special, indirect, incidental, consequential, + punitive, exemplary, or other losses, costs, expenses, or damages arising + out of this Public License or use of the Licensed Material, even if the + Licensor has been advised of the possibility of such losses, costs, expenses, + or damages. Where a limitation of liability is not allowed in full or in + part, this limitation may not apply to You.** + +c. The disclaimer of warranties and limitation of liability provided above + shall be interpreted in a manner that, to the extent possible, most + closely approximates an absolute disclaimer and waiver of all liability. + +Section 6 – Term and Termination. +================================= + +a. This Public License applies for the term of the Copyright and Similar Rights + licensed here. However, if You fail to comply with this Public License, then + Your rights under this Public License terminate automatically. + +b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided it is cured + within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any right the + Licensor may have to seek remedies for Your violations of this Public License. + +c. For the avoidance of doubt, the Licensor may also offer the Licensed Material + under separate terms or conditions or stop distributing the Licensed Material + at any time; however, doing so will not terminate this Public License. + +d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +Section 7 – Other Terms and Conditions. +======================================= + +a. The Licensor shall not be bound by any additional or different terms or + conditions communicated by You unless expressly agreed. + +b. Any arrangements, understandings, or agreements regarding the Licensed + Material not stated herein are separate from and independent of the terms + and conditions of this Public License. + +Section 8 – Interpretation. +=========================== + +a. For the avoidance of doubt, this Public License does not, and shall not be + interpreted to, reduce, limit, restrict, or impose conditions on any use of + the Licensed Material that could lawfully be made without permission under + this Public License. + +b. To the extent possible, if any provision of this Public License is deemed + unenforceable, it shall be automatically reformed to the minimum extent + necessary to make it enforceable. If the provision cannot be reformed, it + shall be severed from this Public License without affecting the + enforceability of the remaining terms and conditions. + +c. No term or condition of this Public License will be waived and no failure to + comply consented to unless expressly agreed to by the Licensor. + +d. Nothing in this Public License constitutes or may be interpreted as a + limitation upon, or waiver of, any privileges and immunities that apply to + the Licensor or You, including from the legal processes of any jurisdiction + or authority. + +------------------ + +Creative Commons is not a party to its public licenses. Notwithstanding, +Creative Commons may elect to apply one of its public licenses to material it +publishes and in those instances will be considered the “Licensor.” Except for +the limited purpose of indicating that material is shared under a Creative +Commons public license or as otherwise permitted by the Creative Commons +policies published at `creativecommons.org/policies `__, +Creative Commons does not authorize the use of the trademark “Creative Commons” +or any other trademark or logo of Creative Commons without its prior written +consent including, without limitation, in connection with any unauthorized +modifications to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For the +avoidance of doubt, this paragraph does not form part of the public licenses. + +Creative Commons may be contacted at `creativecommons.org `__ diff --git a/_sources/DocCov/index.rst.txt b/_sources/DocCov/index.rst.txt new file mode 100644 index 00000000..d691cf29 --- /dev/null +++ b/_sources/DocCov/index.rst.txt @@ -0,0 +1,147 @@ +.. _DOCCOV: + +Documentation Coverage +###################### + +:term:`Documentation coverage` counts how many publicly accessible members (packages, modules, classes, methods, +functions, variables, ...) are documented using a Python :term:`doc-string`. Based on the count of possibly documented +public members and the actual number of non-empty *doc-strings*, a percentage of documentation coverage can be computed. + +Documentation coverage is a measure of code quality, which expresses how well documented (completeness or documentation, +but not necessarily quality/helpfulness of documentation) source code is. Well documented code helps to use and maintain +the existing code base. It also allows for automated documentation generation. + +Depending on quality standards, a coverage goal (or limit) like 90% might be defined, which considers an overall +documentation coverage less then 90% as FAILED. Such a limit might be enforced by maintainers or merge rules (via CI +jobs). This ensures new code introduced by merge requests (pull requests) cannot decrease the once achieved overall +project's code quality. + + +.. _DOCCOV/Quick: + +Quick Configuration +******************* + +See the :ref:`overview page ` on how to setup and enable the Sphinx extension in general. + +.. note:: This is a quick and minimal configuration. See below detailed explanations. + +1. Configure one or more Python packages for documentation coverage analysis in :file:`conf.py` by adding a new + 'section' defining some configuration variables. Each package is identified by an ID, which is later referred to by + the report directive. Here, the ID is called ``src`` (dictionary key). Each package needs 4 configuration entries: + + ``name`` + Name of the Python package[#PkgNameVsPkgDir]_. + + ``directory`` + The directory of the package to analyze. + + ``fail_below`` + An integer value in range 0..100, for when a documentation coverage is considered FAILED. + + ``levels`` + A dictionary of coverage limits, their description and CSS style classes. + + .. code-block:: Python + + # ============================================================================== + # Sphinx-reports - DocCov + # ============================================================================== + report_doccov_packages = { + "src": { + "name": "myPackage", + "directory": "../myPackage", + "fail_below": 80, + "levels": { + 30: {"class": "report-cov-below30", "desc": "almost undocumented"}, + 50: {"class": "report-cov-below50", "desc": "poorly documented"}, + 80: {"class": "report-cov-below80", "desc": "roughly documented"}, + 90: {"class": "report-cov-below90", "desc": "well documented"}, + 100: {"class": "report-cov-below100", "desc": "excellent documented"}, + "error": {"class": "report-cov-error", "desc": "internal error"}, + }, + } + } + +2. Add the :rst:dir:`doc-coverage` directive into your Restructured Text (ReST) document. + + .. code-block:: ReST + + .. report:doc-coverage:: + :packageid: src + + +.. _DOCCOV/Example: + +Example Document +**************** + +The following ``DocCoverage`` document is an example on how this documentation uses the :rst:dir:`doc-coverage` +directive. The first file consists of three parts: At first, a headline; at second second a short introduction paragraph +and at third, the report generating directive. The second file shows how to integrate that document into the navigation +bar. + +.. admonition:: :file:`DocCoverage.rst` + + .. code-block:: ReST + + Documentation Coverage Report + ############################# + + Documentation coverage generated by `docstr-coverage `__. + + .. report:doc-coverage:: + :packageid: src + +.. admonition:: :file:`index.rst` + + .. code-block:: ReST + + .. toctree:: + :caption: References and Reports + :hidden: + + sphinx_reports/sphinx_reports + unittests/index + coverage/index + Doc. Coverage Report + Static Type Check Report ➚ + + .. toctree:: + :caption: Appendix + :hidden: + + +.. _DOCCOV/Directives: + +Directives +********** + +.. rst:directive:: doc-coverage + + Add a table summarizing the documentation coverage per Python source code file (packages and/or modules). + + .. rst:directive:option:: packageid + + An identifier referencing a dictionary entry in the configuration variable ``report_doccov_packages`` defined in + :file:`conf.py`. + + .. rst:directive:option:: legend + + Describes if and where to add a legend. Possible values: ``no_legend``, ``top``, ``bottom``, ``both``. + + +.. _DOCCOV/Roles: + +Roles +***** + +*There are no roles defined.* + +--------------------------------- + +.. rubric:: Footnotes + +.. [#PkgNameVsPkgDir] Toplevel Python packages can reside in a directory not matching the package name. This is possible + because the toplevel package name is set in the package installation description. This is not good practice, but + possible and unfortunately widely used. E.g. ``src`` as directory name. See setuptools, etc. for more details. diff --git a/_sources/DocCoverage.rst.txt b/_sources/DocCoverage.rst.txt new file mode 100644 index 00000000..c1e75266 --- /dev/null +++ b/_sources/DocCoverage.rst.txt @@ -0,0 +1,7 @@ +Documentation Coverage +###################### + +Documentation coverage generated by `docstr-coverage `__. + +.. report:doc-coverage:: + :packageid: src diff --git a/_sources/Examples/FullyDocumented.rst.txt b/_sources/Examples/FullyDocumented.rst.txt new file mode 100644 index 00000000..1786ce0c --- /dev/null +++ b/_sources/Examples/FullyDocumented.rst.txt @@ -0,0 +1,7 @@ +Fully Undocumented +################## + +The following report shows a fully documented package. + +.. report:doc-coverage:: + :packageid: documented diff --git a/_sources/Examples/PartiallyDocumented.rst.txt b/_sources/Examples/PartiallyDocumented.rst.txt new file mode 100644 index 00000000..f23558fa --- /dev/null +++ b/_sources/Examples/PartiallyDocumented.rst.txt @@ -0,0 +1,7 @@ +Partially Documented +#################### + +The following report shows a partially documented package. + +.. report:doc-coverage:: + :packageid: partially diff --git a/_sources/Examples/Undocumented.rst.txt b/_sources/Examples/Undocumented.rst.txt new file mode 100644 index 00000000..65aba007 --- /dev/null +++ b/_sources/Examples/Undocumented.rst.txt @@ -0,0 +1,7 @@ +Undocumented +############ + +The following report shows an undocumented package. + +.. report:doc-coverage:: + :packageid: undocumented diff --git a/_sources/Glossary.rst.txt b/_sources/Glossary.rst.txt new file mode 100644 index 00000000..4d148519 --- /dev/null +++ b/_sources/Glossary.rst.txt @@ -0,0 +1,31 @@ +Glossary +######## + +.. glossary:: + + Branch Coverage + tbd + + Code Coverage + tbd + + doc-string + tbd + + .. code-block:: Python + + def myFunction(a: int, b: int) -> str: + """ + Converts 2 integers to a tuple represented as a string. + + :param a: First tuple element. + :param b: Second tuple element. + :returns: The tuple ``"(a, b)"`` as a string. + """ + return f"({a}, {b})" + + Documentation Coverage + tbd + + Statement Coverage + tbd diff --git a/_sources/Installation.rst.txt b/_sources/Installation.rst.txt new file mode 100644 index 00000000..cc0ab31f --- /dev/null +++ b/_sources/Installation.rst.txt @@ -0,0 +1,209 @@ +.. _INSTALL: + +Installation/Updates +#################### + +.. _INSTALL/pip: + +Using PIP to Install from PyPI +****************************** + +The following instruction are using PIP (Package Installer for Python) as a package manager and PyPI (Python Package +Index) as a source of Python packages. + + +.. _INSTALL/pip/install: + +Installing a Wheel Package from PyPI using PIP +============================================== + +Users of pyTooling can select if the want to install a basic variant of pyTooling. See :ref:`DEP` for more +details. + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. code-block:: bash + + # Basic sphinx-reports package + pip3 install sphinx_reports + + .. tab-item:: Windows + :sync: Windows + + .. code-block:: powershell + + # Basic sphinx-reports package + pip install sphinx_reports + +Developers can install further dependencies for documentation generation (``doc``) or running unit tests (``test``) or +just all (``all``) dependencies. + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. tab-set:: + + .. tab-item:: With Documentation Dependencies + :sync: Doc + + .. code-block:: bash + + # Install with dependencies to generate documentation + pip3 install sphinx_reports[doc] + + .. tab-item:: With Unit Testing Dependencies + :sync: Unit + + .. code-block:: bash + + # Install with dependencies to run unit tests + pip3 install sphinx_reports[test] + + .. tab-item:: All Developer Dependencies + :sync: All + + .. code-block:: bash + + # Install with all developer dependencies + pip install sphinx_reports[all] + + .. tab-item:: Windows + :sync: Windows + + .. tab-set:: + + .. tab-item:: With Documentation Dependencies + :sync: Doc + + .. code-block:: powershell + + # Install with dependencies to generate documentation + pip install sphinx_reports[doc] + + .. tab-item:: With Unit Testing Dependencies + :sync: Unit + + .. code-block:: powershell + + # Install with dependencies to run unit tests + pip install sphinx_reports[test] + + .. tab-item:: All Developer Dependencies + :sync: All + + .. code-block:: powershell + + # Install with all developer dependencies + pip install sphinx_reports[all] + + +.. _INSTALL/pip/update: + +Updating from PyPI using PIP +============================ + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. code-block:: bash + + pip install -U sphinx_reports + + .. tab-item:: Windows + :sync: Windows + + .. code-block:: powershell + + pip3 install -U sphinx_reports + + +.. _INSTALL/pip/uninstall: + +Uninstallation using PIP +======================== + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. code-block:: bash + + pip uninstall sphinx_reports + + .. tab-item:: Windows + :sync: Windows + + .. code-block:: powershell + + pip3 uninstall sphinx_reports + + +.. _INSTALL/setup: + +Using ``setup.py`` (legacy) +*************************** + +See sections above on how to use PIP. + +Installation using ``setup.py`` +=============================== + +.. code-block:: bash + + setup.py install + + +.. _INSTALL/building: + +Local Packaging and Installation via PIP +**************************************** + +For development and bug fixing it might be handy to create a local wheel package and also install it locally on the +development machine. The following instructions will create a local wheel package (``*.whl``) and then use PIP to +install it. As a user might have a sphinx-reports installation from PyPI, it's recommended to uninstall any previous +sphinx-reports packages. (This step is also needed if installing an updated local wheel file with same version number. PIP +will not detect a new version and thus not overwrite/reinstall the updated package contents.) + +Ensure :ref:`packaging requirements ` are installed. + +.. tab-set:: + + .. tab-item:: Linux/MacOS + :sync: Linux + + .. code-block:: bash + + cd + + # Package the code in a wheel (*.whl) + python -m build --wheel + + # Uninstall the old package + python -m pip uninstall -y sphinx_reports + + # Install from wheel + python -m pip install ./dist/sphinx_reports-1.0.0-py3-none-any.whl + + .. tab-item:: Windows + :sync: Windows + + .. code-block:: powershell + + cd + + # Package the code in a wheel (*.whl) + py -m build --wheel + + # Uninstall the old package + py -m pip uninstall -y sphinx_reports + + # Install from wheel + py -m pip install .\dist\sphinx_reports-1.0.0-py3-none-any.whl diff --git a/_sources/License.rst.txt b/_sources/License.rst.txt new file mode 100644 index 00000000..7df6024f --- /dev/null +++ b/_sources/License.rst.txt @@ -0,0 +1,136 @@ +.. Note:: This is a local copy of the `Apache License Version 2.0 `_. + +Apache License 2.0 +################## + +Version 2.0, January 2004 + +**TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION** + + +1. Definitions. +=============== +**"License"** shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +**"Licensor"** shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +**"Legal Entity"** shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that +entity. For the purposes of this definition, **"control"** means (i) the power, direct or indirect, to cause the direction or management of such entity, whether +by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +**"You"** (or **"Your"**) shall mean an individual or Legal Entity exercising permissions granted by this License. + +**"Source"** form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and +configuration files. + +**"Object"** form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object +code, generated documentation, and conversions to other media types. + +**"Work"** shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is +included in or attached to the work (an example is provided in the Appendix below). + +**"Derivative Works"** shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +**"Contribution"** shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative +Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to +submit on behalf of the copyright owner. For the purposes of this definition, **"submitted"** means any form of electronic, verbal, or written communication +sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue +tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is +conspicuously marked or otherwise designated in writing by the copyright owner as **"Not a Contribution."** + +**"Contributor"** shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. +============================== +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. +=========================== +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such +license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of +their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim +or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then +any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. +================== +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +* You must give any other recipients of the Work or Derivative Works a copy of this License; and +* You must cause any modified files to carry prominent notices stating that You changed the files; and +* You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source + form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +* If the Work includes a **"NOTICE"** text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the + attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the + following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the + Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE + file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, + alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise +complies with the conditions stated in this License. + +5. Submission of Contributions. +=============================== +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any +separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. +============== +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable +and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. +========================== +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, +MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and +assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. +=========================== +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or +consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages +for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been +advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. +============================================== +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other +liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole +responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +---------------------------------------------------------------------------------------------------------------------------------------------------------------- + +**Appendix: How to apply the Apache License to your work** + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying +information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or +class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +.. code-block:: none + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/_sources/Overview.rst.txt b/_sources/Overview.rst.txt new file mode 100644 index 00000000..9be0a210 --- /dev/null +++ b/_sources/Overview.rst.txt @@ -0,0 +1,70 @@ +.. _OVER: + +Overview +######## + + +.. _OVER/Setup: + +General Extension Setup +*********************** + +To use the *sphinx-reports* extension in your Sphinx documentation project, the ``sphinx_reports`` package must be +downloaded and :ref:`installed from PyPI ` in your environment. The installation page also shows, +how to :ref:`update ` the package from PyPI using ``pip``. + +At next, it's recommended to add ``sphinx_reports`` to your documentation's :file:`doc/requirements.txt`. As +modification to the package might bring braking changes, it's recommended to specify a package version (range/limit). + +See the following :file:`doc/requirements.txt` file as an example with commonly used extensions: + +.. code-block:: + + -r ../requirements.txt + + # Enforce latest version on ReadTheDocs + sphinx ~= 7 + docutils ~= 0.18 + + # ReadTheDocs Theme + sphinx_rtd_theme ~= 2.0 + + # Sphinx Extenstions + sphinxcontrib-mermaid ~= 0.9.2 + autoapi ~= 2.0.1 + sphinx_design ~= 0.5.0 + sphinx-copybutton ~= 0.5.2 + sphinx_autodoc_typehints ~= 1.25.2 + sphinx_reports ~= 1.0 + +Finally, the extension needs to be enabled in Sphinx's :file:`conf.py`, so the extension is loaded by Sphinx. + +The following code snippets shows a list of commonly enabled extensions, including ``sphinx_report``: + + .. code-block:: Python + + # ============================================================================== + # Extensions + # ============================================================================== + 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", + # SphinxContrib extensions + "sphinxcontrib.mermaid", + # Other extensions + "autoapi.sphinx", + "sphinx_design", + "sphinx_copybutton", + "sphinx_autodoc_typehints", + "sphinx_reports", + # User defined extensions + # ... + ] diff --git a/_sources/TODO.rst.txt b/_sources/TODO.rst.txt new file mode 100644 index 00000000..3144da04 --- /dev/null +++ b/_sources/TODO.rst.txt @@ -0,0 +1,4 @@ +TODOs +##### + +.. todolist:: diff --git a/_sources/Unittest/index.rst.txt b/_sources/Unittest/index.rst.txt new file mode 100644 index 00000000..23d54d2f --- /dev/null +++ b/_sources/Unittest/index.rst.txt @@ -0,0 +1,116 @@ +.. _UNITTEST: + +Unit Test Summary +################# + +🚧 This is a work-in-progress feature. 🚧 + +.. #:term:`Unittests` checks if a source code was used during execution. Usually, testcases are run by a testcase +execution framework like `pytest `__. + +.. rubric:: Supported report generators + +* `pytest `__ + + +.. _UNITTEST/Quick: + +Quick Configuration +******************* + +See the :ref:`overview page ` on how to setup and enable the Sphinx extension in general. + +.. note:: This is a quick and minimal configuration. See below detailed explanations. + +1. Configure one or more unitest summary reports in :file:`conf.py` by adding a new 'section' defining some + configuration variables. Each summary report is identified by an ID, which is later referred to by the report + directive. Here, the ID is called ``src`` (dictionary key). Each analysis report needs 2 configuration entries: + + ``name`` + Name of the Python package[#PkgNameVsPkgDir]_. + + ``xml_report`` + The code coverage report as JSON file as generated by *Coverage.py*. + + .. code-block:: Python + + # ============================================================================== + # Sphinx-reports - Unittest + # ============================================================================== + report_codecov_packages = { + "src": { + "name": "myPackage", + "xml_report": "../report/unit/unittest.xml", + } + } + +2. Add the :rst:dir:`unittest-summary` directive into your Restructured Text (ReST) document. + + .. code-block:: ReST + + .. report:unittest-summary:: + :reportid: src + + +.. _UNITTEST/Example: + +Example Document +**************** + +The following ``unittest/index`` document is an example on how this documentation uses the :rst:dir:`unittest-summary` +directive. The first file consists of three parts: At first, a headline; at second second a short introduction paragraph +and at third, the report generating directive. The second file shows how to integrate that document into the navigation +bar. + +.. admonition:: :file:`unittest/index.rst` + + .. code-block:: ReST + + Unittest Summary Report + ####################### + + Code coverage report generated with `pytest `__. + + .. report:unittest-summary:: + :reportid: src + +.. admonition:: :file:`index.rst` + + .. code-block:: ReST + + .. toctree:: + :caption: References and Reports + :hidden: + + sphinx_reports/sphinx_reports + unittests/index + coverage/index + Doc. Coverage Report + Static Type Check Report ➚ + + .. toctree:: + :caption: Appendix + :hidden: + + +.. _UNITTEST/Directives: + +Directives +********** + +.. rst:directive:: unittest-summary + + Add a table summarizing the unittest results. + + .. rst:directive:option:: reportid + + An identifier referencing a dictionary entry in the configuration variable ``report_unittest_testsuites`` defined + in :file:`conf.py`. + + +.. _UNITTEST/Roles: + +Roles +***** + +*There are no roles defined.* diff --git a/_sources/coverage/index.rst.txt b/_sources/coverage/index.rst.txt new file mode 100644 index 00000000..bad51b90 --- /dev/null +++ b/_sources/coverage/index.rst.txt @@ -0,0 +1,7 @@ +Code Coverage Report +#################### + +Code coverage report generated with `pytest `__ and `Coverage.py `__. + +.. report:code-coverage:: + :packageid: src diff --git a/_sources/genindex.rst.txt b/_sources/genindex.rst.txt new file mode 100644 index 00000000..c07da40d --- /dev/null +++ b/_sources/genindex.rst.txt @@ -0,0 +1,4 @@ +.. This file is a placeholder and will be replaced + +Index +##### diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 00000000..d536b42a --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,213 @@ +.. |img-sphinx-reports-github| image:: https://img.shields.io/badge/pyTooling-sphinx--reports-323131.svg?logo=github&longCache=true + :alt: Sourcecode on GitHub + :height: 22 + :target: https://github.com/pyTooling/sphinx-reports +.. |img-sphinx-reports-license| image:: https://img.shields.io/badge/Apache%20License,%202.0-bd0000.svg?longCache=true&label=license&logo=Apache&logoColor=D22128 + :alt: License + :height: 22 +.. |img-sphinx-reports-tag| image:: https://img.shields.io/github/v/tag/pyTooling/sphinx-reports?logo=GitHub&include_prereleases + :alt: GitHub tag (latest SemVer incl. pre-release + :height: 22 + :target: https://github.com/pyTooling/sphinx-reports/tags +.. |img-sphinx-reports-release| image:: https://img.shields.io/github/v/release/pyTooling/sphinx-reports?logo=GitHub&include_prereleases + :alt: GitHub release (latest SemVer incl. including pre-releases + :height: 22 + :target: https://github.com/pyTooling/sphinx-reports/releases/latest +.. |img-sphinx-reports-date| image:: https://img.shields.io/github/release-date/pyTooling/sphinx-reports?logo=GitHub + :alt: GitHub release date + :height: 22 + :target: https://github.com/pyTooling/sphinx-reports/releases +.. |img-sphinx-reports-lib-status| image:: https://img.shields.io/librariesio/release/pypi/sphinx-reports + :alt: Libraries.io status for latest release + :height: 22 + :target: https://libraries.io/github/pyTooling/sphinx-reports +.. |img-sphinx-reports-req-status| image:: https://img.shields.io/requires/github/pyTooling/sphinx-reports + :alt: Requires.io + :height: 22 + :target: https://requires.io/github/pyTooling/sphinx-reports/requirements/?branch=master +.. |img-sphinx-reports-travis| image:: https://img.shields.io/travis/com/pyTooling/sphinx-reports?logo=Travis + :alt: Travis - Build on 'master' + :height: 22 + :target: https://travis-ci.com/pyTooling/sphinx-reports +.. |img-sphinx-reports-pypi-tag| image:: https://img.shields.io/pypi/v/sphinx-reports?logo=PyPI + :alt: PyPI - Tag + :height: 22 + :target: https://pypi.org/project/sphinx-reports/ +.. |img-sphinx-reports-pypi-status| image:: https://img.shields.io/pypi/status/sphinx-reports?logo=PyPI + :alt: PyPI - Status + :height: 22 +.. |img-sphinx-reports-pypi-python| image:: https://img.shields.io/pypi/pyversions/sphinx-reports?logo=PyPI + :alt: PyPI - Python Version + :height: 22 +.. |img-sphinx-reports-lib-dep| image:: https://img.shields.io/librariesio/dependent-repos/pypi/sphinx-reports + :alt: Dependent repos (via libraries.io) + :height: 22 + :target: https://github.com/pyTooling/sphinx-reports/network/dependents +.. |img-sphinx-reports-codacy-quality| image:: https://img.shields.io/codacy/grade/9a89bbc1d2c04a699ea14abea75588c7?logo=codacy + :alt: Codacy - Quality + :height: 22 + :target: https://www.codacy.com/manual/pyTooling/sphinx-reports +.. |img-sphinx-reports-codacy-coverage| image:: https://img.shields.io/codacy/coverage/9a89bbc1d2c04a699ea14abea75588c7?logo=codacy + :alt: Codacy - Line Coverage + :height: 22 + :target: https://www.codacy.com/manual/pyTooling/sphinx-reports +.. |img-sphinx-reports-codecov-coverage| image:: https://codecov.io/gh/pyTooling/sphinx-reports/branch/master/graph/badge.svg + :alt: Codecov - Branch Coverage + :height: 22 + :target: https://codecov.io/gh/pyTooling/sphinx-reports +.. |img-sphinx-reports-lib-rank| image:: https://img.shields.io/librariesio/sourcerank/pypi/sphinx-reports + :alt: Libraries.io SourceRank + :height: 22 + :target: https://libraries.io/github/pyTooling/sphinx-reports/sourcerank +.. |img-sphinx-reports-rtd| image:: https://img.shields.io/readthedocs/sphinx-reports + :alt: Read the Docs + :height: 22 + :target: https://sphinx-reports.readthedocs.io/en/latest/ + +|img-sphinx-reports-github| |img-sphinx-reports-tag| |img-sphinx-reports-release| |img-sphinx-reports-date| |br| +|img-sphinx-reports-lib-status| |img-sphinx-reports-req-status| |img-sphinx-reports-lib-dep| |br| +|img-sphinx-reports-travis| |img-sphinx-reports-pypi-tag| |img-sphinx-reports-pypi-status| |img-sphinx-reports-pypi-python| |br| +|img-sphinx-reports-codacy-quality| |img-sphinx-reports-codacy-coverage| |img-sphinx-reports-codecov-coverage| |img-sphinx-reports-lib-rank| |br| +|img-sphinx-reports-rtd| |img-sphinx-reports-license| + + +sphinx-reports Documentation +############################ + +The Sphinx extension `sphinx_reports` offers a set of directives to integrate reports and summaries into the +documentation generated by Sphinx. + + +Supported Report Formats +************************ + +Supported format reports are: + +* ✅🚧 Unit Test summaries (by `pytest `__) + + * ✅ Summary page (displaying `unittest.xml`) + * 🚧 Show logging, output and error messages. + +* 🚧 Code coverage (by `Coverage.py `__) + + * ✅ Summary page + * 🚧 Highlighted source code + +* ✅ Documentation coverage (by `docstr_coverage `__ (or `interrogate`?)) +* 🚧 Dependencies (reading `requirements.txt` files) + + +Unit Test Summary +================= + +🚧 This is a work-in-progress feature. 🚧 + +:ref:`UNITTEST` + +.. todo:: index: Screen shot here and link to this unitest summary. + + +Code Coverage +============= + +:ref:`CODECOV` checks if a source code was used during execution. Usually, testcases are run by a testcase execution +framework like `pytest `__, which also offers to instrument the code for code +coverage collection using the ``pytest-cov`` plugin. For Python, coverage collection is usually based on +`Coverage.py `__, which supports statement and branch coverage collection. + +.. todo:: index: Screen shot here and link to this code coverage report. + + +Documentation coverage +====================== + +:ref:`DOCCOV` counts how many publicly accessible members are documented using a Python :term:`doc-string`. Based on the +count of possibly documented public members and the actual number of non-empty *doc-strings*, a percentage of +documentation coverage can be computed. + +.. todo:: index: Screen shot here and link to this documentations report. + + +Dependencies +============ + +🚧 This is a planned feature. 🚧 + + +Contributors +************ + +* `Patrick Lehmann `__ (Maintainer) +* `and more... `__ + + +License +******* + +.. only:: html + + This Python package (source code) is licensed under `Apache License 2.0 `__. |br| + The accompanying documentation is licensed under `Creative Commons - Attribution 4.0 (CC-BY 4.0) `__. + +.. only:: latex + + This Python package (source code) is licensed under **Apache License 2.0**. |br| + The accompanying documentation is licensed under **Creative Commons - Attribution 4.0 (CC-BY 4.0)**. + + +.. toctree:: + :caption: Overview + :hidden: + + Installation + Dependency + +.. raw:: latex + + \part{Main Documentation} + +.. toctree:: + :caption: Examples + :hidden: + + Examples/Undocumented + Examples/PartiallyDocumented + Examples/FullyDocumented + +.. toctree:: + :caption: Supported Reports + :hidden: + + Overview + Unittest/index + CodeCov/index + DocCov/index + +.. raw:: latex + + \part{References and Reports} + +.. toctree:: + :caption: References and Reports + :hidden: + + Python Class Reference + unittests/index + coverage/index + Doc. Coverage Report + Static Type Check Report ➚ + +.. raw:: latex + + \part{Appendix} + +.. toctree:: + :caption: Appendix + :hidden: + + License + Doc-License + Glossary + genindex + Python Module Index + TODO diff --git a/_sources/sphinx_reports/sphinx_reports.Adapter.Coverage.rst.txt b/_sources/sphinx_reports/sphinx_reports.Adapter.Coverage.rst.txt new file mode 100644 index 00000000..6c75f49a --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.Adapter.Coverage.rst.txt @@ -0,0 +1,59 @@ +.. # 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. + +=============================== +sphinx_reports.Adapter.Coverage +=============================== + +.. automodule:: sphinx_reports.Adapter.Coverage + + +.. currentmodule:: sphinx_reports.Adapter.Coverage + + +**Exceptions** + +- :py:exc:`CodeCoverageError`: + Extension error. + + + +**Classes** + +- :py:class:`Analyzer`: + Undocumented. + + + +--------------------- + +**Exceptions** + + + + +.. autoexception:: CodeCoverageError + + .. rubric:: Inheritance + .. inheritance-diagram:: CodeCoverageError + :parts: 1 + + +--------------------- + +**Classes** + + + + +.. autoclass:: Analyzer + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: Analyzer + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.Adapter.DocStrCoverage.rst.txt b/_sources/sphinx_reports/sphinx_reports.Adapter.DocStrCoverage.rst.txt new file mode 100644 index 00000000..3424a2aa --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.Adapter.DocStrCoverage.rst.txt @@ -0,0 +1,59 @@ +.. # 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. + +===================================== +sphinx_reports.Adapter.DocStrCoverage +===================================== + +.. automodule:: sphinx_reports.Adapter.DocStrCoverage + + +.. currentmodule:: sphinx_reports.Adapter.DocStrCoverage + + +**Exceptions** + +- :py:exc:`DocStrCoverageError`: + Extension error. + + + +**Classes** + +- :py:class:`Analyzer`: + Undocumented. + + + +--------------------- + +**Exceptions** + + + + +.. autoexception:: DocStrCoverageError + + .. rubric:: Inheritance + .. inheritance-diagram:: DocStrCoverageError + :parts: 1 + + +--------------------- + +**Classes** + + + + +.. autoclass:: Analyzer + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: Analyzer + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.Adapter.JUnit.rst.txt b/_sources/sphinx_reports/sphinx_reports.Adapter.JUnit.rst.txt new file mode 100644 index 00000000..93a82759 --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.Adapter.JUnit.rst.txt @@ -0,0 +1,59 @@ +.. # 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. + +============================ +sphinx_reports.Adapter.JUnit +============================ + +.. automodule:: sphinx_reports.Adapter.JUnit + + +.. currentmodule:: sphinx_reports.Adapter.JUnit + + +**Exceptions** + +- :py:exc:`UnittestError`: + Extension error. + + + +**Classes** + +- :py:class:`Analyzer`: + Undocumented. + + + +--------------------- + +**Exceptions** + + + + +.. autoexception:: UnittestError + + .. rubric:: Inheritance + .. inheritance-diagram:: UnittestError + :parts: 1 + + +--------------------- + +**Classes** + + + + +.. autoclass:: Analyzer + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: Analyzer + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.Adapter.rst.txt b/_sources/sphinx_reports/sphinx_reports.Adapter.rst.txt new file mode 100644 index 00000000..bf3fc00c --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.Adapter.rst.txt @@ -0,0 +1,22 @@ +.. # 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. + +====================== +sphinx_reports.Adapter +====================== + +.. automodule:: sphinx_reports.Adapter + + + +**Submodules** + +.. toctree:: + :maxdepth: 1 + + sphinx_reports.Adapter.Coverage + sphinx_reports.Adapter.DocStrCoverage + sphinx_reports.Adapter.JUnit + +.. currentmodule:: sphinx_reports.Adapter diff --git a/_sources/sphinx_reports/sphinx_reports.CodeCoverage.rst.txt b/_sources/sphinx_reports/sphinx_reports.CodeCoverage.rst.txt new file mode 100644 index 00000000..6426b8c7 --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.CodeCoverage.rst.txt @@ -0,0 +1,38 @@ +.. # 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. + +=========================== +sphinx_reports.CodeCoverage +=========================== + +.. automodule:: sphinx_reports.CodeCoverage + + +.. currentmodule:: sphinx_reports.CodeCoverage + + +**Classes** + +- :py:class:`CodeCoverage`: + This directive will be replaced by a table representing code coverage. + + + +--------------------- + +**Classes** + + + + +.. autoclass:: CodeCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: CodeCoverage + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.Common.rst.txt b/_sources/sphinx_reports/sphinx_reports.Common.rst.txt new file mode 100644 index 00000000..b99f8ea4 --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.Common.rst.txt @@ -0,0 +1,74 @@ +.. # 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. + +===================== +sphinx_reports.Common +===================== + +.. automodule:: sphinx_reports.Common + + +.. currentmodule:: sphinx_reports.Common + + +**Functions** + +- :py:func:`ReadResourceFile`: + Undocumented. + + + +**Exceptions** + +- :py:exc:`ReportExtensionError`: + Extension error. + + + +**Classes** + +- :py:class:`LegendPosition`: + Support for flags + + + +--------------------- + +**Functions** + + +.. autofunction:: ReadResourceFile + + +--------------------- + +**Exceptions** + + + + +.. autoexception:: ReportExtensionError + + .. rubric:: Inheritance + .. inheritance-diagram:: ReportExtensionError + :parts: 1 + + +--------------------- + +**Classes** + + + + +.. autoclass:: LegendPosition + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: LegendPosition + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.DataModel.CodeCoverage.rst.txt b/_sources/sphinx_reports/sphinx_reports.DataModel.CodeCoverage.rst.txt new file mode 100644 index 00000000..5bfd67d4 --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.DataModel.CodeCoverage.rst.txt @@ -0,0 +1,80 @@ +.. # 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. + +===================================== +sphinx_reports.DataModel.CodeCoverage +===================================== + +.. automodule:: sphinx_reports.DataModel.CodeCoverage + + +.. currentmodule:: sphinx_reports.DataModel.CodeCoverage + + +**Classes** + +- :py:class:`Coverage`: + Undocumented. + +- :py:class:`AggregatedCoverage`: + Undocumented. + +- :py:class:`ModuleCoverage`: + Undocumented. + +- :py:class:`PackageCoverage`: + Undocumented. + + + +--------------------- + +**Classes** + + + + +.. autoclass:: Coverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: Coverage + :parts: 1 + +.. autoclass:: AggregatedCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: AggregatedCoverage + :parts: 1 + +.. autoclass:: ModuleCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: ModuleCoverage + :parts: 1 + +.. autoclass:: PackageCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: PackageCoverage + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.DataModel.DocumentationCoverage.rst.txt b/_sources/sphinx_reports/sphinx_reports.DataModel.DocumentationCoverage.rst.txt new file mode 100644 index 00000000..1bdcf31a --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.DataModel.DocumentationCoverage.rst.txt @@ -0,0 +1,108 @@ +.. # 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. + +============================================== +sphinx_reports.DataModel.DocumentationCoverage +============================================== + +.. automodule:: sphinx_reports.DataModel.DocumentationCoverage + + +.. currentmodule:: sphinx_reports.DataModel.DocumentationCoverage + + +**Classes** + +- :py:class:`CoverageState`: + Support for flags + +- :py:class:`Coverage`: + Undocumented. + +- :py:class:`AggregatedCoverage`: + Undocumented. + +- :py:class:`ClassCoverage`: + Undocumented. + +- :py:class:`ModuleCoverage`: + Undocumented. + +- :py:class:`PackageCoverage`: + Undocumented. + + + +--------------------- + +**Classes** + + + + +.. autoclass:: CoverageState + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: CoverageState + :parts: 1 + +.. autoclass:: Coverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: Coverage + :parts: 1 + +.. autoclass:: AggregatedCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: AggregatedCoverage + :parts: 1 + +.. autoclass:: ClassCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: ClassCoverage + :parts: 1 + +.. autoclass:: ModuleCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: ModuleCoverage + :parts: 1 + +.. autoclass:: PackageCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: PackageCoverage + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.DataModel.Unittest.rst.txt b/_sources/sphinx_reports/sphinx_reports.DataModel.Unittest.rst.txt new file mode 100644 index 00000000..7164c92e --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.DataModel.Unittest.rst.txt @@ -0,0 +1,143 @@ +.. # 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. + +================================= +sphinx_reports.DataModel.Unittest +================================= + +.. automodule:: sphinx_reports.DataModel.Unittest + + +.. currentmodule:: sphinx_reports.DataModel.Unittest + + +**Exceptions** + +- :py:exc:`UnittestError`: + Extension error. + + + +**Classes** + +- :py:class:`TestcaseState`: + Support for flags + +- :py:class:`Base`: + Undocumented. + +- :py:class:`Test`: + Undocumented. + +- :py:class:`Testcase`: + Undocumented. + +- :py:class:`TestsuiteBase`: + Undocumented. + +- :py:class:`Testsuite`: + Undocumented. + +- :py:class:`TestsuiteSummary`: + Undocumented. + + + +--------------------- + +**Exceptions** + + + + +.. autoexception:: UnittestError + + .. rubric:: Inheritance + .. inheritance-diagram:: UnittestError + :parts: 1 + + +--------------------- + +**Classes** + + + + +.. autoclass:: TestcaseState + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: TestcaseState + :parts: 1 + +.. autoclass:: Base + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: Base + :parts: 1 + +.. autoclass:: Test + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: Test + :parts: 1 + +.. autoclass:: Testcase + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: Testcase + :parts: 1 + +.. autoclass:: TestsuiteBase + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: TestsuiteBase + :parts: 1 + +.. autoclass:: Testsuite + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: Testsuite + :parts: 1 + +.. autoclass:: TestsuiteSummary + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: TestsuiteSummary + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.DataModel.rst.txt b/_sources/sphinx_reports/sphinx_reports.DataModel.rst.txt new file mode 100644 index 00000000..270fe2fc --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.DataModel.rst.txt @@ -0,0 +1,22 @@ +.. # 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. + +======================== +sphinx_reports.DataModel +======================== + +.. automodule:: sphinx_reports.DataModel + + + +**Submodules** + +.. toctree:: + :maxdepth: 1 + + sphinx_reports.DataModel.CodeCoverage + sphinx_reports.DataModel.DocumentationCoverage + sphinx_reports.DataModel.Unittest + +.. currentmodule:: sphinx_reports.DataModel diff --git a/_sources/sphinx_reports/sphinx_reports.DocCoverage.rst.txt b/_sources/sphinx_reports/sphinx_reports.DocCoverage.rst.txt new file mode 100644 index 00000000..14f65692 --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.DocCoverage.rst.txt @@ -0,0 +1,52 @@ +.. # 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. + +========================== +sphinx_reports.DocCoverage +========================== + +.. automodule:: sphinx_reports.DocCoverage + + +.. currentmodule:: sphinx_reports.DocCoverage + + +**Classes** + +- :py:class:`DocCoverage`: + This directive will be replaced by a table representing documentation coverage. + +- :py:class:`DocStrCoverage`: + This directive will be replaced by a table representing documentation coverage. + + + +--------------------- + +**Classes** + + + + +.. autoclass:: DocCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: DocCoverage + :parts: 1 + +.. autoclass:: DocStrCoverage + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: DocStrCoverage + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.Sphinx.rst.txt b/_sources/sphinx_reports/sphinx_reports.Sphinx.rst.txt new file mode 100644 index 00000000..593e4742 --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.Sphinx.rst.txt @@ -0,0 +1,53 @@ +.. # 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. + +===================== +sphinx_reports.Sphinx +===================== + +.. automodule:: sphinx_reports.Sphinx + + +.. currentmodule:: sphinx_reports.Sphinx + + +**Functions** + +- :py:func:`strip`: + Undocumented. + + + +**Classes** + +- :py:class:`BaseDirective`: + Directive to describe a class, function or similar object. Not used + + + +--------------------- + +**Functions** + + +.. autofunction:: strip + + +--------------------- + +**Classes** + + + + +.. autoclass:: BaseDirective + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: BaseDirective + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.Unittest.rst.txt b/_sources/sphinx_reports/sphinx_reports.Unittest.rst.txt new file mode 100644 index 00000000..2f04b72d --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.Unittest.rst.txt @@ -0,0 +1,38 @@ +.. # 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. + +======================= +sphinx_reports.Unittest +======================= + +.. automodule:: sphinx_reports.Unittest + + +.. currentmodule:: sphinx_reports.Unittest + + +**Classes** + +- :py:class:`UnittestSummary`: + This directive will be replaced by a table representing unit test results. + + + +--------------------- + +**Classes** + + + + +.. autoclass:: UnittestSummary + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: UnittestSummary + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.rst.txt b/_sources/sphinx_reports/sphinx_reports.rst.txt new file mode 100644 index 00000000..3ca762bf --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.rst.txt @@ -0,0 +1,68 @@ +.. # 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. + +============== +sphinx_reports +============== + +.. automodule:: sphinx_reports + + + +**Submodules** + +.. toctree:: + :maxdepth: 1 + + sphinx_reports.Adapter + sphinx_reports.CodeCoverage + sphinx_reports.Common + sphinx_reports.DataModel + sphinx_reports.DocCoverage + sphinx_reports.Sphinx + sphinx_reports.Unittest + sphinx_reports.static + +.. currentmodule:: sphinx_reports + + +**Functions** + +- :py:func:`setup`: + Extension setup function registering the ``report`` domain in Sphinx. + + + +**Classes** + +- :py:class:`ReportDomain`: + A Sphinx extension providing a ``report`` domain to integrate reports and summaries into a Sphinx-based documentation. + + + +--------------------- + +**Functions** + + +.. autofunction:: setup + + +--------------------- + +**Classes** + + + + +.. autoclass:: ReportDomain + :members: + :private-members: + :special-members: + :inherited-members: + :exclude-members: __weakref__ + + .. rubric:: Inheritance + .. inheritance-diagram:: ReportDomain + :parts: 1 diff --git a/_sources/sphinx_reports/sphinx_reports.static.rst.txt b/_sources/sphinx_reports/sphinx_reports.static.rst.txt new file mode 100644 index 00000000..ef21bf15 --- /dev/null +++ b/_sources/sphinx_reports/sphinx_reports.static.rst.txt @@ -0,0 +1,12 @@ +.. # 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. + +===================== +sphinx_reports.static +===================== + +.. automodule:: sphinx_reports.static + + +.. currentmodule:: sphinx_reports.static diff --git a/_sources/typing/index.rst.txt b/_sources/typing/index.rst.txt new file mode 100644 index 00000000..3a22a255 --- /dev/null +++ b/_sources/typing/index.rst.txt @@ -0,0 +1,8 @@ +Static Type Checking Report +########################### + +*Placeholder for the Static Type Checking report generated with* ``mypy``. + +.. #raw:: html + +