From 795296d71e844cec13d06078e9a7af40df6c1775 Mon Sep 17 00:00:00 2001 From: Onyx and Iris Date: Thu, 27 Feb 2025 19:52:37 +0000 Subject: [PATCH] move tox config into tox.ini add testenv:genbadges for generating test badges update README badges --- .gitignore | 13 +- .pre-commit-config.yaml | 7 + README.md | 8 +- pyproject.toml | 33 +- scripts.py | 11 +- tests/pre-commit.ps1 | 35 - tests/reports/assets/style.css | 319 ++++++++ .../{banana.svg => reports/badge-banana.svg} | 2 +- tests/{basic.svg => reports/badge-basic.svg} | 2 +- .../{potato.svg => reports/badge-potato.svg} | 2 +- tests/reports/html-banana.html | 770 ++++++++++++++++++ tests/reports/html-basic.html | 770 ++++++++++++++++++ tests/reports/html-potato.html | 770 ++++++++++++++++++ tox.ini | 42 + 14 files changed, 2702 insertions(+), 82 deletions(-) create mode 100644 .pre-commit-config.yaml delete mode 100644 tests/pre-commit.ps1 create mode 100644 tests/reports/assets/style.css rename tests/{banana.svg => reports/badge-banana.svg} (85%) rename tests/{basic.svg => reports/badge-basic.svg} (85%) rename tests/{potato.svg => reports/badge-potato.svg} (85%) create mode 100644 tests/reports/html-banana.html create mode 100644 tests/reports/html-basic.html create mode 100644 tests/reports/html-potato.html create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index a42d336..b88860a 100644 --- a/.gitignore +++ b/.gitignore @@ -128,10 +128,11 @@ dmypy.json # Pyre type checker .pyre/ -# test/config -quick.py -config.toml -vm-api.log -logging.json +# test reports +tests/reports/junit-*.xml -.vscode/ \ No newline at end of file +# test/config +test-*.py +config.toml + +.vscode/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0ee24b4 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace diff --git a/README.md b/README.md index 72cb6b2..6c65cb9 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/onyx-and-iris/voicemeeter-api-python/blob/dev/LICENSE) [![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) -![Tests Status](./tests/basic.svg?dummy=8484744) -![Tests Status](./tests/banana.svg?dummy=8484744) -![Tests Status](./tests/potato.svg?dummy=8484744) +[![Tests Status](./tests/reports/badge-basic.svg?dummy=8484744)](./tests/reports/junit-basic.html) +[![Tests Status](./tests/reports/badge-banana.svg?dummy=8484744)](./tests/reports/junit-banana.html) +[![Tests Status](./tests/reports/badge-potato.svg?dummy=8484744)](./tests/reports/junit-potato.html) # Python Wrapper for Voicemeeter API @@ -882,4 +882,4 @@ poetry poe test-potato - [Voicemeeter Remote C API](https://github.com/onyx-and-iris/Voicemeeter-SDK/blob/main/VoicemeeterRemoteAPI.pdf) -[Voicemeeter Remote Header]: https://github.com/onyx-and-iris/Voicemeeter-SDK/blob/main/VoicemeeterRemote.h \ No newline at end of file +[Voicemeeter Remote Header]: https://github.com/onyx-and-iris/Voicemeeter-SDK/blob/main/VoicemeeterRemote.h diff --git a/pyproject.toml b/pyproject.toml index 243eed0..9e716c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,39 +41,8 @@ test-basic.script = "scripts:test_basic" test-banana.script = "scripts:test_banana" test-potato.script = "scripts:test_potato" test-all.script = "scripts:test_all" +generate-badges.script = "scripts:generate_badges" -[tool.tox] -legacy_tox_ini = """ - [tox] - envlist = py310,py311,py312,py313 - - [testenv] - passenv = * - setenv = VIRTUALENV_DISCOVERY=pyenv - allowlist_externals = poetry - commands_pre = - poetry install --no-interaction --no-root - commands = - poetry run pytest tests - - [testenv:dsl] - setenv = VIRTUALENV_DISCOVERY=pyenv - allowlist_externals = poetry - deps = pyparsing - commands_pre = - poetry install --no-interaction --no-root --without dev - commands = - poetry run python examples/dsl - - [testenv:obs] - setenv = VIRTUALENV_DISCOVERY=pyenv - allowlist_externals = poetry - deps = obsws-python - commands_pre = - poetry install --no-interaction --no-root --without dev - commands = - poetry run python examples/obs -""" [tool.ruff] exclude = [ diff --git a/scripts.py b/scripts.py index e7c80a1..2fbe674 100644 --- a/scripts.py +++ b/scripts.py @@ -9,7 +9,7 @@ def ex_dsl(): def ex_callbacks(): - scriptpath = Path.cwd() / 'examples' / 'callbacks' / '.' + scriptpath = Path.cwd() / 'examples' / 'events' / 'callbacks' / '.' subprocess.run([sys.executable, str(scriptpath)]) @@ -33,7 +33,7 @@ def ex_obs(): def ex_observer(): - scriptpath = Path.cwd() / 'examples' / 'observer' / '.' + scriptpath = Path.cwd() / 'examples' / 'events' / 'observer' / '.' subprocess.run([sys.executable, str(scriptpath)]) @@ -53,3 +53,10 @@ def test_all(): steps = [test_basic, test_banana, test_potato] for step in steps: step() + + +def generate_badges(): + for kind in ['basic', 'banana', 'potato']: + subprocess.run( + ['tox', 'r', '-e', 'genbadges'], env=os.environ.copy() | {'KIND': kind} + ) diff --git a/tests/pre-commit.ps1 b/tests/pre-commit.ps1 deleted file mode 100644 index f637563..0000000 --- a/tests/pre-commit.ps1 +++ /dev/null @@ -1,35 +0,0 @@ -Function RunTests { - $coverage = "./tests/pytest_coverage.log" - $run_tests = "pytest --run-slow -v --capture=tee-sys --junitxml=./tests/.coverage.xml" - $match_pattern = "^=|^\s*$|^Running|^Using|^plugins|^collecting|^tests" - - if ( Test-Path $coverage ) { Clear-Content $coverage } - - ForEach ($line in $(Invoke-Expression $run_tests)) { - If ( $line -Match $match_pattern ) { - if ( $line -Match "^Running tests for kind \[(\w+)\]" ) { $kind = $Matches[1] } - $line | Tee-Object -FilePath $coverage -Append - } - } - Write-Output "$(Get-TimeStamp)" | Out-File $coverage -Append - - Invoke-Expression "genbadge tests -t 90 -i ./tests/.coverage.xml -o ./tests/$kind.svg" -} - -Function Get-TimeStamp { - - return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date) - -} - -if ($MyInvocation.InvocationName -ne ".") { - Invoke-Expression ".\.venv\Scripts\Activate.ps1" - - @("potato") | ForEach-Object { - $env:KIND = $_ - RunTests - } - - - Invoke-Expression "deactivate" -} diff --git a/tests/reports/assets/style.css b/tests/reports/assets/style.css new file mode 100644 index 0000000..561524c --- /dev/null +++ b/tests/reports/assets/style.css @@ -0,0 +1,319 @@ +body { + font-family: Helvetica, Arial, sans-serif; + font-size: 12px; + /* do not increase min-width as some may use split screens */ + min-width: 800px; + color: #999; +} + +h1 { + font-size: 24px; + color: black; +} + +h2 { + font-size: 16px; + color: black; +} + +p { + color: black; +} + +a { + color: #999; +} + +table { + border-collapse: collapse; +} + +/****************************** + * SUMMARY INFORMATION + ******************************/ +#environment td { + padding: 5px; + border: 1px solid #e6e6e6; + vertical-align: top; +} +#environment tr:nth-child(odd) { + background-color: #f6f6f6; +} +#environment ul { + margin: 0; + padding: 0 20px; +} + +/****************************** + * TEST RESULT COLORS + ******************************/ +span.passed, +.passed .col-result { + color: green; +} + +span.skipped, +span.xfailed, +span.rerun, +.skipped .col-result, +.xfailed .col-result, +.rerun .col-result { + color: orange; +} + +span.error, +span.failed, +span.xpassed, +.error .col-result, +.failed .col-result, +.xpassed .col-result { + color: red; +} + +.col-links__extra { + margin-right: 3px; +} + +/****************************** + * RESULTS TABLE + * + * 1. Table Layout + * 2. Extra + * 3. Sorting items + * + ******************************/ +/*------------------ + * 1. Table Layout + *------------------*/ +#results-table { + border: 1px solid #e6e6e6; + color: #999; + font-size: 12px; + width: 100%; +} +#results-table th, +#results-table td { + padding: 5px; + border: 1px solid #e6e6e6; + text-align: left; +} +#results-table th { + font-weight: bold; +} + +/*------------------ + * 2. Extra + *------------------*/ +.logwrapper { + max-height: 230px; + overflow-y: scroll; + background-color: #e6e6e6; +} +.logwrapper.expanded { + max-height: none; +} +.logwrapper.expanded .logexpander:after { + content: "collapse [-]"; +} +.logwrapper .logexpander { + z-index: 1; + position: sticky; + top: 10px; + width: max-content; + border: 1px solid; + border-radius: 3px; + padding: 5px 7px; + margin: 10px 0 10px calc(100% - 80px); + cursor: pointer; + background-color: #e6e6e6; +} +.logwrapper .logexpander:after { + content: "expand [+]"; +} +.logwrapper .logexpander:hover { + color: #000; + border-color: #000; +} +.logwrapper .log { + min-height: 40px; + position: relative; + top: -50px; + height: calc(100% + 50px); + border: 1px solid #e6e6e6; + color: black; + display: block; + font-family: "Courier New", Courier, monospace; + padding: 5px; + padding-right: 80px; + white-space: pre-wrap; +} + +div.media { + border: 1px solid #e6e6e6; + float: right; + height: 240px; + margin: 0 5px; + overflow: hidden; + width: 320px; +} + +.media-container { + display: grid; + grid-template-columns: 25px auto 25px; + align-items: center; + flex: 1 1; + overflow: hidden; + height: 200px; +} + +.media-container--fullscreen { + grid-template-columns: 0px auto 0px; +} + +.media-container__nav--right, +.media-container__nav--left { + text-align: center; + cursor: pointer; +} + +.media-container__viewport { + cursor: pointer; + text-align: center; + height: inherit; +} +.media-container__viewport img, +.media-container__viewport video { + object-fit: cover; + width: 100%; + max-height: 100%; +} + +.media__name, +.media__counter { + display: flex; + flex-direction: row; + justify-content: space-around; + flex: 0 0 25px; + align-items: center; +} + +.collapsible td:not(.col-links) { + cursor: pointer; +} +.collapsible td:not(.col-links):hover::after { + color: #bbb; + font-style: italic; + cursor: pointer; +} + +.col-result { + width: 130px; +} +.col-result:hover::after { + content: " (hide details)"; +} + +.col-result.collapsed:hover::after { + content: " (show details)"; +} + +#environment-header h2:hover::after { + content: " (hide details)"; + color: #bbb; + font-style: italic; + cursor: pointer; + font-size: 12px; +} + +#environment-header.collapsed h2:hover::after { + content: " (show details)"; + color: #bbb; + font-style: italic; + cursor: pointer; + font-size: 12px; +} + +/*------------------ + * 3. Sorting items + *------------------*/ +.sortable { + cursor: pointer; +} +.sortable.desc:after { + content: " "; + position: relative; + left: 5px; + bottom: -12.5px; + border: 10px solid #4caf50; + border-bottom: 0; + border-left-color: transparent; + border-right-color: transparent; +} +.sortable.asc:after { + content: " "; + position: relative; + left: 5px; + bottom: 12.5px; + border: 10px solid #4caf50; + border-top: 0; + border-left-color: transparent; + border-right-color: transparent; +} + +.hidden, .summary__reload__button.hidden { + display: none; +} + +.summary__data { + flex: 0 0 550px; +} +.summary__reload { + flex: 1 1; + display: flex; + justify-content: center; +} +.summary__reload__button { + flex: 0 0 300px; + display: flex; + color: white; + font-weight: bold; + background-color: #4caf50; + text-align: center; + justify-content: center; + align-items: center; + border-radius: 3px; + cursor: pointer; +} +.summary__reload__button:hover { + background-color: #46a049; +} +.summary__spacer { + flex: 0 0 550px; +} + +.controls { + display: flex; + justify-content: space-between; +} + +.filters, +.collapse { + display: flex; + align-items: center; +} +.filters button, +.collapse button { + color: #999; + border: none; + background: none; + cursor: pointer; + text-decoration: underline; +} +.filters button:hover, +.collapse button:hover { + color: #ccc; +} + +.filter__label { + margin-right: 10px; +} diff --git a/tests/banana.svg b/tests/reports/badge-banana.svg similarity index 85% rename from tests/banana.svg rename to tests/reports/badge-banana.svg index 1030af5..b057fee 100644 --- a/tests/banana.svg +++ b/tests/reports/badge-banana.svg @@ -1 +1 @@ -tests: 159tests159 \ No newline at end of file +tests: 158tests158 diff --git a/tests/basic.svg b/tests/reports/badge-basic.svg similarity index 85% rename from tests/basic.svg rename to tests/reports/badge-basic.svg index 5e18ec9..e4422bb 100644 --- a/tests/basic.svg +++ b/tests/reports/badge-basic.svg @@ -1 +1 @@ -tests: 116tests116 \ No newline at end of file +tests: 115tests115 diff --git a/tests/potato.svg b/tests/reports/badge-potato.svg similarity index 85% rename from tests/potato.svg rename to tests/reports/badge-potato.svg index a1fed37..c9c7e47 100644 --- a/tests/potato.svg +++ b/tests/reports/badge-potato.svg @@ -1 +1 @@ -tests: 184tests184 \ No newline at end of file +tests: 183tests183 diff --git a/tests/reports/html-banana.html b/tests/reports/html-banana.html new file mode 100644 index 0000000..72df7f3 --- /dev/null +++ b/tests/reports/html-banana.html @@ -0,0 +1,770 @@ + + + + + html-banana.html + + + +

html-banana.html

+

Report generated on 27-Feb-2025 at 19:25:20 by pytest-html + v4.1.1

+
+

Environment

+
+
+ + + + + +
+
+

Summary

+
+
+

158 tests took 00:00:01.

+

(Un)check the boxes to filter the results.

+
+ +
+
+
+
+ + 0 Failed, + + 158 Passed, + + 37 Skipped, + + 0 Expected failures, + + 0 Unexpected passes, + + 0 Errors, + + 0 Reruns +
+
+  /  +
+
+
+
+
+
+
+
+ + + + + + + + + +
ResultTestDurationLinks
+ + + diff --git a/tests/reports/html-basic.html b/tests/reports/html-basic.html new file mode 100644 index 0000000..7fad5bc --- /dev/null +++ b/tests/reports/html-basic.html @@ -0,0 +1,770 @@ + + + + + html-basic.html + + + +

html-basic.html

+

Report generated on 27-Feb-2025 at 19:25:04 by pytest-html + v4.1.1

+
+

Environment

+
+
+ + + + + +
+
+

Summary

+
+
+

115 tests took 00:00:01.

+

(Un)check the boxes to filter the results.

+
+ +
+
+
+
+ + 0 Failed, + + 115 Passed, + + 80 Skipped, + + 0 Expected failures, + + 0 Unexpected passes, + + 0 Errors, + + 0 Reruns +
+
+  /  +
+
+
+
+
+
+
+
+ + + + + + + + + +
ResultTestDurationLinks
+ + + diff --git a/tests/reports/html-potato.html b/tests/reports/html-potato.html new file mode 100644 index 0000000..caf0bab --- /dev/null +++ b/tests/reports/html-potato.html @@ -0,0 +1,770 @@ + + + + + html-potato.html + + + +

html-potato.html

+

Report generated on 27-Feb-2025 at 19:25:36 by pytest-html + v4.1.1

+
+

Environment

+
+
+ + + + + +
+
+

Summary

+
+
+

183 tests took 00:00:02.

+

(Un)check the boxes to filter the results.

+
+ +
+
+
+
+ + 0 Failed, + + 183 Passed, + + 12 Skipped, + + 0 Expected failures, + + 0 Unexpected passes, + + 0 Errors, + + 0 Reruns +
+
+  /  +
+
+
+
+
+
+
+
+ + + + + + + + + +
ResultTestDurationLinks
+ + + diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..1943d8f --- /dev/null +++ b/tox.ini @@ -0,0 +1,42 @@ +[tox] +envlist = py310,py311,py312,py313 + +[testenv] +passenv = * +setenv = VIRTUALENV_DISCOVERY=pyenv +allowlist_externals = poetry +commands_pre = + poetry install --no-interaction --no-root +commands = + poetry run pytest tests + +[testenv:genbadges] +passenv = * +setenv = VIRTUALENV_DISCOVERY=pyenv +allowlist_externals = poetry +deps = + genbadge[all] + pytest-html +commands_pre = + poetry install --no-interaction --no-root +commands = + poetry run pytest --capture=tee-sys --junitxml=./tests/reports/junit-${KIND}.xml --html=./tests/reports/html-${KIND}.html tests + poetry run genbadge tests -t 90 -i ./tests/reports/junit-${KIND}.xml -o ./tests/reports/badge-${KIND}.svg + +[testenv:dsl] +setenv = VIRTUALENV_DISCOVERY=pyenv +allowlist_externals = poetry +deps = pyparsing +commands_pre = + poetry install --no-interaction --no-root --without dev +commands = + poetry run python examples/dsl + +[testenv:obs] +setenv = VIRTUALENV_DISCOVERY=pyenv +allowlist_externals = poetry +deps = obsws-python +commands_pre = + poetry install --no-interaction --no-root --without dev +commands = + poetry run python examples/obs