From a0b72b12b4f946abab679fc2716e27c93a692bf2 Mon Sep 17 00:00:00 2001 From: Valery M Date: Tue, 21 May 2019 12:38:30 -0400 Subject: [PATCH] Error item links (#89) * Add failing test case * Handle raw keys --- CHANGES.md | 2 ++ src/arche/report.py | 14 +++++++++++--- src/arche/rules/json_schema.py | 1 - tests/test_arche.py | 30 +++++++++++++++++++++++++++++- tests/test_report.py | 10 ++++++++-- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 897c724..de02f08 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,8 @@ Note that the top-most release is changes in the unreleased master branch on Git ### Added ### Changed ### Fixed +- `Arche.glance()`, #88 +- Item links in Schema validation errors, #89 - Empty NAN bars on category graphs, #93 ### Removed diff --git a/src/arche/report.py b/src/arche/report.py index 174e489..34b97e0 100755 --- a/src/arche/report.py +++ b/src/arche/report.py @@ -1,5 +1,6 @@ from typing import Dict +from arche import SH_URL from arche.rules.result import Level, Outcome, Result from colorama import Fore, Style from IPython.display import display, HTML @@ -100,8 +101,15 @@ def sample_keys(keys: pd.Series, limit: int) -> str: sample = keys.sample(limit) else: sample = keys + + def url(x: str) -> str: + if SH_URL in x: + return f"{x.split('/')[-1]}" + key, number = x.rsplit("/", 1) + return f"{number}" + # make links only for Cloud data if keys.dtype == np.dtype("object") and "/" in keys.iloc[0]: - sample = [f"{k.split('/')[-1]}" for k in sample] - sample = ", ".join(sample) - return sample + sample = sample.apply(url) + + return ", ".join(sample) diff --git a/src/arche/rules/json_schema.py b/src/arche/rules/json_schema.py index 0afcadb..9b8555e 100755 --- a/src/arche/rules/json_schema.py +++ b/src/arche/rules/json_schema.py @@ -22,7 +22,6 @@ def validate(schema: Schema, raw_items: RawItems, fast: bool = False) -> Result: schema_result_message = ( f"{len(raw_items)} items were checked, {len(errors)} error(s)" ) - if errors: result.add_error(schema_result_message, errors=errors) else: diff --git a/tests/test_arche.py b/tests/test_arche.py index 3369b56..4ad552e 100755 --- a/tests/test_arche.py +++ b/tests/test_arche.py @@ -1,4 +1,4 @@ -from arche import arche +from arche import arche, SH_URL from arche.arche import Arche from arche.rules.result import Level from conftest import create_result @@ -245,6 +245,34 @@ def test_validate_with_json_schema(mocker, get_job_items, get_schema): assert a.report.results.get("JSON Schema Validation") == res +def test_validate_with_json_schema_fails(mocker, get_job_items, get_schema): + mocked_html = mocker.patch("arche.report.HTML", autospec=True) + key = f"112358/13/21" + url_base = f"{SH_URL}/{key}/item" + res = create_result( + "JSON Schema Validation", + { + Level.ERROR: [ + ( + "4 items were checked, 1 error(s)", + None, + {"'price' is a required property": {f"{key}/1"}}, + ) + ] + }, + ) + schema = {"type": "object", "required": ["price"]} + a = Arche("source", schema=schema) + a._source_items = get_job_items + a.validate_with_json_schema() + + assert len(a.report.results) == 1 + assert a.report.results.get("JSON Schema Validation") == res + mocked_html.assert_any_call( + f"1 items affected - 'price' is a required property: 1" + ) + + @pytest.mark.parametrize( "source, expected_message", [ diff --git a/tests/test_report.py b/tests/test_report.py index 5cec8de..40f1dcb 100755 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -131,16 +131,22 @@ def test_write_detailed_errors(mocker, errors, short, keys_limit, expected_messa ( pd.Series(f"{SH_URL}/112358/13/21/item/0"), 5, - [f"{SH_URL}/112358/13/21/item/5"], + pd.Series(f"{SH_URL}/112358/13/21/item/5"), f"0", ), ( pd.Series([f"{SH_URL}/112358/13/21/item/{i}" for i in range(20)]), 10, - [f"{SH_URL}/112358/13/21/item/5"], + pd.Series(f"{SH_URL}/112358/13/21/item/5"), f"5", ), (pd.Series([str(i) for i in range(5)]), 1, ["0"], "0"), + ( + pd.Series("112358/13/21/0"), + 1, + pd.Series("112358/13/21/0"), + f"0", + ), ], ) def test_sample_keys(mocker, keys, limit, sample_mock, expected_sample):