Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -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/
4 changes: 2 additions & 2 deletions tests/musicxml.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ This file defines the MusicXML 3.0 XSD, including the score-partwise and score-t
<xs:annotation>
<xs:documentation>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.</xs:documentation>
</xs:annotation>
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.musicxml.org/xsd/xml.xsd"/>
<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="http://www.musicxml.org/xsd/xlink.xsd"/>
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/03/xml.xsd"/>
<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="http://www.w3.org/XML/2008/06/xlink.xsd"/>

<!-- Simple types derived from common.mod entities and elements -->

Expand Down
32 changes: 28 additions & 4 deletions tests/test_xml.py
Original file line number Diff line number Diff line change
@@ -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():
Expand Down Expand Up @@ -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'(?<=<encoding-date>)\d{4}-\d{2}-\d{2}(?=</encoding-date>)')

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


Expand All @@ -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):
Expand All @@ -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()
8 changes: 4 additions & 4 deletions tests/test_xml_files/break.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN"
"http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="3.0">
<identification>
<encoding>
<software>python-ly 0.9.5</software>
<encoding-date>2017-05-14</encoding-date>
<software>python-ly 0.9.8</software>
<encoding-date>2024-08-10</encoding-date>
</encoding>
</identification>
<part-list>
Expand Down Expand Up @@ -64,6 +64,7 @@
</note>
</measure>
<measure number="2">
<print new-system="yes" />
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️ correct MusicXML equivalent of lily \break

<note>
<pitch>
<step>C</step>
Expand Down Expand Up @@ -101,6 +102,5 @@
<type>quarter</type>
</note>
</measure>
<measure number="3" />
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be correct - break.ly only has musical content for two measures.

</part>
</score-partwise>
6 changes: 3 additions & 3 deletions tests/test_xml_files/breathe.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN"
"http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="3.0">
<identification>
<encoding>
<software>python-ly 0.9.5</software>
<encoding-date>2017-06-05</encoding-date>
<software>python-ly 0.9.8</software>
<encoding-date>2024-08-10</encoding-date>
</encoding>
</identification>
<part-list>
Expand Down
6 changes: 3 additions & 3 deletions tests/test_xml_files/church_modes.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN"
"http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="3.0">
<identification>
<encoding>
<software>python-ly 0.9.5</software>
<encoding-date>2017-07-20</encoding-date>
<software>python-ly 0.9.8</software>
<encoding-date>2024-08-10</encoding-date>
</encoding>
</identification>
<part-list>
Expand Down
6 changes: 4 additions & 2 deletions tests/test_xml_files/dynamics.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<score-partwise version="3.0">
<identification>
<encoding>
<software>python-ly 0.9.4</software>
<encoding-date>2016-03-28</encoding-date>
<software>python-ly 0.9.8</software>
<encoding-date>2024-08-10</encoding-date>
</encoding>
</identification>
<part-list>
Expand Down Expand Up @@ -87,6 +87,8 @@
<dashes type="start" />
</direction-type>
</direction>
</measure>
<measure number="2">
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️ correct - dynamics.ly doesn't specify \time, so the default 4/4 is used

<direction placement="below">
<direction-type>
<dashes type="stop" />
Expand Down
32 changes: 10 additions & 22 deletions tests/test_xml_files/full_bar_rest.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN"
"http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="3.0">
<identification>
<encoding>
<software>python-ly 0.9.5</software>
<encoding-date>2017-07-20</encoding-date>
<software>python-ly 0.9.8</software>
<encoding-date>2024-08-10</encoding-date>
</encoding>
</identification>
<part-list>
Expand All @@ -26,24 +26,13 @@
<line>2</line>
</clef>
</attributes>
<attributes>
<measure-style>
<multiple-rest>6</multiple-rest>
</measure-style>
</attributes>
<note>
<rest />
<duration>4</duration>
<voice>1</voice>
</note>
</measure>
<measure number="2">
<note>
<rest />
<duration>4</duration>
<voice>1</voice>
</note>
</measure>
<measure number="2" />
<measure number="3">
<note>
<rest />
Expand Down Expand Up @@ -73,24 +62,18 @@
</note>
</measure>
<measure number="7">
<attributes>
<measure-style>
<multiple-rest>4</multiple-rest>
</measure-style>
</attributes>
<note>
<rest />
<duration>4</duration>
<voice>1</voice>
</note>
</measure>
<measure number="8">
<note>
<rest />
<duration>4</duration>
<voice>1</voice>
</note>
</measure>
<measure number="8" />
<measure number="9">
<note>
<rest />
Expand All @@ -106,6 +89,11 @@
</note>
</measure>
<measure number="11">
<note>
<rest />
<duration>4</duration>
<voice>1</voice>
</note>
<note>
<pitch>
<step>B</step>
Expand Down
4 changes: 2 additions & 2 deletions tests/test_xml_files/glissando.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
<score-partwise version="3.0">
<identification>
<encoding>
<software>python-ly 0.9.4</software>
<encoding-date>2016-03-28</encoding-date>
<software>python-ly 0.9.8</software>
<encoding-date>2024-08-10</encoding-date>
</encoding>
</identification>
<part-list>
Expand Down
28 changes: 14 additions & 14 deletions tests/test_xml_files/mark.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 2.0 Partwise//EN"
"http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise version="3.0">
<identification>
<encoding>
<software>python-ly 0.9.5</software>
<encoding-date>2017-06-26</encoding-date>
<software>python-ly 0.9.8</software>
<encoding-date>2024-08-10</encoding-date>
</encoding>
</identification>
<part-list>
Expand All @@ -26,11 +26,6 @@
<line>2</line>
</clef>
</attributes>
<direction placement="above">
<direction-type>
<rehearsal>A</rehearsal>
</direction-type>
</direction>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't tell for sure if the changes to this file are correct, but the result renders in MuseScore almost the same mark.ly renders in LilyPond. Just a trailing measure with a rest is added.

<note>
<pitch>
<step>C</step>
Expand All @@ -45,7 +40,7 @@
<attributes />
<direction placement="above">
<direction-type>
<rehearsal>H</rehearsal>
<rehearsal>A</rehearsal>
</direction-type>
</direction>
<note>
Expand All @@ -62,7 +57,7 @@
<attributes />
<direction placement="above">
<direction-type>
<rehearsal>J</rehearsal>
<rehearsal>H</rehearsal>
</direction-type>
</direction>
<note>
Expand All @@ -79,7 +74,7 @@
<attributes />
<direction placement="above">
<direction-type>
<rehearsal>Z</rehearsal>
<rehearsal>J</rehearsal>
</direction-type>
</direction>
<note>
Expand All @@ -96,7 +91,7 @@
<attributes />
<direction placement="above">
<direction-type>
<rehearsal>AA</rehearsal>
<rehearsal>Z</rehearsal>
</direction-type>
</direction>
<note>
Expand All @@ -113,7 +108,7 @@
<attributes />
<direction placement="above">
<direction-type>
<rehearsal>AZ</rehearsal>
<rehearsal>AA</rehearsal>
</direction-type>
</direction>
<note>
Expand All @@ -130,7 +125,7 @@
<attributes />
<direction placement="above">
<direction-type>
<rehearsal>BA</rehearsal>
<rehearsal>AZ</rehearsal>
</direction-type>
</direction>
<note>
Expand All @@ -145,6 +140,11 @@
</measure>
<measure number="8">
<attributes />
<direction placement="above">
<direction-type>
<rehearsal>BA</rehearsal>
</direction-type>
</direction>
</measure>
</part>
</score-partwise>
12 changes: 6 additions & 6 deletions tests/test_xml_files/merge_voice.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
<movement-title>Somebody to love</movement-title>
<identification>
<encoding>
<software>python-ly 0.9.4</software>
<encoding-date>2016-03-28</encoding-date>
<software>python-ly 0.9.8</software>
<encoding-date>2024-08-10</encoding-date>
</encoding>
</identification>
<part-list>
<part-group number="1" type="start">
<part-group type="start" number="1">
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️ mere attribute order change

<group-symbol>bracket</group-symbol>
</part-group>
<score-part id="P1">
<part-name />
</score-part>
<part-group number="2" type="start">
<part-group type="start" number="2">
<group-symbol>bracket</group-symbol>
</part-group>
<score-part id="P2">
<part-name />
</score-part>
<part-group number="2" type="stop" />
<part-group number="1" type="stop" />
<part-group type="stop" number="2" />
<part-group type="stop" number="1" />
</part-list>
<part id="P1">
<measure number="1">
Expand Down
Loading