From 427073e52ab9a92c69f4e21fe399d30fd67e1147 Mon Sep 17 00:00:00 2001 From: Patrick Date: Mon, 6 Feb 2023 15:45:27 +0900 Subject: [PATCH] Simplify change validation --- soundchanger/change.py | 26 ++++++++++++-------------- tests/test_change.py | 4 ++++ tests/test_change_errors.py | 20 ++++++++++++-------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/soundchanger/change.py b/soundchanger/change.py index a63e8eb..9f1942c 100644 --- a/soundchanger/change.py +++ b/soundchanger/change.py @@ -1,7 +1,7 @@ import re -def apply(changes, strings, categories={}, apply=True, zero_characters=['∅']): +def apply(changes, strings, categories={}, ignore_errors=True, apply=True, zero_characters=['∅']): """Apply a sound change to a given string""" if not apply: @@ -15,7 +15,9 @@ def apply(changes, strings, categories={}, apply=True, zero_characters=['∅']): strings = [strings] for change in changes: - validate_change(change) + v = validate_change(change, ignore_errors=ignore_errors) + if v == False: + continue change = convert_change_to_regex(change, categories=categories, zero_characters=zero_characters) original, change_to, before, after = split_change(change) @@ -32,11 +34,13 @@ def apply(changes, strings, categories={}, apply=True, zero_characters=['∅']): return strings -def validate_change(change): - if change.count('>') != 1: - raise ValueError(f"Change {change} is not a valid sound change. (Missing character '>')") - if change.count('/') > 1: - raise ValueError(f"Change {change} is not a valid sound change. (More than one '/' character)") +def validate_change(change, ignore_errors): + valid = re.search(r'^[^>_/]+?>[^>_/]*?(:?/[^>_/]*?_+[^>_/]*)?$', change) + if ignore_errors: + return valid != None + if not valid: + raise ValueError(f"Change {change} is not a valid sound change.") + return True def convert_change_to_regex(change, categories, zero_characters): @@ -65,15 +69,9 @@ def split_change(change): environment = '_' # Collaplse multiple underscores - environment = re.sub('(_+)', '_', environment) - - if environment.count('_') != 1: - raise ValueError(f"Environment {environment} is not a valid environment. (Character '_' should exist exactly once)") + environment = re.sub('_+', '_', environment) original, change_to = change.split('>') before, after = environment.split('_') - if not original: - raise ValueError(f"Nothing to change from.") - return (original, change_to, before, after) \ No newline at end of file diff --git a/tests/test_change.py b/tests/test_change.py index 0399f24..b952311 100644 --- a/tests/test_change.py +++ b/tests/test_change.py @@ -88,3 +88,7 @@ def test_multiple_strings(): def test_multiple_changes_and_strings(): assert apply(['p>f', 'f>h/#_a'], ['pana', 'pune']) == ['hana', 'fune'] + +def test_applying_invalid_change(): + assert apply('', 'pana') == 'pana' + assert apply(['p>f', '>', 'f>h'], 'pana') == 'hana' diff --git a/tests/test_change_errors.py b/tests/test_change_errors.py index da6901c..c407eda 100644 --- a/tests/test_change_errors.py +++ b/tests/test_change_errors.py @@ -3,17 +3,21 @@ import re from soundchanger.change import apply def test_error_in_change(): - with pytest.raises(ValueError, match=re.escape("Change is not a valid sound change. (Missing character '>')")): - apply('', '') + # with pytest.raises(ValueError, match=re.escape("Change is not a valid sound change. (Missing character '>')")): + with pytest.raises(ValueError, match=re.escape("Change is not a valid sound change.")): + apply('', '', ignore_errors=False) def test_error_split(): - with pytest.raises(ValueError, match=re.escape("Change a>b/c/d is not a valid sound change. (More than one '/' character)")): - apply('a>b/c/d', '') + # with pytest.raises(ValueError, match=re.escape("Change a>b/c/d is not a valid sound change. (More than one '/' character)")): + with pytest.raises(ValueError, match=re.escape("Change a>b/c/d is not a valid sound change.")): + apply('a>b/c/d', '', ignore_errors=False) def test_error_in_environment(): - with pytest.raises(ValueError, match=re.escape("Environment c is not a valid environment. (Character '_' should exist exactly once)")): - apply('a>b/c', '') + # with pytest.raises(ValueError, match=re.escape("Environment c is not a valid environment. (Character '_' should exist exactly once)")): + with pytest.raises(ValueError, match=re.escape("Change a>b/c is not a valid sound change.")): + apply('a>b/c', '', ignore_errors=False) def test_no_change_from(): - with pytest.raises(ValueError, match=re.escape("Nothing to change from.")): - apply('>b', '') + # with pytest.raises(ValueError, match=re.escape("Nothing to change from.")): + with pytest.raises(ValueError, match=re.escape("Change >b is not a valid sound change.")): + apply('>b', '', ignore_errors=False)