Skip to content

Commit

Permalink
more coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
azuline committed Nov 2, 2023
1 parent 0eaf903 commit bf0f0b7
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 4 deletions.
11 changes: 8 additions & 3 deletions rose/rule_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,12 @@ def parse(cls, matcher: str, actions: list[str]) -> MetadataRule:
# pattern.
#
# NOTE: All rules are currently simple; boolean logics not yet implemented.
if all(a.tags == "matched" and a.match_pattern is None and not a.all for a in rule.actions):
if all(
(a.tags == "matched" or a.tags == rule.matcher.tags)
and a.match_pattern is None
and not a.all
for a in rule.actions
):
for a in rule.actions:
a.match_pattern = rule.matcher.pattern

Expand All @@ -213,7 +218,7 @@ def parse(cls, matcher: str, actions: list[str]) -> MetadataRule:
if single_valued_tags:
raise InvalidRuleError(
f"Single valued tags {', '.join(single_valued_tags)} cannot be modified by "
f"multi-value action {action}"
f"multi-value action {type(action.behavior).__name__}"
)

return rule
Expand Down Expand Up @@ -435,7 +440,7 @@ def parse_action(raw: str, action_number: int) -> MetadataAction:
"no parameters. Please remove this section.",
)
behavior = DeleteAction()
else:
else: # pragma: no cover
raise RoseError(f"Impossible: unknown action_kind {action_kind=}")

return MetadataAction(behavior=behavior, all=all_, tags=tags, match_pattern=pattern)
Expand Down
52 changes: 51 additions & 1 deletion rose/rule_parser_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ def test_rule_parse_action() -> None:
match_pattern="lala",
all=True,
)
assert parse_action("matched:^x::replace-all:lalala", 1) == MetadataAction(
behavior=ReplaceAction(replacement="lalala"),
tags="matched",
match_pattern="^x",
all=True,
)

assert parse_action("sed:lalala:hahaha", 1) == MetadataAction(
behavior=SedAction(src=re.compile("lalala"), dst="hahaha"),
Expand Down Expand Up @@ -212,6 +218,17 @@ def test_err(rule: str, err: str) -> None:
""", # noqa
)

test_err(
"tracktitler::delete",
"""\
Failed to parse action 1, invalid syntax:
tracktitler::delete
^
Invalid tag: must be one of matched, {tracktitle, year, tracknumber, discnumber, albumtitle, genre, label, releasetype, trackartist, albumartist}. (And if the value is matched, it must be alone.) The next character after a tag must be ':' or ','.
""", # noqa
)

test_err(
"tracktitle:haha:delete",
"""\
Expand Down Expand Up @@ -289,6 +306,17 @@ def test_err(rule: str, err: str) -> None:
""", # noqa
)

test_err(
"sed:invalid[",
"""\
Failed to parse action 1, invalid syntax:
sed:invalid[
^
Failed to compile the sed pattern regex: invalid pattern: unterminated character set at position 7
""", # noqa
)

test_err(
"sed:hihi:byebye:",
"""\
Expand Down Expand Up @@ -366,15 +394,37 @@ def test_rule_parsing_end_to_end() -> None:


def test_rule_parsing_multi_value_validation() -> None:
with pytest.raises(InvalidRuleError):
with pytest.raises(InvalidRuleError) as e:
MetadataRule.parse("tracktitle:h", ["split-all:x"])
assert (
str(e.value)
== "Single valued tags tracktitle cannot be modified by multi-value action SplitAction"
)
with pytest.raises(InvalidRuleError):
MetadataRule.parse("tracktitle:h", ["split:x"])
assert (
str(e.value)
== "Single valued tags tracktitle cannot be modified by multi-value action SplitAction"
)
with pytest.raises(InvalidRuleError):
MetadataRule.parse("genre:h", ["tracktitle::split:x"])
assert (
str(e.value)
== "Single valued tags tracktitle cannot be modified by multi-value action SplitAction"
)
with pytest.raises(InvalidRuleError):
MetadataRule.parse("genre:h", ["split:y", "tracktitle::split:x"])
assert (
str(e.value)
== "Single valued tags tracktitle cannot be modified by multi-value action SplitAction"
)


def test_rule_parsing_defaults() -> None:
rule = MetadataRule.parse("tracktitle:Track", ["replace:hi"])
assert rule.actions[0].match_pattern == "Track"
rule = MetadataRule.parse("tracktitle:Track", ["tracktitle::replace:hi"])
assert rule.actions[0].match_pattern == "Track"
rule = MetadataRule.parse("tracktitle:Track", ["tracktitle:Lack::replace:hi"])
assert rule.actions[0].match_pattern == "Lack"

Expand Down
1 change: 1 addition & 0 deletions rose/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ def execute_multi_value_action(
continue
if isinstance(action.behavior, SplitAction):
for newv in v.split(action.behavior.delimiter):
newv = newv.strip()
if newv:
rval.append(newv.strip())
elif newv2 := execute_single_action(action, v):
Expand Down
66 changes: 66 additions & 0 deletions rose/rules_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,16 @@ def test_sed_action(config: Config, source_dir: Path) -> None:
assert af.title == "Trip 1"


def test_sed_all(config: Config, source_dir: Path) -> None:
rule = MetadataRule(
matcher=MetadataMatcher(tags=["genre"], pattern="P"),
actions=[MetadataAction(behavior=SedAction(src=re.compile("^.*$"), dst="ip"))],
)
execute_metadata_rule(config, rule, False)
af = AudioTags.from_file(source_dir / "Test Release 1" / "01.m4a")
assert af.genre == ["ip", "ip"]


def test_split_action(config: Config, source_dir: Path) -> None:
rule = MetadataRule(
matcher=MetadataMatcher(tags=["label"], pattern="Cool"),
Expand All @@ -230,6 +240,16 @@ def test_split_action(config: Config, source_dir: Path) -> None:
assert af.label == ["A", "Label"]


def test_split_all_action(config: Config, source_dir: Path) -> None:
rule = MetadataRule(
matcher=MetadataMatcher(tags=["genre"], pattern="K-Pop"),
actions=[MetadataAction(behavior=SplitAction(delimiter="P"), all=True)],
)
execute_metadata_rule(config, rule, False)
af = AudioTags.from_file(source_dir / "Test Release 1" / "01.m4a")
assert af.genre == ["K-", "op", "op"]


def test_delete_action(config: Config, source_dir: Path) -> None:
rule = MetadataRule(
matcher=MetadataMatcher(tags=["genre"], pattern="^Pop"),
Expand All @@ -240,6 +260,16 @@ def test_delete_action(config: Config, source_dir: Path) -> None:
assert af.genre == ["K-Pop"]


def test_delete_all_action(config: Config, source_dir: Path) -> None:
rule = MetadataRule(
matcher=MetadataMatcher(tags=["genre"], pattern="^Pop"),
actions=[MetadataAction(behavior=DeleteAction(), match_pattern="^Pop", all=True)],
)
execute_metadata_rule(config, rule, False)
af = AudioTags.from_file(source_dir / "Test Release 1" / "01.m4a")
assert af.genre == []


def test_preserves_unmatched_multitags(config: Config, source_dir: Path) -> None:
rule = MetadataRule(
matcher=MetadataMatcher(tags=["genre"], pattern="^Pop$"),
Expand All @@ -252,6 +282,42 @@ def test_preserves_unmatched_multitags(config: Config, source_dir: Path) -> None
assert af.genre == ["K-Pop", "lalala"]


def test_action_on_different_tag(config: Config, source_dir: Path) -> None:
rule = MetadataRule(
matcher=MetadataMatcher(tags=["label"], pattern="A Cool Label"),
actions=[MetadataAction(behavior=ReplaceAction(replacement="hi"), tags=["genre"])],
)
execute_metadata_rule(config, rule, False)
af = AudioTags.from_file(source_dir / "Test Release 1" / "01.m4a")
assert af.genre == ["hi", "hi"]


def test_chained_action(config: Config, source_dir: Path) -> None:
rule = MetadataRule(
matcher=MetadataMatcher(tags=["label"], pattern="A Cool Label"),
actions=[
MetadataAction(behavior=ReplaceAction(replacement="Jennie"), tags=["label"]),
MetadataAction(
behavior=ReplaceAction(replacement="Jisoo"),
tags=["label"],
match_pattern="^Jennie$",
),
MetadataAction(
behavior=ReplaceAction(replacement="Rose"), tags=["label"], match_pattern="nomatch"
),
MetadataAction(
behavior=ReplaceAction(replacement="haha"),
tags=["genre"],
all=True,
),
],
)
execute_metadata_rule(config, rule, False)
af = AudioTags.from_file(source_dir / "Test Release 1" / "01.m4a")
assert af.label == ["Jisoo"]
assert af.genre == ["haha"]


@pytest.mark.timeout(2)
def test_confirmation_yes(monkeypatch: Any, config: Config, source_dir: Path) -> None:
rule = MetadataRule(
Expand Down

0 comments on commit bf0f0b7

Please sign in to comment.