diff --git a/tests/fixtures/chart_crlf.txt b/tests/fixtures/chart_crlf.txt new file mode 100644 index 0000000..731297a --- /dev/null +++ b/tests/fixtures/chart_crlf.txt @@ -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 diff --git a/tests/fixtures/chart_latin1.txt b/tests/fixtures/chart_latin1.txt new file mode 100644 index 0000000..19a0c03 --- /dev/null +++ b/tests/fixtures/chart_latin1.txt @@ -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 diff --git a/tests/fixtures/sanctuary.txt b/tests/fixtures/sanctuary.txt deleted file mode 100755 index b90e0c5..0000000 --- a/tests/fixtures/sanctuary.txt +++ /dev/null @@ -1,472 +0,0 @@ -#TITLE:Sanctuary -#ARTIST:Utada Hikaru -#LANGUAGE:English -#YEAR:2009 -#CREATOR:Subkei -#GENRE:J-Pop -#COVER:Utada Hikaru - Sanctuary [CO].jpg -#MP3:Utada Hikaru - Sanctuary.mp3 -#VIDEO:Utada Hikaru - Sanctuary.mp4 -#BPM:217,98 -#GAP:4880 -#MEDLEYSTARTBEAT:2471 -#MEDLEYENDBEAT:2990 -: 0 3 16 ah -: 5 3 20 ah -: 11 3 23 ah -: 17 3 16 ah -: 22 28 15 ah -: 51 2 16 ah -: 54 31 16 ~ -- 95 -F 113 3 18 wonk -F 117 3 21 uoy -F 121 3 21 naht -F 125 3 21 snoit -F 129 3 21 cef -F 133 3 18 fa -F 137 3 18 erom -F 144 2 18 deen -F 147 4 18 I -- 180 -: 425 3 16 In -: 429 3 21 you -: 433 2 20 ~ -: 436 4 16 ~ -: 441 2 18 and -: 445 4 20 I -: 451 4 18 ~ -- 459 -: 461 3 16 there's -: 465 3 16 a -: 469 5 20 new -: 475 4 23 land -: 481 4 16 ~ -: 487 27 15 ~ -: 515 4 16 ~ -: 521 17 16 ~ -: 539 1 18 ~ -: 541 3 20 ~ -- 547 -: 549 1 16 An -: 551 2 18 ~ -: 556 3 18 gels -: 560 4 18 in -: 565 7 20 flight -: 573 2 18 ~ -- 576 -F 578 2 18 wonk -F 581 3 21 uoy -F 585 3 21 naht -F 589 3 21 snoit -F 593 3 21 cef -F 597 3 18 fa -F 601 3 18 erom -F 608 2 18 deen -F 611 3 18 I -- 615 -: 617 1 16 My -: 620 1 21 sanc -: 624 2 20 tu -: 628 4 16 a -: 634 8 18 ry -- 646 -: 648 3 16 my -: 653 1 21 sanc -: 657 2 20 tu -: 661 3 16 a -: 665 4 16 ry -: 670 2 18 ~ -F 674 4 13 yeah -- 680 -: 682 2 16 Where -: 686 1 21 fears -: 689 1 20 ~ -: 691 5 16 ~ -: 697 1 18 and -* 701 4 20 lies -* 707 4 18 ~ -- 715 -: 717 3 16 melt -: 721 3 16 a -: 725 4 20 way -: 732 4 23 ~ -: 737 3 16 ~ -: 742 28 15 ~ -: 771 3 16 ~ -: 775 19 16 ~ -: 795 1 18 ~ -: 797 3 20 ~ -- 804 -: 806 1 16 Mu -: 808 2 18 ~ -: 812 3 18 sic -: 817 3 18 will -: 822 7 20 tie -: 830 2 18 ~ -- 833 -F 835 1 18 wonk -F 837 3 21 uoy -F 841 3 21 naht -F 845 3 21 snoit -F 849 3 21 cef -F 853 3 18 fa -F 857 3 18 erom -F 864 2 18 deen -F 867 3 18 I -- 871 -: 873 2 16 What's -: 877 1 21 left -: 881 1 20 of -: 884 3 16 me -: 888 1 16 ~ -: 890 7 18 ~ -- 903 -: 905 2 16 What's -: 909 1 21 left -: 913 1 20 of -: 916 3 16 me -: 921 2 16 ~ -: 925 3 18 ~ -: 933 24 13 now? -- 986 -: 1069 3 13 I -: 1074 6 16 watch -: 1082 3 16 you -: 1087 9 18 ~ -- 1102 -: 1105 3 18 fast -: 1109 3 20 ~ -* 1117 2 13 a -* 1122 5 16 sleep -: 1129 3 18 ~ -: 1133 15 16 ~ -- 1162 -: 1189 3 20 All -: 1193 6 21 ~ -: 1201 3 18 I -: 1205 6 20 ~ -: 1213 5 16 fear -: 1220 20 13 ~ -- 1246 -: 1249 2 11 means -: 1255 7 13 no -: 1266 5 18 thing -: 1273 41 20 ~ -- 1319 -: 1321 2 16 In -: 1325 2 21 you -: 1328 2 20 ~ -: 1332 3 16 ~ -: 1337 2 18 and -: 1341 4 20 I -: 1347 4 18 ~ -- 1355 -: 1357 3 16 there's -: 1361 3 16 a -* 1365 5 20 new -: 1371 4 23 land -: 1377 4 16 ~ -: 1383 27 15 ~ -: 1411 4 16 ~ -: 1417 17 16 ~ -: 1435 1 18 ~ -: 1437 3 20 ~ -- 1442 -: 1444 1 16 An -: 1446 2 18 ~ -: 1452 3 18 gels -: 1457 3 18 in -: 1462 6 20 flight -: 1469 2 18 ~ -- 1472 -F 1474 1 18 wonk -F 1476 3 21 uoy -F 1480 3 21 naht -F 1484 3 21 snoit -F 1488 3 21 cef -F 1492 3 18 fa -F 1496 3 18 erom -F 1503 2 18 deen -F 1506 3 18 I -- 1511 -: 1513 1 16 My -: 1516 1 21 sanc -: 1520 2 20 tu -: 1524 4 16 a -: 1530 8 18 ry -- 1541 -: 1543 3 16 my -: 1548 1 21 sanc -: 1552 2 20 tu -: 1556 3 16 a -: 1560 4 16 ry -: 1565 2 18 ~ -F 1570 3 13 yeah -- 1575 -: 1577 2 16 Where -* 1581 1 21 fears -* 1584 1 20 ~ -: 1586 5 16 ~ -: 1592 1 18 and -: 1596 4 20 lies -: 1602 4 18 ~ -- 1611 -: 1613 3 16 melt -: 1617 3 16 a -: 1621 4 20 way -: 1628 4 23 ~ -: 1633 3 16 ~ -: 1638 27 15 ~ -: 1666 4 16 ~ -: 1672 18 16 ~ -: 1691 1 18 ~ -: 1693 3 20 ~ -- 1699 -: 1701 1 16 Mu -: 1703 2 18 ~ -: 1707 3 18 sic -: 1712 3 18 will -: 1717 7 20 tie -: 1725 2 18 ~ -- 1728 -F 1730 2 18 wonk -F 1733 3 21 uoy -F 1737 3 21 naht -F 1741 3 21 snoit -F 1745 3 21 cef -F 1749 3 18 fa -F 1753 3 18 erom -F 1760 2 18 deen -F 1763 3 18 I -- 1767 -: 1769 2 16 What's -: 1773 1 21 left -: 1777 1 20 of -: 1780 3 16 me -: 1785 1 16 ~ -: 1787 7 18 ~ -- 1798 -: 1800 2 16 What's -: 1804 1 21 left -* 1808 1 20 of -* 1811 3 16 me -: 1815 1 16 ~ -: 1817 7 18 ~ -- 1831 -F 1834 2 21 snwod -F 1837 2 20 dna -F 1841 3 18 spu -F 1845 3 20 y -F 1849 3 20 nam -F 1853 3 18 os -- 1870 -: 1897 3 20 My -* 1901 2 20 heart's -: 1904 1 18 a -: 1906 3 20 bat -: 1910 3 21 tle -: 1914 5 21 ground -- 1926 -F 1929 2 16 snoit -F 1932 6 16 om -F 1941 2 18 e -F 1945 2 18 ~ -F 1948 2 18 eurt -F 1952 2 18 deen -F 1955 2 16 I -- 1971 -F 1987 3 18 wonk -F 1991 3 21 uoy -F 1995 3 21 naht -F 1999 3 21 snoit -F 2003 3 21 cef -F 2007 3 18 fa -F 2011 3 18 erom -F 2018 2 18 deen -F 2021 3 18 I -- 2038 -F 2059 2 16 snoit -F 2062 6 16 om -F 2070 3 18 e -F 2075 2 18 ~ -F 2078 2 18 eurt -F 2082 2 18 deen -F 2085 2 16 I -- 2116 -: 2219 3 13 You -: 2224 6 16 show -: 2232 3 16 me -: 2237 7 18 ~ -- 2252 -: 2255 3 18 how -: 2259 3 20 ~ -: 2267 2 13 to -: 2272 5 16 see -- 2282 -* 2284 3 13 That -* 2289 6 16 no -* 2297 3 16 thing -* 2302 5 18 ~ -- 2313 -: 2316 3 13 is -: 2321 3 16 whole -: 2325 2 15 ~ -: 2328 2 13 and -: 2331 1 13 ~ -: 2333 2 15 ~ -- 2338 -: 2340 3 20 no -: 2344 6 21 ~ -: 2352 3 18 ~ -: 2356 6 20 ~ -: 2364 5 16 thing -: 2371 12 13 ~ -- 2395 -: 2399 2 11 is -: 2403 9 13 bro -: 2416 5 18 ken -: 2423 41 20 ~ -- 2470 -: 2472 2 16 In -* 2476 2 21 you -* 2479 2 20 ~ -* 2483 3 16 ~ -: 2488 2 18 and -: 2492 4 20 I -: 2499 3 18 ~ -- 2506 -: 2508 3 16 There's -: 2512 3 16 a -: 2516 5 20 new -: 2522 4 23 land -: 2528 4 16 ~ -: 2534 27 15 ~ -: 2562 4 16 ~ -: 2568 17 16 ~ -: 2586 1 18 ~ -: 2588 3 20 ~ -- 2593 -: 2595 1 16 An -: 2597 2 18 ~ -: 2603 3 18 gels -: 2608 3 18 in -: 2613 6 20 flight -: 2620 2 18 ~ -- 2623 -F 2625 2 18 wonk -F 2628 3 21 uoy -F 2632 3 21 naht -F 2636 3 21 snoit -F 2640 3 21 cef -F 2644 3 18 fa -F 2648 3 18 erom -F 2655 2 18 deen -F 2658 2 18 I -- 2661 -: 2663 2 16 My -: 2668 1 21 sanc -: 2672 1 20 tu -: 2675 4 16 a -: 2681 7 18 ry -- 2693 -: 2695 3 16 My -: 2700 1 21 sanc -: 2704 2 20 tu -: 2708 3 16 a -: 2712 4 16 ry -: 2717 2 18 ~ -F 2721 4 13 yeah -- 2726 -: 2728 2 16 Where -: 2732 1 21 fears -: 2735 1 20 ~ -: 2737 5 16 ~ -: 2743 1 18 and -: 2747 4 20 lies -: 2754 3 18 ~ -- 2761 -: 2763 3 16 melt -: 2767 3 16 a -: 2771 4 20 way -: 2778 4 23 ~ -: 2783 4 16 ~ -: 2789 27 15 ~ -: 2817 4 16 ~ -: 2823 17 16 ~ -: 2841 1 18 ~ -: 2843 3 20 ~ -- 2849 -: 2851 1 16 Mu -: 2853 2 18 ~ -: 2857 3 18 sic -* 2862 3 18 will -* 2868 7 20 tie -: 2877 2 18 ~ -- 2880 -F 2882 1 18 wonk -F 2884 3 21 uoy -F 2888 3 21 naht -F 2892 3 21 snoit -F 2896 3 21 cef -F 2900 3 18 fa -F 2904 3 18 erom -F 2911 2 18 deen -F 2914 2 18 I -- 2917 -: 2919 2 16 What's -: 2923 1 21 left -: 2927 1 20 of -: 2930 3 16 me -: 2935 1 16 ~ -: 2937 7 18 ~ -- 2949 -: 2951 2 16 What's -: 2955 1 21 left -* 2959 1 20 of -* 2962 3 16 me -* 2967 2 16 ~ -: 2971 3 18 ~ -: 2979 12 13 now? -- 3005 -: 3026 2 11 uh -: 3029 2 13 ~ -: 3032 3 16 ~ -: 3036 8 15 ~ -: 3045 4 18 ~ -: 3051 4 16 ~ -: 3056 3 15 ~ -: 3060 3 13 ~ -- 3066 -: 3068 1 16 My -: 3070 2 18 ~ -: 3074 12 18 fears -- 3096 -: 3100 1 16 my -: 3102 2 18 ~ -: 3107 3 18 lies -: 3111 2 16 ~ -: 3114 1 13 ~ -- 3129 -* 3164 3 16 melt -* 3169 3 16 a -* 3173 4 20 way -* 3179 4 23 ~ -* 3185 3 16 ~ -* 3190 27 15 ~ -* 3218 3 16 ~ -* 3223 19 16 ~ -- 3248 -: 3250 4 18 ah -: 3256 126 20 ~ -- 3392 -F 3410 1 18 wonk -F 3412 3 21 uoy -F 3416 3 21 naht -F 3420 3 21 snoit -F 3424 3 21 cef -F 3428 3 18 fa -F 3432 3 18 erom -F 3439 2 18 deen -F 3442 3 18 I -E diff --git a/tests/fixtures/sweet_child.txt b/tests/fixtures/sweet_child.txt deleted file mode 100755 index 8133924..0000000 --- a/tests/fixtures/sweet_child.txt +++ /dev/null @@ -1,494 +0,0 @@ -#TITLE:Sweet Child O´Mine -#ARTIST:Guns N' Roses -#LANGUAGE:English -#GENRE:Rock -#YEAR:1987 -#MP3:Guns N' Roses - Sweet Child O´Mine.mp3 -#COVER:Guns N' Roses - Sweet Child O´Mine.jpg -#VIDEO:Guns N' Roses - Sweet Child O´Mine.webm -#CREATOR:sanicsip -#FIXER:Pacayaka -#BPM:256 -#GAP:49673 -#VIDEOGAP:0,3 -#START:13 -#MEDLEYSTARTBEAT:1564 -#MEDLEYENDBEAT:2057 -: 0 3 8 She's -: 5 2 8 got -: 8 1 8 a -: 13 2 6 smile -: 16 8 8 ~ -: 25 1 6 that -: 27 2 5 it -: 32 7 6 seems -: 41 1 8 to -: 45 1 5 me -: 47 5 4 ~ -: 53 1 3 ~ -- 55 -: 57 1 1 re -: 60 7 6 minds -: 69 2 5 me -: 73 1 1 of -: 76 1 1 child -: 79 9 6 ~ -: 91 5 6 hood -- 99 -: 101 3 6 mem -: 105 4 5 o -: 111 6 3 ries -: 118 1 1 ~ -- 120 -: 122 3 1 where -: 126 2 4 eve -: 129 5 6 ~ -: 135 2 5 ~ -: 138 1 1 ry -: 142 2 4 thing -: 145 4 6 ~ -: 150 2 5 was -: 154 1 1 as -: 158 2 5 fresh -: 161 4 6 ~ -: 166 3 5 as -: 171 1 1 the -: 174 5 6 bright -: 181 5 6 blue -: 190 8 6 sky -: 200 5 5 ~ -- 222 -: 258 4 8 Now -: 264 4 8 and -: 271 10 8 then -: 283 2 6 when -: 287 2 5 I -: 291 3 6 see -: 295 1 5 her -: 297 1 6 ~ -: 299 2 8 ~ -: 304 8 5 face -- 313 -: 315 3 6 she -: 319 3 8 ~ -: 324 3 6 takes -: 330 2 5 me -: 334 1 1 a -: 338 2 3 way -: 341 3 6 ~ -: 345 2 5 to -: 349 3 1 that -- 354 -: 356 3 6 spe -: 360 3 6 cial -: 364 2 8 ~ -: 369 1 6 place -: 371 4 5 ~ -: 377 2 5 and -: 381 1 6 if -: 384 2 5 I -: 389 3 6 stare -: 393 2 5 ~ -: 398 3 6 too -: 402 2 5 ~ -: 405 4 6 long -: 410 1 5 ~ -- 415 -: 417 1 1 I'd -: 420 1 1 prob -: 423 1 6 a -: 425 2 6 bly -: 429 5 6 break -: 436 5 6 down -: 442 2 6 and -* 445 1 8 ~ -: 450 7 6 cry -: 458 8 5 ~ -- 483 -: 512 3 6 Whoah -: 517 24 8 ~ -: 543 3 10 oh -: 548 2 8 ooh -: 551 3 8 whoah -: 555 1 6 ~ -: 559 3 6 sweet -: 563 1 5 ~ -: 567 2 5 child -: 570 3 6 ~ -: 575 1 6 o' -: 578 8 6 mine -: 587 12 5 ~ -- 616 -: 643 1 6 Whoah -: 645 11 8 ~ -: 659 7 6 oh -: 668 7 5 oh -: 677 2 5 oh -: 680 3 6 ~ -: 684 3 5 ~ -: 689 5 1 sweet -: 697 7 3 love -: 706 2 5 of -: 711 26 1 mine -- 771 -: 1041 5 8 She's -: 1048 6 8 got -: 1056 2 6 eyes -: 1059 7 8 ~ -: 1068 3 6 of -: 1073 1 5 the -: 1076 3 6 blu -: 1080 3 6 est -: 1084 2 8 ~ -: 1089 11 3 skies -: 1102 5 1 as -: 1110 5 6 if -: 1118 7 6 they -- 1128 -: 1130 4 6 thought -: 1135 2 5 of -: 1140 2 5 rain -: 1143 4 6 ~ -: 1148 4 5 ~ -- 1162 -* 1171 4 8 I -: 1176 2 5 hate -: 1179 3 6 ~ -: 1184 2 6 to -: 1187 3 5 ~ -: 1192 2 6 look -: 1196 10 6 in -: 1208 3 6 to -: 1213 6 5 those -: 1221 2 5 eyes -: 1224 7 6 ~ -: 1233 4 6 and -- 1239 -: 1241 4 6 see -: 1246 1 5 ~ -: 1249 3 1 an -: 1253 1 3 ounce -: 1256 5 6 ~ -: 1262 1 5 ~ -: 1265 2 1 of -: 1269 15 1 pain -- 1294 -: 1301 3 6 Her -: 1305 2 6 hair -: 1308 5 8 ~ -: 1314 2 8 re -: 1318 6 8 minds -: 1326 4 8 me -: 1331 3 6 of -: 1335 2 5 a -: 1339 6 6 warm -: 1347 2 6 safe -: 1350 3 8 ~ -: 1355 6 5 place -- 1362 -: 1364 6 1 where -: 1372 3 6 as -: 1376 2 5 ~ -: 1380 2 1 a -: 1384 2 5 child -: 1387 7 6 ~ -* 1395 3 8 I'd -: 1399 5 6 hide -: 1405 1 5 ~ -: 1408 11 1 ~ -- 1428 -: 1431 1 6 and -: 1433 2 8 ~ -: 1437 2 5 pray -: 1440 3 6 ~ -: 1445 3 6 for -: 1449 2 5 the -: 1453 7 6 thun -: 1461 6 6 der -- 1471 -: 1473 4 6 and -: 1478 2 5 the -: 1482 1 5 rain -: 1484 6 6 ~ -- 1491 -: 1493 1 5 to -: 1496 8 6 qui -: 1505 2 5 et -: 1509 2 1 ly -: 1514 1 5 pass -: 1516 6 6 ~ -* 1526 2 8 me -: 1529 5 6 by -: 1535 1 5 ~ -: 1538 10 1 ~ -- 1558 -: 1566 3 6 Whoah -: 1570 19 8 ~ -: 1591 3 10 oh -: 1595 3 8 ooh -: 1600 2 8 whoah -: 1603 1 6 ~ -: 1607 4 6 sweet -: 1612 1 5 ~ -: 1615 3 5 child -: 1620 2 6 ~ -: 1623 1 6 o' -: 1629 7 6 mine -: 1637 11 5 ~ -- 1658 -: 1675 2 12 Whoah -: 1678 20 13 ~ -: 1699 1 12 ~ -: 1701 5 13 ~ -: 1711 1 8 oh -: 1713 4 10 ~ -: 1719 7 8 oh -: 1727 3 8 oh -: 1731 3 10 ~ -: 1736 1 8 ~ -- 1737 -: 1739 3 6 Sweet -: 1743 1 5 ~ -: 1748 7 6 love -* 1757 2 8 of -: 1761 4 6 mine -: 1766 1 5 ~ -: 1770 16 1 ~ -- 1803 -* 1829 8 8 Oh -* 1842 4 10 oh -* 1850 4 13 oh -* 1858 2 13 oh -* 1861 5 15 ~ -* 1867 1 13 ~ -- 1869 -: 1871 3 13 Sweet -: 1875 1 10 ~ -: 1880 1 10 child -: 1882 3 13 ~ -: 1886 1 10 ~ -: 1888 2 8 o' -: 1892 2 8 mine -: 1895 5 10 ~ -: 1901 2 13 ~ -: 1905 2 10 ~ -: 1909 9 8 ~ -- 1924 -: 1926 2 8 Ooh -: 1929 4 10 ~ -: 1934 2 8 ~ -: 1937 3 5 ~ -: 1942 3 8 yeah -: 1951 1 8 yeah -: 1953 5 10 ~ -: 1959 2 8 ~ -- 1962 -: 1964 1 8 Ooh -: 1966 7 10 ~ -: 1974 7 8 ~ -: 1982 7 6 ~ -: 1991 2 5 ooh -: 1994 4 6 ~ -: 1999 1 5 ~ -- 2002 -: 2004 3 1 sweet -: 2010 9 3 love -: 2021 1 5 of -: 2025 1 3 mine -: 2027 1 5 ~ -: 2029 2 3 ~ -: 2032 25 1 ~ -- 2091 -: 3176 4 3 Where -: 3181 3 1 do -: 3185 2 -2 we -: 3190 8 -4 go? -- 3204 -: 3207 1 1 Where -: 3209 4 3 ~ -: 3214 2 1 do -: 3217 2 -2 we -: 3221 6 -4 go -: 3229 8 -6 now? -- 3239 -: 3241 3 3 Where -: 3245 3 1 do -: 3249 2 -2 we -: 3253 11 -4 go? -- 3274 -: 3282 1 -4 Ooh -: 3284 4 -2 ~ -: 3289 3 -4 oh -: 3293 3 -2 ~ -: 3297 3 -4 oh -: 3301 1 -6 ~ -- 3304 -: 3306 2 -2 Where -: 3309 2 -4 do -: 3312 2 -6 we -: 3316 4 -2 go -: 3321 4 -4 ~ -: 3326 6 -2 ~? -- 3342 -: 3355 5 -4 Oh -: 3362 7 -2 ~ -: 3370 2 -2 where -: 3373 2 -2 do -: 3376 2 -2 we -: 3380 3 -4 go -: 3384 1 -6 ~ -: 3387 13 -9 now? -- 3410 -: 3430 1 -6 Where -: 3433 1 -2 ~ -: 3435 2 -2 do -: 3439 2 1 we -: 3443 3 -4 go -: 3447 8 -2 ~? -- 3465 -: 3474 7 3 Ooh -: 3483 12 1 oh -: 3497 2 3 where -: 3500 2 1 do -: 3503 2 -2 we -: 3507 6 -4 go -: 3514 13 -6 now? -- 3537 -: 3558 1 -4 ay -: 3560 6 -2 ~ -: 3567 1 -4 ay -: 3569 5 -2 ~ -: 3575 1 -4 ay -: 3577 5 -2 ~ -: 3583 1 -4 ay -: 3585 5 -2 ~ -: 3591 1 -4 ay -: 3593 6 -2 ~ -: 3600 1 -4 ay -: 3602 5 -2 ~ -: 3608 2 -4 ay -: 3611 2 -2 ~ -- 3614 -: 3616 4 10 Oh -: 3623 1 13 where -: 3625 1 15 ~ -: 3627 3 13 do -: 3631 3 10 we -: 3635 6 8 go -: 3643 5 6 now? -- 3649 -* 3651 2 6 ah -* 3655 2 10 ah -* 3659 2 13 ah -* 3663 2 10 ah -* 3666 1 8 ah -* 3668 2 10 ah -* 3673 2 8 ah -* 3676 2 6 oh -* 3680 2 8 ah -* 3683 1 6 oh -- 3684 -: 3686 1 8 where -: 3688 2 10 ~ -: 3691 2 8 do -: 3695 2 6 we -: 3699 1 8 go -: 3701 11 10 ~? -- 3719 -* 3722 2 13 ah -* 3725 12 15 ~ -* 3738 8 13 ~ -* 3748 1 10 oh -* 3752 2 15 where -* 3756 2 13 do -* 3760 2 10 we -* 3764 7 8 go -* 3772 10 6 now? -- 3792 -: 3816 3 10 Where -: 3821 2 10 do -: 3825 2 13 we -: 3829 1 8 go -: 3831 4 10 ~ -: 3837 1 13 ~ -: 3841 2 10 ~ -: 3845 1 13 ~ -: 3849 1 10 ~ -: 3851 1 8 ~ -: 3853 1 10 ~ -: 3855 1 8 ~ -: 3857 1 10 ~ -: 3859 1 8 ~ -: 3861 2 10 ~ -: 3865 2 8 ~ -: 3868 3 6 ~ -: 3872 3 8 ~ -: 3876 2 6 ~? -- 3879 -: 3881 2 10 where -: 3884 1 8 do -: 3886 1 10 ~ -: 3888 2 10 we -: 3892 3 8 go -: 3897 1 6 ~ -: 3901 11 3 now? -- 3922 -: 3943 1 8 Where -: 3945 2 10 ~ -: 3949 2 8 do -: 3953 2 6 we -: 3957 2 10 go -: 3960 2 8 ~ -: 3963 10 10 ~? -- 3983 -: 3990 8 10 Whoah -: 4000 3 13 ~ -: 4004 3 10 ~ -: 4008 3 10 where -: 4012 3 13 do -: 4017 2 10 we -: 4021 5 8 go -: 4028 10 6 now? -- 4039 -* 4041 3 15 no -* 4046 3 13 no -* 4051 4 10 no -* 4057 3 9 no -* 4062 3 8 no -* 4067 3 6 no -* 4072 9 3 no -- 4087 -: 4090 3 8 sweet -: 4094 2 10 ~ -: 4101 3 8 child -: 4105 2 6 ~ -: 4109 7 3 ~ -- 4122 -: 4124 3 10 sweet -: 4128 1 8 ~ -: 4130 3 10 ~ -: 4137 3 10 child -: 4142 2 13 ~ -: 4145 4 10 ~ -: 4150 2 13 ~ -: 4153 4 10 ~ -: 4158 1 8 ~ -: 4160 2 10 ~ -: 4163 2 8 ~ -: 4166 3 6 ~ -: 4171 2 10 ~ -: 4175 2 13 ~ -: 4179 3 10 ~ -: 4183 4 13 ~ -: 4188 4 15 ~ -: 4194 2 13 ~ -: 4199 1 10 ~ -- 4200 -: 4202 1 8 o' -: 4204 2 10 ~ -: 4208 2 8 mine -: 4211 2 6 ~ -: 4214 46 3 ~ -: 4262 33 1 ~ -: 4297 49 3 ~ -E diff --git a/tests/test_align.py b/tests/test_align.py index c362510..f7016a3 100644 --- a/tests/test_align.py +++ b/tests/test_align.py @@ -7,7 +7,7 @@ from songtrace.lyrics import normalize_lyrics from songtrace.pipeline import Ctx, PipelineError, SongInput from songtrace.stages import align -LYRICS = "she's got a smile\nthat it seems to me" +LYRICS = "it's one two three\nfour five six seven eight" def make_ctx(tmp_path, lyrics=LYRICS, transcript=None): @@ -15,7 +15,7 @@ def make_ctx(tmp_path, lyrics=LYRICS, transcript=None): work.mkdir(exist_ok=True) if transcript is None: transcript = [{"start": 1.0, "end": 4.0, - "text": "she's got a smile that it seems to me"}] + "text": "it's one two three four five six seven eight"}] (work / "transcript.json").write_text(json.dumps(transcript)) inp = SongInput(title="T", artist="A", lyrics_text=lyrics) return Ctx(inp=inp, cfg=Config(whisper_url="u", device="cpu"), @@ -49,7 +49,7 @@ def check_invariants(rows, lyrics): def test_alignment_covers_all_words(tmp_path, monkeypatch): rows = run_align(tmp_path, monkeypatch) assert [r["word"] for r in rows] == \ - ["she's", "got", "a", "smile", "that", "it", "seems", "to", "me"] + ["it's", "one", "two", "three", "four", "five", "six", "seven", "eight"] assert rows[0]["line_index"] == 0 and rows[-1]["line_index"] == 1 starts = [r["start"] for r in rows] assert starts == sorted(starts) @@ -63,18 +63,18 @@ def test_mismatched_lyrics_fail(tmp_path, monkeypatch): def test_unalignable_word_interpolated(tmp_path, monkeypatch): - lyrics = "she's got ... smile\nthat it seems to me" + lyrics = "it's one ... three\nfour five six seven eight" rows = run_align(tmp_path, monkeypatch, lyrics) dots = next(r for r in rows if r["word"] == "...") assert dots["score"] == 0.0 - prev = next(r for r in rows if r["word"] == "got") - nxt = next(r for r in rows if r["word"] == "smile") + prev = next(r for r in rows if r["word"] == "one") + nxt = next(r for r in rows if r["word"] == "three") assert prev["end"] <= dots["start"] <= dots["end"] <= nxt["start"] + 1e-6 check_invariants(rows, lyrics) def test_leading_unalignable_word(tmp_path, monkeypatch): - lyrics = "... got a smile\nthat it seems to me" + lyrics = "... one two three\nfour five six seven eight" rows = run_align(tmp_path, monkeypatch, lyrics) assert rows[0]["word"] == "..." and rows[0]["score"] == 0.0 assert rows[0]["start"] >= 0.0 @@ -83,7 +83,7 @@ def test_leading_unalignable_word(tmp_path, monkeypatch): def test_trailing_unalignable_word(tmp_path, monkeypatch): - lyrics = "she's got a smile\nthat it seems to ..." + lyrics = "it's one two three\nfour five six seven ..." rows = run_align(tmp_path, monkeypatch, lyrics) assert rows[-1]["word"] == "..." and rows[-1]["score"] == 0.0 assert rows[-2]["end"] <= rows[-1]["start"] @@ -91,7 +91,7 @@ def test_trailing_unalignable_word(tmp_path, monkeypatch): def test_consecutive_unalignable_words(tmp_path, monkeypatch): - lyrics = "she's got ... ... smile\nthat it seems to me" + lyrics = "it's one ... ... three\nfour five six seven eight" rows = run_align(tmp_path, monkeypatch, lyrics) dots = [r for r in rows if r["word"] == "..."] assert len(dots) == 2 @@ -113,8 +113,8 @@ def test_all_words_unalignable_in_section(tmp_path, monkeypatch): def test_non_chronological_transcript(tmp_path, monkeypatch): - transcript = [{"start": 30.0, "end": 33.0, "text": "that it seems to me"}, - {"start": 1.0, "end": 4.0, "text": "she's got a smile"}] + transcript = [{"start": 30.0, "end": 33.0, "text": "four five six seven eight"}, + {"start": 1.0, "end": 4.0, "text": "it's one two three"}] rows = run_align(tmp_path, monkeypatch, transcript=transcript) check_invariants(rows, LYRICS) assert len({r["start"] for r in rows}) == len(rows) @@ -131,8 +131,8 @@ def test_inverted_section_does_not_collapse(tmp_path, monkeypatch): def test_words_split_across_sections(tmp_path, monkeypatch): - transcript = [{"start": 1.0, "end": 4.0, "text": "she's got a smile"}, - {"start": 30.0, "end": 33.0, "text": "that it seems to me"}] + transcript = [{"start": 1.0, "end": 4.0, "text": "it's one two three"}, + {"start": 30.0, "end": 33.0, "text": "four five six seven eight"}] rows = run_align(tmp_path, monkeypatch, transcript=transcript) check_invariants(rows, LYRICS) assert rows[3]["end"] <= 5.0 @@ -140,9 +140,9 @@ def test_words_split_across_sections(tmp_path, monkeypatch): def test_align_drops_lines_never_sung(tmp_path, monkeypatch): - lyrics = "she's got a smile\nthat it seems to me\nbut then it fades away" + lyrics = "it's one two three\nfour five six seven eight\nnine ten eleven twelve" transcript = [{"start": 1.0, "end": 4.0, - "text": "she's got a smile that it seems to me"}] + "text": "it's one two three four five six seven eight"}] rows = run_align(tmp_path, monkeypatch, lyrics, transcript) assert {r["line_index"] for r in rows} == {0, 1} meta = json.loads((tmp_path / "w" / "align_meta.json").read_text()) @@ -151,9 +151,9 @@ def test_align_drops_lines_never_sung(tmp_path, monkeypatch): def test_align_flags_missing_span_for_unmatched_singing(tmp_path, monkeypatch): - lyrics = "she's got a smile\nthat it seems to me" + lyrics = "it's one two three\nfour five six seven eight" transcript = [ - {"start": 1.0, "end": 4.0, "text": "she's got a smile that it seems to me"}, + {"start": 1.0, "end": 4.0, "text": "it's one two three four five six seven eight"}, {"start": 20.0, "end": 23.0, "text": "completely unrelated ad lib bridge"}, ] run_align(tmp_path, monkeypatch, lyrics, transcript) diff --git a/tests/test_lyrics.py b/tests/test_lyrics.py index b9f05dd..716c759 100644 --- a/tests/test_lyrics.py +++ b/tests/test_lyrics.py @@ -1,22 +1,22 @@ from songtrace.lyrics import normalize_lyrics, alignment_token RAW = """[Verse 1] -She's got a smile +It's one two three [Chorus] -Whoa, sweet child o' mine -Take me down to 7 streets +Whoa, la la o' la +Count me up to 7 times """ def test_normalize_strips_sections_and_blanks(): ref = normalize_lyrics(RAW) assert ref.lines == [ - ["She's", "got", "a", "smile"], - ["Whoa,", "sweet", "child", "o'", "mine"], - ["Take", "me", "down", "to", "7", "streets"], + ["It's", "one", "two", "three"], + ["Whoa,", "la", "la", "o'", "la"], + ["Count", "me", "up", "to", "7", "times"], ] - assert ref.words[0] == "She's" + assert ref.words[0] == "It's" assert ref.word_line_index == [0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2] diff --git a/tests/test_notes.py b/tests/test_notes.py index 1e556f4..1e33cc0 100644 --- a/tests/test_notes.py +++ b/tests/test_notes.py @@ -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 @@ -225,8 +225,8 @@ def test_build_notes_short_multisyllable_word_does_not_overlap(): def test_build_notes_never_overlaps_on_dense_input(): rng = np.random.default_rng(11) times = np.arange(0, 40.0, 0.01) - words = ["She's", "got", "a", "beautiful", "smile", "reminds", "me", - "everything", "I", "lost", "yesterday", "oh"] + words = ["We", "count", "a", "beautiful", "number", "reminds", "us", + "everything", "we", "listed", "yesterday", "oh"] for _ in range(8): f0 = 220.0 * 2 ** (rng.integers(0, 12, len(times)) // 3 / 12.0) conf = np.where(rng.random(len(times)) < 0.9, 0.9, 0.1) @@ -244,8 +244,8 @@ def test_build_notes_starts_are_non_decreasing(): times = np.arange(0, 12.0, 0.01) f0 = 220.0 * 2 ** (np.floor(times * 2) % 5 / 12.0) # stepped melody conf = np.where((times % 3.0) < 2.6, 0.9, 0.1) # unvoiced gaps - words = ["She's", "got", "a", "beautiful", "smile", "that", - "reminds", "me", "of", "everything", "I", "lost"] + words = ["We", "count", "a", "beautiful", "number", "that", + "reminds", "us", "of", "everything", "we", "list"] rows = [] for i, w in enumerate(words): dur = 0.8 if i % 3 else 0.07 # every third word sung very fast @@ -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 diff --git a/tests/test_transcribe.py b/tests/test_transcribe.py index 5947706..9ac80e4 100644 --- a/tests/test_transcribe.py +++ b/tests/test_transcribe.py @@ -18,35 +18,35 @@ def test_vocal_sections_keeps_contained_segment(): assert sections == [(0.0, 11.0)] def test_similarity_high_for_matching_lyrics(): - ref = normalize_lyrics("she's got a smile\nthat it seems to me") - segs = [seg(0, 2, "She's got a smile"), seg(2, 4, "that it seems to me")] + ref = normalize_lyrics("it's one two three\nfour five six seven eight") + segs = [seg(0, 2, "It's one two three"), seg(2, 4, "four five six seven eight")] assert lyrics_similarity(segs, ref) > 0.9 def test_similarity_low_for_wrong_lyrics(): ref = normalize_lyrics("completely different words here entirely") - segs = [seg(0, 2, "she's got a smile that it seems to me")] + segs = [seg(0, 2, "it's one two three four five six seven eight")] assert lyrics_similarity(segs, ref) < 0.4 def test_classify_lyrics_match_flags_extra_reference_line(): - ref = normalize_lyrics("she's got a smile\nthat it seems to me\nbut then it fades") - segs = [seg(1, 4, "she's got a smile that it seems to me")] + ref = normalize_lyrics("it's one two three\nfour five six seven eight\nnine ten eleven") + segs = [seg(1, 4, "it's one two three four five six seven eight")] dropped, missing = classify_lyrics_match(segs, ref) assert dropped == [2] assert missing == [] def test_classify_lyrics_match_flags_unmatched_singing(): - ref = normalize_lyrics("she's got a smile\nthat it seems to me") - segs = [seg(1, 4, "she's got a smile that it seems to me"), + ref = normalize_lyrics("it's one two three\nfour five six seven eight") + segs = [seg(1, 4, "it's one two three four five six seven eight"), seg(20, 23, "completely unrelated ad lib bridge")] dropped, missing = classify_lyrics_match(segs, ref) assert dropped == [] assert missing == [(19.0, 24.0)] def test_classify_lyrics_match_keeps_partially_matched_lines(): - ref = normalize_lyrics("she's got a smile\nthat it seems to me") - # line 1 heard with one word garbled ("it" -> "bit"): still a replace/equal + ref = normalize_lyrics("it's one two three\nfour five six seven eight") + # line 1 heard with one word garbled ("five" -> "fife"): still a replace/equal # match, so the line stays matched rather than dropped - segs = [seg(1, 4, "she's got a smile that bit seems to me")] + segs = [seg(1, 4, "it's one two three four fife six seven eight")] dropped, _ = classify_lyrics_match(segs, ref) assert dropped == [] @@ -54,8 +54,8 @@ def test_classify_lyrics_match_scopes_missing_span_to_adlib_not_whole_section(): # matched line and an unmatched ad-lib close enough together that # vocal_sections would merge them into one section; missing_spans must # stay tight around the ad-lib so the review marks the right place. - ref = normalize_lyrics("she's got a smile\nthat it seems to me") - segs = [seg(1, 4, "she's got a smile that it seems to me"), + ref = normalize_lyrics("it's one two three\nfour five six seven eight") + segs = [seg(1, 4, "it's one two three four five six seven eight"), seg(6, 8, "completely unrelated ad lib")] sections = vocal_sections(segs) assert sections == [(0.0, 9.0)] # confirms the two segments do merge diff --git a/tests/test_ultrastar.py b/tests/test_ultrastar.py index b523cc3..b4fadac 100644 --- a/tests/test_ultrastar.py +++ b/tests/test_ultrastar.py @@ -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