Skip to content

Commit

Permalink
Make tests comply with xen-dev-utils v0.1.4, enforce scale restrictio…
Browse files Browse the repository at this point in the history
…ns for KorgExport octave format

Addresses #175, #384, and #387
  • Loading branch information
vsicurella committed Nov 25, 2023
1 parent 76abd77 commit 1cc89e7
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 58 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
"jszip": "^3.10.1",
"moment-of-symmetry": "^0.3.1",
"qs": "^6.11.0",
"scale-workshop-core": "github:xenharmonic-devs/scale-workshop-core#v0.0.6",
"temperaments": "^0.4.0",
"vue": "^3.2.33",
"vue-router": "^4.1.5",
"webmidi": "^3.0.21",
"xen-dev-utils": "^0.1.4",
"scale-workshop-core": "github:xenharmonic-devs/scale-workshop-core#v0.0.1"
"xen-dev-utils": "^0.1.4"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.2.0",
Expand Down
18 changes: 18 additions & 0 deletions src/assets/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@

--color-error: red;

/* Mimic Bootstrap alert with 'danger' variant */
--color-alert-danger: rgba(104, 35, 39, 1.0);
--color-alert-danger-background: rgba(243, 216, 218, 1.0);
--color-alert-danger-border: rgba(239, 199, 204, 1.0);

--section-gap: 160px;
--base-font-size: 15px;
--base-line-height: 1.5;
Expand Down Expand Up @@ -300,3 +305,16 @@ span.info-question:hover {
color: var(--color-background);
transition: all 0.3s ease;
}

/* Padded box for displaying UI feedback message */
div.alert-box-danger {
background: var(--color-alert-danger-background);
border-width: 1px;
border-radius: 1%;
border-style: solid;
border-color: var(--color-alert-danger-border);
padding: 8px;
}
p.alert-message-danger {
color: var(--color-alert-danger);
}
35 changes: 30 additions & 5 deletions src/components/modals/export/KorgExport.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,20 @@ const models = [
];
const modelName = ref("minilogue");
const useScaleFormat = ref(true);
const useOctaveFormat = ref(false);
const dialogErrorMessage = computed(() => {
if (useOctaveFormat.value) {
const message = KorgExporter.getOctaveFormatErrorMessage(props.scale);
if (message.length > 0) return message;
}
// Can check for other errors here...
return String();
});
const fileTypePreview = computed(() => {
const format = getKorgModelInfo(modelName.value);
return useScaleFormat.value ? format.scale : format.octave;
return useOctaveFormat.value ? format.octave : format.scale;
});
function doExport() {
Expand All @@ -40,7 +49,7 @@ function doExport() {
const exporter = new KorgExporter(
params,
modelName.value,
useScaleFormat.value
useOctaveFormat.value
);
exporter.saveFile();
Expand All @@ -66,18 +75,34 @@ function doExport() {
<div id="format" class="control radio-group">
<label for="format">Tuning Format</label>
<label>
<input type="radio" :value="true" v-model="useScaleFormat" />
<input type="radio" :value="false" v-model="useOctaveFormat" />
&nbsp;Scale (128-note table)
</label>
<label>
<input type="radio" :value="false" v-model="useScaleFormat" />
<input type="radio" :value="true" v-model="useOctaveFormat" />
&nbsp;Octave (12-note table, octave repeating with fixed C)
</label>
</div>
<p>
<label>Export Format: </label>
{{ fileTypePreview }}
</p>
<div class="alert-box-danger" v-if="dialogErrorMessage.length > 0">
<p class="alert-message-danger">
{{ dialogErrorMessage }}
</p>
</div>
</div>
</template>
<template #footer>
<div class="btn-group">
<button
@click="$emit('confirm')"
:disabled="dialogErrorMessage.length > 0"
>
OK
</button>
<button @click="$emit('cancel')">Cancel</button>
</div>
</template>
</Modal>
Expand Down
85 changes: 77 additions & 8 deletions src/exporters/__tests__/korg.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createHash } from "crypto";
import type { JSZipObject } from "jszip";
import { DEFAULT_NUMBER_OF_COMPONENTS } from "../../constants";
import { Scale } from "scale-workshop-core";
import { ExtendedMonzo, Interval, Scale } from "scale-workshop-core";
import { describe, it, expect } from "vitest";

import { KorgExporter, KorgModels } from "../korg";
import { KorgExporter, KorgModels, KorgExporterError } from "../korg";

import { getTestData } from "./test-data";

Expand All @@ -19,7 +19,7 @@ describe("Korg exporters", () => {
256
);

const exporter = new KorgExporter(params, KorgModels.MINILOGUE, true);
const exporter = new KorgExporter(params, KorgModels.MINILOGUE, false);
const [zip, fileType] = exporter.getFileContents();

expect(fileType).toBe(".mnlgtuns");
Expand All @@ -36,7 +36,7 @@ describe("Korg exporters", () => {
if (path.endsWith("bin")) {
const content = await file.async("uint8array");
expect(createHash("sha256").update(content).digest("base64")).toBe(
"O6YaWtzo33MdIBcMRYlVq7PnzuoMd5Yyp6sBT/3oDnc="
"LvpKRSKkPVHun2VShSXSBx5zWy52voZcZGduTSVmeEY="
);
}
// Other contents didn't seem to have issues so we ignore them here.
Expand All @@ -46,7 +46,7 @@ describe("Korg exporters", () => {
it("can handle all line types (mnlgtuns)", async () => {
const params = getTestData("Korg 'logue exporter unit test v0.0.0");

const exporter = new KorgExporter(params, KorgModels.MINILOGUE, true);
const exporter = new KorgExporter(params, KorgModels.MINILOGUE, false);
const [zip, fileType] = exporter.getFileContents();

expect(fileType).toBe(".mnlgtuns");
Expand All @@ -63,7 +63,7 @@ describe("Korg exporters", () => {
if (path.endsWith("bin")) {
const content = await file.async("uint8array");
expect(createHash("sha256").update(content).digest("base64")).toBe(
"Ps5Ddp9lBYZgCn7Y8aSBnhXOcfIm+sh9AcnybiLX4Zg="
"z7mQ6pS8tVYimN2B5V3WIgN7NR4lFMwrlIjxKJkWEss="
);
} else {
const content = await file.async("string");
Expand All @@ -82,9 +82,78 @@ describe("Korg exporters", () => {
return;
});

it("throws error if 12-note octave tuning is selected, but equave is not 2/1", () => {
const params = getTestData("Korg 'logue exporter unit test v0.0.0");
params.scale.equave = new Interval(
ExtendedMonzo.fromCents(100.0, 3),
"cents"
);
expect(
() => new KorgExporter(params, KorgModels.MINILOGUE, true)
).toThrowError(KorgExporterError.OCTAVE_INVALID_EQUAVE);
});

it("throws error if 12-note octave tuning is selected, but scale does not have 12 notes", () => {
const params = getTestData("Korg 'logue exporter unit test v0.0.0");
expect(
() => new KorgExporter(params, KorgModels.MINILOGUE, true)
).toThrowError(KorgExporterError.OCTAVE_INVALID_SIZE);
});

it("throws error if 12-note octave tuning is selected, but scale contains an interval that is below unison", () => {
const params = getTestData("Korg 'logue exporter unit test v0.0.0");
params.scale.intervals.splice(
1,
0,
new Interval(ExtendedMonzo.fromCents(-500.0, 3), "cents")
);

// Make sure there's 12 notes in the test scale
while (params.scale.intervals.length < 12)
params.scale.intervals.splice(
1,
0,
new Interval(ExtendedMonzo.fromCents(100.0, 3), "cents")
);

expect(
() => new KorgExporter(params, KorgModels.MINILOGUE, true)
).toThrowError(KorgExporterError.OCTAVE_INVALID_INTERVAL);
});

it("throws error if 12-note octave tuning is selected, but scale contains an interval that is greater than an octave", () => {
const params = getTestData("Korg 'logue exporter unit test v0.0.0");
params.scale.intervals.splice(
1,
0,
new Interval(ExtendedMonzo.fromCents(1300.0, 3), "cents")
);

// Make sure there's 12 notes in the test scale
while (params.scale.intervals.length < 12)
params.scale.intervals.splice(
1,
0,
new Interval(ExtendedMonzo.fromCents(100.0, 3), "cents")
);

expect(
() => new KorgExporter(params, KorgModels.MINILOGUE, true)
).toThrowError(KorgExporterError.OCTAVE_INVALID_INTERVAL);
});

it("can handle all line types (mnlgtuno)", async () => {
const params = getTestData("Korg 'logue exporter unit test v0.0.0");
const exporter = new KorgExporter(params, KorgModels.MINILOGUE, false);

// Make sure there's 12 notes in the test scale
while (params.scale.intervals.length < 12)
params.scale.intervals.splice(
1,
0,
new Interval(ExtendedMonzo.fromCents(100.0, 3), "cents")
);

const exporter = new KorgExporter(params, KorgModels.MINILOGUE, true);
const [zip, fileType] = exporter.getFileContents();

expect(fileType).toBe(".mnlgtuno");
Expand All @@ -101,7 +170,7 @@ describe("Korg exporters", () => {
if (path.endsWith("bin")) {
const content = await file.async("uint8array");
expect(createHash("sha256").update(content).digest("base64")).toBe(
"hnBNRPHvVHYkBfgM/ss+wTqd2Sy4UQ6bBk8aJqQWPzI="
"XwQptSiZLUa8LL/41LEeN1fUNvFr8GUptkga2k+tYJE="
);
} else {
const content = await file.async("string");
Expand Down
8 changes: 4 additions & 4 deletions src/exporters/__tests__/mts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe("MTS exporter", () => {

const scaleData = exporter.getBulkTuningData();
expect(createHash("sha256").update(scaleData).digest("base64")).toBe(
"Ps5Ddp9lBYZgCn7Y8aSBnhXOcfIm+sh9AcnybiLX4Zg="
"z7mQ6pS8tVYimN2B5V3WIgN7NR4lFMwrlIjxKJkWEss="
);

// Name is padded with spaces
Expand All @@ -26,7 +26,7 @@ describe("MTS exporter", () => {

const sysExMsg = exporter.buildSysExDump();
expect(createHash("sha256").update(sysExMsg).digest("base64")).toBe(
"Dx+z9IBMNqBrj7/g4EJ3XQxMPKbtQqmpfjLdoPPrV48="
"WYM++7Jej+d9FhBWw0hqKyj/YMhgtSbCfFA6QryKhdI="
);
});

Expand All @@ -41,7 +41,7 @@ describe("MTS exporter", () => {

const scaleData = exporter.getBulkTuningData();
expect(createHash("sha256").update(scaleData).digest("base64")).toBe(
"Ps5Ddp9lBYZgCn7Y8aSBnhXOcfIm+sh9AcnybiLX4Zg="
"z7mQ6pS8tVYimN2B5V3WIgN7NR4lFMwrlIjxKJkWEss="
);

// Name is truncated
Expand All @@ -52,7 +52,7 @@ describe("MTS exporter", () => {

const sysExMsg = exporter.buildSysExDump();
expect(createHash("sha256").update(sysExMsg).digest("base64")).toBe(
"8TgBDEn+mTm/xar39zeO9NBCcRn6KymbO/ZeMfa8rq0="
"vrtx5APwYW8zLF0CVgkcBE3z/kGSXYKfDHDrd0oh8xI="
);
});

Expand Down
Loading

0 comments on commit 1cc89e7

Please sign in to comment.