Merge pull request 'tests: replace copyrighted lyrics with placeholder text' (#14) from synthetic-lyrics into main

Reviewed-on: #14
Reviewed-by: branderson <brad@branderson.io>
This commit is contained in:
2026-10-09 18:15:01 -07:00
4 changed files with 67 additions and 10 deletions
+36
View File
@@ -0,0 +1,36 @@
#TITLE:Placeholder Chart
#ARTIST:Test Artist
#LANGUAGE:English
#YEAR:2000
#CREATOR:songtrace tests
#GENRE:Test
#COVER:Test Artist - Placeholder Chart [CO].jpg
#MP3:Test Artist - Placeholder Chart.mp3
#VIDEO:Test Artist - Placeholder Chart.mp4
#BPM:217,98
#GAP:4880
#MEDLEYSTARTBEAT:113
#MEDLEYENDBEAT:240
: 0 3 16 ah
: 5 3 20 ah
: 11 3 23 la
: 17 3 16 la
: 22 28 15 ah
: 51 2 16 doo
: 54 31 16 ~
- 95
F 113 3 18 la
F 117 3 21 la
F 121 3 21 la
* 125 3 21 doo
* 129 12 19 ~
- 150
: 155 4 12 Na
R 160 4 0 na
G 165 4 0 na
: 170 6 14 la
- 190
: 194 3 16 La
: 198 3 18 la
* 202 10 20 ah
E
+21
View File
@@ -0,0 +1,21 @@
#TITLE:Café Placeholder
#ARTIST:Tést Artist
#LANGUAGE:English
#GENRE:Test
#YEAR:2000
#MP3:Tést Artist - Café Placeholder.mp3
#CREATOR:songtrace tests
#BPM:256
#GAP:49673
: 0 4 2 Doo
: 6 4 4 doo
: 12 8 5 laé
- 28 30
: 32 4 0 Na
: 38 4 -2 na
* 44 12 -9 ah
- 64
F 70 4 3 La
: 76 6 -5 la
: 84 10 -9 ~
E
+5 -5
View File
@@ -78,7 +78,7 @@ def test_syllabify():
assert syllabify("reminds", "English") == ["re", "minds"]
assert syllabify("a", "English") == ["a"]
assert syllabify("xyzzy", None) == ["xyzzy"]
assert syllabify("She's", "English") == ["She's"]
assert syllabify("It's", "English") == ["It's"]
def test_syllabify_preserves_word_characters():
@@ -96,12 +96,12 @@ def test_syllabify_language_without_pyphen_dict_is_not_mishandled_as_english():
def test_build_notes_basic_line():
times, f0, conf = flat_pitch()
rows = [
{"word": "She's", "start": 1.0, "end": 1.5, "score": 0.9, "line_index": 0},
{"word": "It's", "start": 1.0, "end": 1.5, "score": 0.9, "line_index": 0},
{"word": "got", "start": 1.6, "end": 2.0, "score": 0.9, "line_index": 0},
{"word": "Now", "start": 5.0, "end": 5.5, "score": 0.9, "line_index": 1},
]
notes, breaks, warnings = build_notes(rows, times, f0, conf, "English")
assert notes[0].text == "She's" # line-initial: no leading space
assert notes[0].text == "It's" # line-initial: no leading space
assert notes[1].text == " got" # mid-line: leading space
assert notes[2].text == "Now" # new line: no leading space
assert len(breaks) == 1 and 2.0 <= breaks[0] <= 5.0
@@ -278,7 +278,7 @@ def test_notes_stage_writes_json(tmp_path):
times, f0, conf = flat_pitch()
np.savez(work / "pitch.npz", times=times, f0=f0, conf=conf)
(work / "alignment.json").write_text(json.dumps([
{"word": "She's", "start": 1.0, "end": 1.5, "score": 0.9, "line_index": 0},
{"word": "It's", "start": 1.0, "end": 1.5, "score": 0.9, "line_index": 0},
{"word": "gone", "start": 3.0, "end": 3.5, "score": 0.9, "line_index": 1},
]))
ctx = Ctx(inp=SongInput(title="T", artist="A", lyrics_text="x", language="English"),
@@ -287,7 +287,7 @@ def test_notes_stage_writes_json(tmp_path):
assert stage.outputs(ctx) == [work / "notes_sec.json"]
stage.run(ctx)
data = json.loads((work / "notes_sec.json").read_text())
assert [n["text"] for n in data["notes"]] == ["She's", "gone"]
assert [n["text"] for n in data["notes"]] == ["It's", "gone"]
assert data["breaks"] == [2.25]
assert data["warnings"] == []
assert TimedNote(**data["notes"][0]).pitch == 0
+5 -5
View File
@@ -10,8 +10,8 @@ def load(name):
return (FIXTURES / name).read_text(encoding="utf-8", errors="replace")
def test_parse_headers_and_notes():
song = parse_ultrastar(load("sanctuary.txt"))
assert get_header(song, "artist") == "Utada Hikaru"
song = parse_ultrastar(load("chart_crlf.txt"))
assert get_header(song, "artist") == "Test Artist"
assert parse_bpm(get_header(song, "BPM")) == 217.98
first = song.body[0]
assert first == Note(kind=":", beat=0, length=3, pitch=16, text="ah")
@@ -19,16 +19,16 @@ def test_parse_headers_and_notes():
assert any(n.kind == "F" for n in song.body if isinstance(n, Note))
def test_note_text_keeps_leading_space():
song = parse_ultrastar(load("sanctuary.txt"))
song = parse_ultrastar(load("chart_crlf.txt"))
notes = [n for n in song.body if isinstance(n, Note)]
assert notes[1].text == " ah"
def test_negative_pitch():
song = parse_ultrastar(load("sweet_child.txt"))
song = parse_ultrastar(load("chart_latin1.txt"))
assert any(n.pitch == -9 for n in song.body if isinstance(n, Note))
def test_round_trip():
for name in ("sweet_child.txt", "sanctuary.txt"):
for name in ("chart_latin1.txt", "chart_crlf.txt"):
song = parse_ultrastar(load(name))
again = parse_ultrastar(serialize_ultrastar(song))
assert again == song