From 92f6fa6363ed29099562c4a2cf63be059e2e02f3 Mon Sep 17 00:00:00 2001 From: Paul Madden Date: Thu, 19 Dec 2024 06:01:17 +0000 Subject: [PATCH] Fix & test --- src/uwtools/config/validator.py | 3 ++- src/uwtools/tests/config/test_validator.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/uwtools/config/validator.py b/src/uwtools/config/validator.py index 65db718fe..201197aae 100644 --- a/src/uwtools/config/validator.py +++ b/src/uwtools/config/validator.py @@ -71,7 +71,8 @@ def validate(schema: dict, desc: str, config: dict) -> bool: log_msg = "%s schema-validation error%s found in %s" log_method(log_msg, len(errors), "" if len(errors) == 1 else "s", desc) for error in errors: - log.error("Error at %s:", ".".join(str(k) for k in error.path)) + location = ".".join(str(k) for k in error.path) if error.path else "top level" + log.error("Error at %s:", location) log.error("%s%s", INDENT, error.message) return not bool(errors) diff --git a/src/uwtools/tests/config/test_validator.py b/src/uwtools/tests/config/test_validator.py index 8081847e2..7eb035749 100644 --- a/src/uwtools/tests/config/test_validator.py +++ b/src/uwtools/tests/config/test_validator.py @@ -5,6 +5,7 @@ import json import logging from pathlib import Path +from textwrap import dedent from typing import Any from unittest.mock import Mock, patch @@ -174,6 +175,25 @@ def test_validate_fail_bad_number_val(caplog, config, schema): assert any(x for x in caplog.records if "'string' is not of type 'number'" in x.message) +def test_validate_fail_top_level(caplog): + schema = { + "additionalProperties": False, + "properties": {"n": {"type": "integer"}}, + "required": ["n"], + "type": "object", + } + config = {"x": 42} + assert not validator.validate(schema=schema, desc="test", config=config) + expected = """ + 2 schema-validation errors found in test + Error at top level: + Additional properties are not allowed ('x' was unexpected) + Error at top level: + 'n' is a required property + """ + assert all(line in caplog.messages for line in dedent(expected).strip().split("\n")) + + def test_validate_internal_no(caplog, schema_file): with patch.object(validator, "resource_path", return_value=schema_file.parent): with raises(UWConfigError) as e: