diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..f033f870
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,22 @@
+name: CI
+on: [push, pull_request]
+jobs:
+ specs:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version:
+ - 3.8 # oldest officially supported by python-ly
+ - 3.12 # latest
+
+ steps:
+ - name: Check out code
+ uses: actions/checkout@v4
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install dependencies
+ run: pip install pytest lxml
+ - name: Run tests
+ run: pytest tests/
diff --git a/tests/musicxml.xsd b/tests/musicxml.xsd
index 48116bf7..147b2cfc 100644
--- a/tests/musicxml.xsd
+++ b/tests/musicxml.xsd
@@ -20,8 +20,8 @@ This file defines the MusicXML 3.0 XSD, including the score-partwise and score-t
The MusicXML 3.0 DTD has no namespace, so for compatibility the MusicXML 3.0 XSD has no namespace either. Those who need to import the MusicXML XSD into another schema are advised to create a new version that uses "http://www.musicxml.org/xsd/MusicXML" as the namespace.
-
-
+
+
diff --git a/tests/test_xml.py b/tests/test_xml.py
index 33ddfbb3..015be833 100644
--- a/tests/test_xml.py
+++ b/tests/test_xml.py
@@ -1,10 +1,14 @@
"""Tests for XML output."""
import datetime
import difflib
+import glob
import ly.musicxml
from lxml import etree
import os
+import os.path
import io
+import re
+import sys
def test_glissando():
@@ -75,17 +79,18 @@ def ly_to_xml(filename):
with open(filename, 'r') as lyfile:
writer.parse_text(lyfile.read())
xml = writer.musicxml()
- sio = io.StringIO()
+ sio = io.BytesIO()
xml.write(sio, "utf-8")
- return sio.getvalue()
+ return sio.getvalue().decode("utf-8")
+encoding_date_element_re = re.compile(r'(?<=)\d{4}-\d{2}-\d{2}(?=)')
def read_expected_xml(filename):
"""Return string with expected XML from file."""
with open(filename, 'r') as xmlfile:
output = xmlfile.read()
# Replace date in XML file with today's date
- output = output.replace("2016-03-28", str(datetime.date.today()))
+ output = encoding_date_element_re.sub(str(datetime.date.today()), output)
return output
@@ -109,8 +114,9 @@ def validate_xml(xml):
xsdfile.close()
xmlschema = etree.XMLSchema(xmlschema_doc)
parser = etree.XMLParser(schema=xmlschema)
+ xml_bytes = xml.encode('utf-8')
# Raises Exception if not valid:
- etree.fromstring(xml, parser)
+ etree.fromstring(xml_bytes, parser)
def assert_multi_line_equal(first, second, msg=None):
@@ -127,3 +133,21 @@ def assert_multi_line_equal(first, second, msg=None):
if msg:
message += " : " + msg
assert False, "Multi-line strings are unequal:\n" + message
+
+
+def regenerate_xml():
+ """Regenerate the XML files"""
+ extension_re = re.compile(r'\.ly$')
+ for ly_path in glob.glob(os.path.join(os.path.dirname(__file__), 'test_xml_files/*.ly')):
+ xml_path = extension_re.sub('.xml', ly_path)
+ xml = ly_to_xml(ly_path)
+ with open(xml_path, 'w') as fw:
+ fw.write(xml)
+
+
+# Run
+# $ test_xml.py regenerate
+# to generate the expected XML files anew with current python-ly
+if __name__ == '__main__':
+ if len(sys.argv) > 1 and sys.argv[1] == 'regenerate':
+ regenerate_xml()
diff --git a/tests/test_xml_files/break.xml b/tests/test_xml_files/break.xml
index 4cca3162..39d667e2 100644
--- a/tests/test_xml_files/break.xml
+++ b/tests/test_xml_files/break.xml
@@ -1,11 +1,11 @@
-
+
- python-ly 0.9.5
- 2017-05-14
+ python-ly 0.9.8
+ 2024-08-10
@@ -64,6 +64,7 @@
+
C
@@ -101,6 +102,5 @@
quarter
-
diff --git a/tests/test_xml_files/breathe.xml b/tests/test_xml_files/breathe.xml
index a6b93bf8..51a247c1 100644
--- a/tests/test_xml_files/breathe.xml
+++ b/tests/test_xml_files/breathe.xml
@@ -1,11 +1,11 @@
-
+
- python-ly 0.9.5
- 2017-06-05
+ python-ly 0.9.8
+ 2024-08-10
diff --git a/tests/test_xml_files/church_modes.xml b/tests/test_xml_files/church_modes.xml
index 3b989183..5226c63f 100644
--- a/tests/test_xml_files/church_modes.xml
+++ b/tests/test_xml_files/church_modes.xml
@@ -1,11 +1,11 @@
-
+
- python-ly 0.9.5
- 2017-07-20
+ python-ly 0.9.8
+ 2024-08-10
diff --git a/tests/test_xml_files/dynamics.xml b/tests/test_xml_files/dynamics.xml
index c39f8fd6..4f100dcd 100644
--- a/tests/test_xml_files/dynamics.xml
+++ b/tests/test_xml_files/dynamics.xml
@@ -4,8 +4,8 @@
- python-ly 0.9.4
- 2016-03-28
+ python-ly 0.9.8
+ 2024-08-10
@@ -87,6 +87,8 @@
+
+
diff --git a/tests/test_xml_files/full_bar_rest.xml b/tests/test_xml_files/full_bar_rest.xml
index b7ad1ae0..78921aa7 100644
--- a/tests/test_xml_files/full_bar_rest.xml
+++ b/tests/test_xml_files/full_bar_rest.xml
@@ -1,11 +1,11 @@
-
+
- python-ly 0.9.5
- 2017-07-20
+ python-ly 0.9.8
+ 2024-08-10
@@ -26,24 +26,13 @@
2
-
-
- 6
-
-
-
-
- 4
- 1
-
-
-
4
1
+
@@ -73,24 +62,18 @@
-
-
- 4
-
-
4
1
-
-
4
1
+
@@ -106,6 +89,11 @@
+
+
+ 4
+ 1
+
B
diff --git a/tests/test_xml_files/glissando.xml b/tests/test_xml_files/glissando.xml
index a680da20..224f68dd 100644
--- a/tests/test_xml_files/glissando.xml
+++ b/tests/test_xml_files/glissando.xml
@@ -4,8 +4,8 @@
- python-ly 0.9.4
- 2016-03-28
+ python-ly 0.9.8
+ 2024-08-10
diff --git a/tests/test_xml_files/mark.xml b/tests/test_xml_files/mark.xml
index acdd63d8..189f92ae 100644
--- a/tests/test_xml_files/mark.xml
+++ b/tests/test_xml_files/mark.xml
@@ -1,11 +1,11 @@
-
+
- python-ly 0.9.5
- 2017-06-26
+ python-ly 0.9.8
+ 2024-08-10
@@ -26,11 +26,6 @@
2
-
-
- A
-
-
C
@@ -45,7 +40,7 @@
- H
+ A
@@ -62,7 +57,7 @@
- J
+ H
@@ -79,7 +74,7 @@
- Z
+ J
@@ -96,7 +91,7 @@
- AA
+ Z
@@ -113,7 +108,7 @@
- AZ
+ AA
@@ -130,7 +125,7 @@
- BA
+ AZ
@@ -145,6 +140,11 @@
+
+
+ BA
+
+
diff --git a/tests/test_xml_files/merge_voice.xml b/tests/test_xml_files/merge_voice.xml
index 4a638647..cfe3324b 100644
--- a/tests/test_xml_files/merge_voice.xml
+++ b/tests/test_xml_files/merge_voice.xml
@@ -5,25 +5,25 @@
Somebody to love
- python-ly 0.9.4
- 2016-03-28
+ python-ly 0.9.8
+ 2024-08-10
-
+
bracket
-
+
bracket
-
-
+
+
diff --git a/tests/test_xml_files/merge_voice_slurs.xml b/tests/test_xml_files/merge_voice_slurs.xml
index f55aaeb6..a7fe54a5 100644
--- a/tests/test_xml_files/merge_voice_slurs.xml
+++ b/tests/test_xml_files/merge_voice_slurs.xml
@@ -5,18 +5,18 @@
merge voices with slurs
- python-ly 0.9.4
- 2016-03-28
+ python-ly 0.9.8
+ 2024-08-10
-
+
bracket
-
+
diff --git a/tests/test_xml_files/no_barcheck.xml b/tests/test_xml_files/no_barcheck.xml
index 18771343..d9f4c064 100644
--- a/tests/test_xml_files/no_barcheck.xml
+++ b/tests/test_xml_files/no_barcheck.xml
@@ -1,11 +1,11 @@
-
+
- python-ly 0.9.5
- 2017-08-08
+ python-ly 0.9.8
+ 2024-08-10
diff --git a/tests/test_xml_files/stem.xml b/tests/test_xml_files/stem.xml
index 6fad1ee7..dcdd2562 100644
--- a/tests/test_xml_files/stem.xml
+++ b/tests/test_xml_files/stem.xml
@@ -1,11 +1,11 @@
-
+
- python-ly 0.9.5
- 2017-07-16
+ python-ly 0.9.8
+ 2024-08-10
diff --git a/tests/test_xml_files/tie.xml b/tests/test_xml_files/tie.xml
index d02a90fa..6d9bb905 100644
--- a/tests/test_xml_files/tie.xml
+++ b/tests/test_xml_files/tie.xml
@@ -4,8 +4,8 @@
- python-ly 0.9.4
- 2016-03-28
+ python-ly 0.9.8
+ 2024-08-10
diff --git a/tests/test_xml_files/tuplet.xml b/tests/test_xml_files/tuplet.xml
index d483be55..fa9f8d15 100644
--- a/tests/test_xml_files/tuplet.xml
+++ b/tests/test_xml_files/tuplet.xml
@@ -4,8 +4,8 @@
- python-ly 0.9.4
- 2016-03-28
+ python-ly 0.9.8
+ 2024-08-10
diff --git a/tests/test_xml_files/variable.xml b/tests/test_xml_files/variable.xml
index acd81e18..12d7f27f 100644
--- a/tests/test_xml_files/variable.xml
+++ b/tests/test_xml_files/variable.xml
@@ -4,8 +4,8 @@
- python-ly 0.9.4
- 2016-03-28
+ python-ly 0.9.8
+ 2024-08-10