Key_Test.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. import { MusicSheetReader } from "../../../src/MusicalScore/ScoreIO/MusicSheetReader";
  2. import { MusicSheet } from "../../../src/MusicalScore/MusicSheet";
  3. import { IXmlElement } from "../../../src/Common/FileIO/Xml";
  4. import { KeyInstruction } from "../../../src/MusicalScore/VoiceData/Instructions/KeyInstruction";
  5. import { KeyEnum as KeyModeEnum } from "../../../src/MusicalScore/VoiceData/Instructions/KeyInstruction";
  6. import * as chai from "chai";
  7. let reader: MusicSheetReader;
  8. let parser: DOMParser;
  9. /* tslint:disable:no-unused-expression */
  10. describe("MusicXML parser for element 'key'", () => {
  11. before((): void => {
  12. reader = new MusicSheetReader();
  13. parser = new DOMParser();
  14. });
  15. describe("for group traditional keys", () => {
  16. xit("enforces single occurrence of element 'fifths'", (done: MochaDone) => {
  17. const keyInstruction: KeyInstruction = getIllegalMusicXmlWithTwoFifthsElements().getFirstSourceMeasure().getKeyInstruction(0);
  18. // TODO Make sure we detect the multiple fifths and react properly
  19. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.none);
  20. done();
  21. });
  22. it("reads key signature with no optional 'mode' element present", (done: MochaDone) => {
  23. const keyInstruction: KeyInstruction = getMusicSheetWithKey(0, undefined).getFirstSourceMeasure().getKeyInstruction(0);
  24. chai.expect(keyInstruction.Key).to.equal(0);
  25. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.none);
  26. done();
  27. });
  28. describe("major keys", () => {
  29. it("reads key signature C-major", (done: MochaDone) => {
  30. const keyInstruction: KeyInstruction = getMusicSheetWithKey(0, "major").getFirstSourceMeasure().getKeyInstruction(0);
  31. chai.expect(keyInstruction.Key).to.equal(0);
  32. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  33. done();
  34. });
  35. it("reads key signature G-major", (done: MochaDone) => {
  36. const keyInstruction: KeyInstruction = getMusicSheetWithKey(1, "major").getFirstSourceMeasure().getKeyInstruction(0);
  37. chai.expect(keyInstruction.Key).to.equal(1);
  38. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  39. done();
  40. });
  41. it("reads key signature D-major", (done: MochaDone) => {
  42. const keyInstruction: KeyInstruction = getMusicSheetWithKey(2, "major").getFirstSourceMeasure().getKeyInstruction(0);
  43. chai.expect(keyInstruction.Key).to.equal(2);
  44. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  45. done();
  46. });
  47. it("reads key signature A-major", (done: MochaDone) => {
  48. const keyInstruction: KeyInstruction = getMusicSheetWithKey(3, "major").getFirstSourceMeasure().getKeyInstruction(0);
  49. chai.expect(keyInstruction.Key).to.equal(3);
  50. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  51. done();
  52. });
  53. it("reads key signature E-major", (done: MochaDone) => {
  54. const keyInstruction: KeyInstruction = getMusicSheetWithKey(4, "major").getFirstSourceMeasure().getKeyInstruction(0);
  55. chai.expect(keyInstruction.Key).to.equal(4);
  56. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  57. done();
  58. });
  59. it("reads key signature B-major", (done: MochaDone) => {
  60. const keyInstruction: KeyInstruction = getMusicSheetWithKey(5, "major").getFirstSourceMeasure().getKeyInstruction(0);
  61. chai.expect(keyInstruction.Key).to.equal(5);
  62. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  63. done();
  64. });
  65. it("reads key signature Fis-major", (done: MochaDone) => {
  66. const keyInstruction: KeyInstruction = getMusicSheetWithKey(6, "major").getFirstSourceMeasure().getKeyInstruction(0);
  67. chai.expect(keyInstruction.Key).to.equal(6);
  68. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  69. done();
  70. });
  71. it("reads key signature Cis-major", (done: MochaDone) => {
  72. const keyInstruction: KeyInstruction = getMusicSheetWithKey(7, "major").getFirstSourceMeasure().getKeyInstruction(0);
  73. chai.expect(keyInstruction.Key).to.equal(7);
  74. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  75. done();
  76. });
  77. it("reads key signature Gis-major", (done: MochaDone) => {
  78. const keyInstruction: KeyInstruction = getMusicSheetWithKey(8, "major").getFirstSourceMeasure().getKeyInstruction(0);
  79. chai.expect(keyInstruction.Key).to.equal(8);
  80. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  81. done();
  82. });
  83. it("reads key signature F-major", (done: MochaDone) => {
  84. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-1, "major").getFirstSourceMeasure().getKeyInstruction(0);
  85. chai.expect(keyInstruction.Key).to.equal(-1);
  86. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  87. done();
  88. });
  89. it("reads key signature B-major", (done: MochaDone) => {
  90. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-2, "major").getFirstSourceMeasure().getKeyInstruction(0);
  91. chai.expect(keyInstruction.Key).to.equal(-2);
  92. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  93. done();
  94. });
  95. it("reads key signature Es-major", (done: MochaDone) => {
  96. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-3, "major").getFirstSourceMeasure().getKeyInstruction(0);
  97. chai.expect(keyInstruction.Key).to.equal(-3);
  98. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  99. done();
  100. });
  101. it("reads key signature As-major", (done: MochaDone) => {
  102. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-4, "major").getFirstSourceMeasure().getKeyInstruction(0);
  103. chai.expect(keyInstruction.Key).to.equal(-4);
  104. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  105. done();
  106. });
  107. it("reads key signature Des-major", (done: MochaDone) => {
  108. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-5, "major").getFirstSourceMeasure().getKeyInstruction(0);
  109. chai.expect(keyInstruction.Key).to.equal(-5);
  110. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  111. done();
  112. });
  113. it("reads key signature Ges-major", (done: MochaDone) => {
  114. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-6, "major").getFirstSourceMeasure().getKeyInstruction(0);
  115. chai.expect(keyInstruction.Key).to.equal(-6);
  116. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  117. done();
  118. });
  119. it("reads key signature Fes-major", (done: MochaDone) => {
  120. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-8, "major").getFirstSourceMeasure().getKeyInstruction(0);
  121. chai.expect(keyInstruction.Key).to.equal(-8);
  122. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
  123. done();
  124. });
  125. });
  126. describe("minor keys", () => {
  127. it("reads key signature a-minor", (done: MochaDone) => {
  128. const keyInstruction: KeyInstruction = getMusicSheetWithKey(0, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  129. chai.expect(keyInstruction.Key).to.equal(0);
  130. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  131. done();
  132. });
  133. it("reads key signature e-minor", (done: MochaDone) => {
  134. const keyInstruction: KeyInstruction = getMusicSheetWithKey(1, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  135. chai.expect(keyInstruction.Key).to.equal(1);
  136. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  137. done();
  138. });
  139. it("reads key signature b-minor", (done: MochaDone) => {
  140. const keyInstruction: KeyInstruction = getMusicSheetWithKey(2, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  141. chai.expect(keyInstruction.Key).to.equal(2);
  142. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  143. done();
  144. });
  145. it("reads key signature fis-minor", (done: MochaDone) => {
  146. const keyInstruction: KeyInstruction = getMusicSheetWithKey(3, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  147. chai.expect(keyInstruction.Key).to.equal(3);
  148. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  149. done();
  150. });
  151. it("reads key signature cis-minor", (done: MochaDone) => {
  152. const keyInstruction: KeyInstruction = getMusicSheetWithKey(4, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  153. chai.expect(keyInstruction.Key).to.equal(4);
  154. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  155. done();
  156. });
  157. it("reads key signature gis-minor", (done: MochaDone) => {
  158. const keyInstruction: KeyInstruction = getMusicSheetWithKey(5, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  159. chai.expect(keyInstruction.Key).to.equal(5);
  160. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  161. done();
  162. });
  163. it("reads key signature dis-minor", (done: MochaDone) => {
  164. const keyInstruction: KeyInstruction = getMusicSheetWithKey(6, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  165. chai.expect(keyInstruction.Key).to.equal(6);
  166. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  167. done();
  168. });
  169. it("reads key signature ais-minor", (done: MochaDone) => {
  170. const keyInstruction: KeyInstruction = getMusicSheetWithKey(7, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  171. chai.expect(keyInstruction.Key).to.equal(7);
  172. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  173. done();
  174. });
  175. it("reads key signature d-minor", (done: MochaDone) => {
  176. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-1, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  177. chai.expect(keyInstruction.Key).to.equal(-1);
  178. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  179. done();
  180. });
  181. it("reads key signature g-minor", (done: MochaDone) => {
  182. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-2, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  183. chai.expect(keyInstruction.Key).to.equal(-2);
  184. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  185. done();
  186. });
  187. it("reads key signature c-minor", (done: MochaDone) => {
  188. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-3, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  189. chai.expect(keyInstruction.Key).to.equal(-3);
  190. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  191. done();
  192. });
  193. it("reads key signature f-minor", (done: MochaDone) => {
  194. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-4, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  195. chai.expect(keyInstruction.Key).to.equal(-4);
  196. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  197. done();
  198. });
  199. it("reads key signature bb-minor", (done: MochaDone) => {
  200. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-5, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  201. chai.expect(keyInstruction.Key).to.equal(-5);
  202. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  203. done();
  204. });
  205. it("reads key signature es-minor", (done: MochaDone) => {
  206. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-6, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  207. chai.expect(keyInstruction.Key).to.equal(-6);
  208. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  209. done();
  210. });
  211. it("reads key signature as-minor", (done: MochaDone) => {
  212. const keyInstruction: KeyInstruction = getMusicSheetWithKey(-7, "minor").getFirstSourceMeasure().getKeyInstruction(0);
  213. chai.expect(keyInstruction.Key).to.equal(-7);
  214. chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
  215. done();
  216. });
  217. });
  218. });
  219. });
  220. function getMusicSheetWithKey(fifths: number = undefined, mode: string = undefined): MusicSheet {
  221. const doc: Document = parser.parseFromString(getMusicXmlWithKey(fifths, mode), "text/xml");
  222. chai.expect(doc).to.not.be.undefined;
  223. const score: IXmlElement = new IXmlElement(doc.getElementsByTagName("score-partwise")[0]);
  224. chai.expect(score).to.not.be.undefined;
  225. return reader.createMusicSheet(score, "template.xml");
  226. }
  227. function getMusicXmlWithKey(fifths: number = undefined, mode: string = undefined): string {
  228. const modeElement: string = mode ? `<mode>${mode}</mode>` : "";
  229. const fifthsElement: string = fifths ? `<fifths>${fifths}</fifths>` : "";
  230. return `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  231. <!DOCTYPE score-partwise PUBLIC
  232. "-//Recordare//DTD MusicXML 3.0 Partwise//EN"
  233. "http://www.musicxml.org/dtds/partwise.dtd">
  234. <score-partwise version="3.0">
  235. <part-list>
  236. <score-part id="P1">
  237. <part-name>Music</part-name>
  238. </score-part>
  239. </part-list>
  240. <part id="P1">
  241. <measure number="1">
  242. <attributes>
  243. <divisions>1</divisions>
  244. <key>
  245. ${fifthsElement}
  246. ${modeElement}
  247. </key>
  248. <time>
  249. <beats>4</beats>
  250. <beat-type>4</beat-type>
  251. </time>
  252. <clef>
  253. <sign>G</sign>
  254. <line>2</line>
  255. </clef>
  256. </attributes>
  257. <note>
  258. <pitch>
  259. <step>C</step>
  260. <octave>4</octave>
  261. </pitch>
  262. <duration>4</duration>
  263. <type>whole</type>
  264. </note>
  265. </measure>
  266. </part>
  267. </score-partwise>`;
  268. }
  269. function getIllegalMusicXmlWithTwoFifthsElements(): MusicSheet {
  270. const doc: Document = parser.parseFromString(
  271. `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  272. <!DOCTYPE score-partwise PUBLIC
  273. "-//Recordare//DTD MusicXML 3.0 Partwise//EN"
  274. "http://www.musicxml.org/dtds/partwise.dtd">
  275. <score-partwise version="3.0">
  276. <part-list>
  277. <score-part id="P1">
  278. <part-name>Music</part-name>
  279. </score-part>
  280. </part-list>
  281. <part id="P1">
  282. <measure number="1">
  283. <attributes>
  284. <divisions>1</divisions>
  285. <key>
  286. <fifths>1</fifths>
  287. <fifths>2</fifths>
  288. <fifths>3</fifths>
  289. </key>
  290. <time>
  291. <beats>4</beats>
  292. <beat-type>4</beat-type>
  293. </time>
  294. <clef>
  295. <sign>G</sign>
  296. <line>2</line>
  297. </clef>
  298. </attributes>
  299. <note>
  300. <pitch>
  301. <step>C</step>
  302. <octave>4</octave>
  303. </pitch>
  304. <duration>4</duration>
  305. <type>whole</type>
  306. </note>
  307. </measure>
  308. </part>
  309. </score-partwise>`,
  310. "text/xml"
  311. );
  312. chai.expect(doc).to.not.be.undefined;
  313. const score: IXmlElement = new IXmlElement(doc.getElementsByTagName("score-partwise")[0]);
  314. chai.expect(score).to.not.be.undefined;
  315. return reader.createMusicSheet(score, "template.xml");
  316. }