Simplify change validation

This commit is contained in:
Patrick Elmer 2023-02-06 15:45:27 +09:00
parent a8928cf715
commit 427073e52a
3 changed files with 28 additions and 22 deletions

View File

@ -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)

View File

@ -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'

View File

@ -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)