basic snapshot test for tunes
This commit is contained in:
parent
3eebccd566
commit
6cac8ba108
8 changed files with 9326 additions and 723 deletions
8735
repl/package-lock.json
generated
8735
repl/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -22,7 +22,8 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
"build": "BUILD_PATH='../docs' react-scripts build && npm run build-tutorial",
|
"build": "BUILD_PATH='../docs' react-scripts build && npm run build-tutorial",
|
||||||
"test": "react-scripts test",
|
"test": "mocha ./src/test --colors",
|
||||||
|
"snapshot": "cd ./src/ && rm -f ./tunes.snapshot.mjs && node ./shoot.mjs > ./tunes.snapshot.mjs",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"tutorial": "parcel src/tutorial/index.html --no-cache",
|
"tutorial": "parcel src/tutorial/index.html --no-cache",
|
||||||
"build-tutorial": "rm -rf ../docs/tutorial && parcel build src/tutorial/index.html --dist-dir ../docs/tutorial --public-url /tutorial --no-scope-hoist --no-cache",
|
"build-tutorial": "rm -rf ../docs/tutorial && parcel build src/tutorial/index.html --dist-dir ../docs/tutorial --public-url /tutorial --no-scope-hoist --no-cache",
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
/*
|
|
||||||
App.test.js - <short description TODO>
|
|
||||||
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/repl/src/App.test.js>
|
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { render, screen } from '@testing-library/react';
|
|
||||||
import App from './App';
|
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
|
||||||
render(<App />);
|
|
||||||
const linkElement = screen.getByText(/learn react/i);
|
|
||||||
expect(linkElement).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
143
repl/src/runtime.mjs
Normal file
143
repl/src/runtime.mjs
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
// this file contains a runtime scope for testing all the tunes
|
||||||
|
// it mocks all the functions that won't work in node (who are not important for testing values / structure)
|
||||||
|
// it might require mocking more stuff when tunes added that use other functions
|
||||||
|
|
||||||
|
// import * as tunes from './tunes.mjs';
|
||||||
|
import { evaluate } from '@strudel.cycles/eval';
|
||||||
|
import { extend } from '@strudel.cycles/eval';
|
||||||
|
import * as strudel from '@strudel.cycles/core';
|
||||||
|
// import gist from '@strudel.cycles/core/gist.js';
|
||||||
|
import { mini } from '@strudel.cycles/mini/mini.mjs';
|
||||||
|
// import { Tone } from '@strudel.cycles/tone';
|
||||||
|
// import * as toneHelpers from '@strudel.cycles/tone/tone.mjs';
|
||||||
|
// import * as voicingHelpers from '@strudel.cycles/tonal/voicings.mjs';
|
||||||
|
// import * as uiHelpers from '@strudel.cycles/tone/ui.mjs';
|
||||||
|
// import * as drawHelpers from '@strudel.cycles/tone/draw.mjs';
|
||||||
|
// import euclid from '@strudel.cycles/core/euclid.mjs';
|
||||||
|
// import '@strudel.cycles/tone/tone.mjs';
|
||||||
|
// import '@strudel.cycles/midi/midi.mjs';
|
||||||
|
import '@strudel.cycles/tonal/voicings.mjs';
|
||||||
|
import '@strudel.cycles/tonal/tonal.mjs';
|
||||||
|
import '@strudel.cycles/xen/xen.mjs';
|
||||||
|
// import '@strudel.cycles/xen/tune.mjs';
|
||||||
|
// import '@strudel.cycles/core/euclid.mjs';
|
||||||
|
// import '@strudel.cycles/core/speak.mjs'; // window is not defined
|
||||||
|
// import '@strudel.cycles/tone/pianoroll.mjs';
|
||||||
|
// import '@strudel.cycles/tone/draw.mjs';
|
||||||
|
// import '@strudel.cycles/osc/osc.mjs';
|
||||||
|
// import '@strudel.cycles/webaudio/webaudio.mjs';
|
||||||
|
// import '@strudel.cycles/serial/serial.mjs';
|
||||||
|
// import controls from '@strudel.cycles/core/controls.mjs';
|
||||||
|
|
||||||
|
class MockedNode {
|
||||||
|
chain() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
connect() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
toDestination() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
set() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
start() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockNode = () => new MockedNode();
|
||||||
|
|
||||||
|
const id = (x) => x;
|
||||||
|
|
||||||
|
const toneHelpersMocked = {
|
||||||
|
FeedbackDelay: MockedNode,
|
||||||
|
MembraneSynth: MockedNode,
|
||||||
|
NoiseSynth: MockedNode,
|
||||||
|
MetalSynth: MockedNode,
|
||||||
|
Synth: MockedNode,
|
||||||
|
PolySynth: MockedNode,
|
||||||
|
Chorus: MockedNode,
|
||||||
|
Freeverb: MockedNode,
|
||||||
|
Gain: MockedNode,
|
||||||
|
vol: mockNode,
|
||||||
|
out: id,
|
||||||
|
osc: id,
|
||||||
|
adsr: id,
|
||||||
|
getDestination: id,
|
||||||
|
players: mockNode,
|
||||||
|
sampler: mockNode,
|
||||||
|
synth: mockNode,
|
||||||
|
piano: mockNode,
|
||||||
|
polysynth: mockNode,
|
||||||
|
fmsynth: mockNode,
|
||||||
|
membrane: mockNode,
|
||||||
|
noise: mockNode,
|
||||||
|
metal: mockNode,
|
||||||
|
lowpass: mockNode,
|
||||||
|
highpass: mockNode,
|
||||||
|
};
|
||||||
|
|
||||||
|
// tone mock
|
||||||
|
strudel.Pattern.prototype.tone = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// draw mock
|
||||||
|
strudel.Pattern.prototype.pianoroll = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// speak mock
|
||||||
|
strudel.Pattern.prototype.speak = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// webaudio mock
|
||||||
|
strudel.Pattern.prototype.wave = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
strudel.Pattern.prototype.filter = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
strudel.Pattern.prototype.adsr = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
strudel.Pattern.prototype.out = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
// tune mock
|
||||||
|
strudel.Pattern.prototype.tune = function () {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
const uiHelpersMocked = {
|
||||||
|
backgroundImage: id,
|
||||||
|
};
|
||||||
|
|
||||||
|
extend(
|
||||||
|
// Tone,
|
||||||
|
strudel,
|
||||||
|
strudel.Pattern.prototype.bootstrap(),
|
||||||
|
toneHelpersMocked,
|
||||||
|
uiHelpersMocked,
|
||||||
|
/* controls,
|
||||||
|
toneHelpers,
|
||||||
|
voicingHelpers,
|
||||||
|
drawHelpers,
|
||||||
|
uiHelpers,
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
// gist,
|
||||||
|
// euclid,
|
||||||
|
mini,
|
||||||
|
// Tone,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const queryCode = async (code, cycles) => {
|
||||||
|
const { pattern } = await evaluate(code);
|
||||||
|
const haps = pattern.queryArc(0, cycles);
|
||||||
|
return haps.map((h) => h.showWhole());
|
||||||
|
};
|
||||||
11
repl/src/shoot.mjs
Normal file
11
repl/src/shoot.mjs
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// this script will render all example tunes and log them to the console.
|
||||||
|
// it is intended to be written to tunes.snapshot.mjs using `npm run snapshot`
|
||||||
|
|
||||||
|
import * as tunes from '../tunes.mjs';
|
||||||
|
import { queryCode } from './runtime.mjs';
|
||||||
|
|
||||||
|
Object.entries(tunes).forEach(([key, code]) => {
|
||||||
|
queryCode(code, 1).then((haps) => {
|
||||||
|
console.log(`export const ${key} = ${JSON.stringify(haps, null, 1)}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
14
repl/src/test/tunes.test.mjs
Normal file
14
repl/src/test/tunes.test.mjs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { queryCode } from '../runtime.mjs';
|
||||||
|
import * as snaps from '../tunes.snapshot.mjs';
|
||||||
|
import * as tunes from '../tunes.mjs';
|
||||||
|
import { strict as assert } from 'assert';
|
||||||
|
|
||||||
|
describe('tunes', () => {
|
||||||
|
it('renders tunes correctly', async () => {
|
||||||
|
async function testTune(key) {
|
||||||
|
const haps = await queryCode(tunes[key], 1);
|
||||||
|
assert.deepStrictEqual(haps, snaps[key]);
|
||||||
|
}
|
||||||
|
await Promise.all(Object.keys(tunes).map(testTune));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -285,9 +285,9 @@ export const zeldasRescue = `stack(
|
||||||
)`;
|
)`;
|
||||||
|
|
||||||
export const technoDrums = `stack(
|
export const technoDrums = `stack(
|
||||||
"c1*2".tone(new Tone.MembraneSynth().toDestination()),
|
"c1*2".tone(new MembraneSynth().toDestination()),
|
||||||
"~ x".tone(new Tone.NoiseSynth().toDestination()),
|
"~ x".tone(new NoiseSynth().toDestination()),
|
||||||
"[~ c4]*2".tone(new Tone.MetalSynth().set({envelope:{decay:0.06,sustain:0}}).chain(new Gain(0.5),getDestination()))
|
"[~ c4]*2".tone(new MetalSynth().set({envelope:{decay:0.06,sustain:0}}).chain(new Gain(0.5),getDestination()))
|
||||||
)`;
|
)`;
|
||||||
|
|
||||||
export const loungerave = `const delay = new FeedbackDelay(1/8, .2).chain(vol(0.5), out());
|
export const loungerave = `const delay = new FeedbackDelay(1/8, .2).chain(vol(0.5), out());
|
||||||
|
|
|
||||||
1123
repl/src/tunes.snapshot.mjs
Normal file
1123
repl/src/tunes.snapshot.mjs
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue