diff --git a/test/tests/CMakeLists.txt b/test/tests/CMakeLists.txt index 0b678090..d45a2f34 100644 --- a/test/tests/CMakeLists.txt +++ b/test/tests/CMakeLists.txt @@ -500,6 +500,13 @@ add_test(NAME test_array_utils COMMAND test_array_utils.x) TIMEOUT 7200) endif() + add_test(NAME test_gvec_chartmap_converter_static + COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/test_gvec_chartmap_converter_static.py) + set_tests_properties(test_gvec_chartmap_converter_static PROPERTIES + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + LABELS "unit;python") + # Export tool for e2e test add_executable(export_boozer_chartmap_tool.x export_boozer_chartmap_tool.f90) target_link_libraries(export_boozer_chartmap_tool.x simple) @@ -770,7 +777,7 @@ if(SIMPLE_ENABLE_PYTHON_TOOLS) endif() ################################################## -# NCSX GC Cash–Karp COMPARISON TEST (VMEC vs MEISS) +# NCSX GC Cash-Karp COMPARISON TEST (VMEC vs MEISS) ################################################## add_test( diff --git a/test/tests/test_gvec_chartmap_converter_static.py b/test/tests/test_gvec_chartmap_converter_static.py new file mode 100644 index 00000000..9879c3e5 --- /dev/null +++ b/test/tests/test_gvec_chartmap_converter_static.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Static checks for the GVEC chartmap converter CLI contract.""" + +from __future__ import annotations + +import ast +from pathlib import Path + + +def fail(message: str) -> None: + raise SystemExit(f"FAIL: {message}") + + +def main() -> None: + repo = Path(__file__).resolve().parents[2] + script = repo / "tools" / "gvec_to_boozer_chartmap.py" + tree = ast.parse(script.read_text(encoding="utf-8")) + + for node in ast.walk(tree): + if not isinstance(node, ast.Call): + continue + if not isinstance(node.func, ast.Attribute): + continue + if node.func.attr != "add_argument": + continue + if not node.args or not isinstance(node.args[0], ast.Constant): + continue + if node.args[0].value != "--Bcov": + continue + for keyword in node.keywords: + if keyword.arg == "default" and isinstance(keyword.value, ast.Constant): + if keyword.value.value == "boozer-avg": + print("PASS: GVEC converter defaults to Boozer covariant averaging") + return + fail(f"--Bcov default is {keyword.value.value!r}") + fail("--Bcov has no default") + + fail("--Bcov argument not found") + + +if __name__ == "__main__": + main() diff --git a/test/tests/test_profiles.f90 b/test/tests/test_profiles.f90 index c94b4a51..e37132fe 100644 --- a/test/tests/test_profiles.f90 +++ b/test/tests/test_profiles.f90 @@ -288,7 +288,7 @@ subroutine test_peaked_profile_collision_rates(passed, nfail) end subroutine test_peaked_profile_collision_rates ! Flat radial profiles must reproduce the scalar (constant-coefficient) - ! collision operator bit-for-bit. This checks every intermediate value the + ! collision operator to round-off. This checks every intermediate value the ! stochastic step depends on: the interpolated coefficients at off-node s ! and the coleff outputs dpp/dhh/fpeff over the whole momentum range. subroutine test_flat_intermediate_values(passed, nfail) diff --git a/tools/gvec_to_boozer_chartmap.py b/tools/gvec_to_boozer_chartmap.py index 1eb0d3a0..9a7c8197 100644 --- a/tools/gvec_to_boozer_chartmap.py +++ b/tools/gvec_to_boozer_chartmap.py @@ -37,7 +37,7 @@ def main(): parser.add_argument("--ntheta", type=int, default=36) parser.add_argument("--nphi", type=int, default=81) parser.add_argument("--boozer-factor", type=int, default=1) - parser.add_argument("--Bcov", choices=["avg", "boozer-avg", "boozer-0"], default="avg", help="Method for computing B_theta and B_phi surface functions.") + parser.add_argument("--Bcov", choices=["avg", "boozer-avg", "boozer-0"], default="boozer-avg", help="Method for computing B_theta and B_phi surface functions.") parser.add_argument("--flip", choices=["pol", "tor"], default="tor", help="Flip the sign of the poloidal or toroidal angle (to obtain left-handed coordinates).") args = parser.parse_args()