satie
Version:
A sheet music renderer for the web
107 lines (106 loc) • 6.68 kB
JavaScript
"use strict";
var musicxml_interfaces_1 = require("musicxml-interfaces");
var chai_1 = require("chai");
var lodash_1 = require("lodash");
var document_1 = require("../document");
var engine_songImpl_1 = require("../engine_songImpl");
var satie_1 = require("../satie");
var songTemplate = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE score-partwise PUBLIC \"-//Recordare//DTD MusicXML 3.0 Partwise//EN\"\n \"http://www.musicxml.org/dtds/partwise.dtd\">\n<score-partwise>\n <movement-title>Satie Sandbox</movement-title>\n <identification>\n <miscellaneous>\n <miscellaneous-field name=\"description\">\n A test song\n </miscellaneous-field>\n </miscellaneous>\n </identification>\n <part-list>\n <score-part id=\"P1\">\n <part-name>Cello</part-name>\n </score-part>\n </part-list>\n <!--=========================================================-->\n <part id=\"P1\">\n <measure number=\"1\">\n <attributes>\n <divisions>1</divisions>\n <key>\n <fifths>-3</fifths>\n <mode>minor</mode>\n </key>\n <time symbol=\"common\">\n <beats>4</beats>\n <beat-type>4</beat-type>\n </time>\n <clef>\n <sign>G</sign>\n <line>2</line>\n </clef>\n </attributes>\n <note>\n <rest measure=\"yes\" />\n <duration>4</duration>\n <voice>1</voice>\n <type>whole</type>\n </note>\n </measure>\n <measure number=\"2\">\n <note>\n <rest measure=\"yes\" />\n <duration>4</duration>\n <voice>1</voice>\n <type>whole</type>\n </note>\n </measure>\n <measure number=\"3\">\n <note>\n <rest measure=\"yes\" />\n <duration>4</duration>\n <voice>1</voice>\n <type>whole</type>\n </note>\n </measure>\n </part>\n</score-partwise>";
describe("patches (1)", function () {
var song;
beforeEach(function (done) {
song = new engine_songImpl_1.default({
baseSrc: songTemplate,
onError: done,
onLoaded: function () {
done();
},
});
song.run();
});
it("can append a bar, and adjust barlines accordingly, and this can be undone", function (done) {
var patch = satie_1.Patch.createPatch(false, song.getDocument(null), function (document) { return document
.insertMeasure(3, function (measure) { return measure
.part("P1", function (part) { return part
.voice(1, function (voice) { return voice
.at(0)
.insertChord([
function (note) { return note
.rest({})
.staff(1)
.noteType(function (type) { return type
.duration(musicxml_interfaces_1.Count.Whole); }); }
]); }); }); }); });
var thirdMeasureUUID = song.getDocument(null).measures[2].uuid;
// new measure
chai_1.expect(patch[0].p).to.deep.equal(["measures", 3]);
var newMeasureUUID = patch[0].li.uuid;
chai_1.expect(newMeasureUUID).to.be.a("number");
// new note
chai_1.expect(patch[1].p).to.deep.equal([newMeasureUUID, "parts", "P1", "voices", 1, 0]);
chai_1.expect(patch[1].li[0]._class).to.equal("Note");
chai_1.expect(patch[1].ld).to.equal(undefined);
// previously final barline
chai_1.expect(patch[2].p).to.deep.equal([thirdMeasureUUID, "parts", "P1", "staves", 1, 3,
"barStyle", "data"]);
chai_1.expect(patch[2].oi).to.equal(musicxml_interfaces_1.BarStyleType.Regular);
chai_1.expect(patch[2].od).to.equal(musicxml_interfaces_1.BarStyleType.LightHeavy);
// No other patches
chai_1.expect(patch.length).to.equal(3);
var expandedPatch = song.createCanonicalPatch({ raw: patch });
// check state of document
var patchedDocument = song.getDocument(expandedPatch);
chai_1.expect(patchedDocument.measures.length).to.equal(4);
chai_1.expect(patchedDocument.measures[3].parts["P1"].voices[1][0].divCount).to.equal(4);
chai_1.expect(patchedDocument.modelHasType(patchedDocument.measures[3].parts["P1"].staves[1][3], document_1.Type.Barline)).to.be.true;
// Does not change previous patch.
chai_1.expect(patch.length).to.equal(3);
var barStylePatch = lodash_1.find(expandedPatch.content, function (p) { return p.li && p.li._class === "Barline"; });
chai_1.expect(barStylePatch).to.deep.equal({
p: [newMeasureUUID, "parts", "P1", "staves", 1, 2],
li: {
_class: "Barline",
barStyle: {
data: musicxml_interfaces_1.BarStyleType.LightHeavy,
},
},
});
// Try undoing everything
var newPatch = song.createCanonicalPatch(null);
chai_1.expect(newPatch.content.length).to.equal(0);
chai_1.expect(song.getDocument(newPatch).measures.length).to.equal(3);
var barline = song.getDocument(newPatch).measures[2].parts["P1"].staves[1][3];
chai_1.expect(barline._class).to.equal("Barline");
chai_1.expect(barline.barStyle.data === musicxml_interfaces_1.BarStyleType.LightHeavy);
// changed barline
done();
});
it("can replace a rest with a shorter note", function (done) {
var measureUUID = song.getDocument(null).measures[0].uuid;
var patch = satie_1.Patch.createPatch(false, song.getDocument(null), measureUUID, "P1", function (part) { return part
.voice(1, function (voice) { return voice
.at(0)
.note(0, function (note) { return note
.pitch(function (pitch) { return pitch
.step("C")
.octave(5)
.alter(1); })
.dots([])
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Quarter); })
.accidental(function (accidental) { return accidental
.accidental(musicxml_interfaces_1.MxmlAccidental.Sharp); })
.color("#cecece"); }); }); });
song.createCanonicalPatch({ raw: patch });
// Try undoing this, making sure the first note is now a rest.
var newPatch = song.createCanonicalPatch(null);
chai_1.expect(song.getDocument(newPatch).measures[0].parts["P1"].voices[1][0][0].rest).
to.deep.equal({
displayOctave: undefined,
displayStep: undefined,
measure: true,
});
// changed barline
done();
});
});