diff --git a/ci/docker/install_node.sh b/ci/docker/install_node.sh index f690f8dd..7ae5c56a 100755 --- a/ci/docker/install_node.sh +++ b/ci/docker/install_node.sh @@ -3,8 +3,8 @@ set -e "$(dirname $0)/install.sh" \ - 'https://nodejs.org/dist/v12.22.12/node-v12.22.12-linux-x64.tar.xz' \ - 'e6d052364bfa2c17da92cf31794100cfd709ba147415ddaeed2222eec9ca1469' + 'https://unofficial-builds.nodejs.org/download/release/v22.22.0/node-v22.22.0-linux-x64-glibc-217.tar.xz' \ + 'db4a1d582e6fffcf7fb348149ca4ac8fa685699c5bc46cd7e22bbf9a7e673454' export PATH="/usr/local/bin:$PATH" diff --git a/js/api_tests/package.json b/js/api_tests/package.json index 08e60ea4..0860c069 100644 --- a/js/api_tests/package.json +++ b/js/api_tests/package.json @@ -9,7 +9,7 @@ "license": "MIT", "private": true, "scripts": { - "test": "qunit src/main.js" + "test": "vitest" }, "dependencies": { "axios": "^0.21.2", @@ -17,7 +17,7 @@ "lodash": "^4.17.21", "mkdirp": "^1.0.4", "picomatch": "^4.0.3", - "qunit": "^2.19.3", - "rimraf": "^3.0.2" + "rimraf": "^3.0.2", + "vitest": "^4.0.17" } } diff --git a/js/api_tests/sources.cmake b/js/api_tests/sources.cmake index 27ec57d2..efc49bb1 100644 --- a/js/api_tests/sources.cmake +++ b/js/api_tests/sources.cmake @@ -10,7 +10,6 @@ src/client_config_api_tests.js src/event_expectation.js src/http_features_tests.js src/install_app.js -src/main.js src/outputs_api_tests.js src/permissions_tests.js src/play_queue_api_tests.js diff --git a/js/api_tests/src/artwork_api_tests.js b/js/api_tests/src/artwork_api_tests.js index 113260df..8e384e42 100644 --- a/js/api_tests/src/artwork_api_tests.js +++ b/js/api_tests/src/artwork_api_tests.js @@ -1,10 +1,9 @@ import path from 'path'; -import { promisify } from 'util'; import fs from 'fs'; -import q from 'qunit'; -import { client, config, tracks, usePlayer } from './test_env.js'; +import { describe, test, assert } from 'vitest'; +import { client, config, tracks, setupPlayer } from './test_env.js'; -const readFile = promisify(fs.readFile); +const readFile = fs.promises.readFile; function getFile(name) { @@ -27,58 +26,60 @@ function getArtwork(playlist, item) }); } -q.module('artwork 1', usePlayer()); +describe('artwork 1', () => { + setupPlayer(); -q.test('get from folder', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.waitPlaybackMetadata(); + test('get from folder', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.waitPlaybackMetadata(); - const expected = await getFile('cover.png'); - const response = await getArtwork(0, 0); + const expected = await getFile('cover.png'); + const response = await getArtwork(0, 0); - assert.equal(response.status, 200); - assert.equal(response.headers['content-type'], 'image/png'); - assert.ok(response.data.equals(expected)); -}); + assert.equal(response.status, 200); + assert.equal(response.headers['content-type'], 'image/png'); + assert.ok(response.data.equals(expected)); + }); -q.test('get current', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.play(0, 0); - await client.waitForState('playing'); - await client.waitPlaybackMetadata(); + test('get current', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.play(0, 0); + await client.waitForState('playing'); + await client.waitPlaybackMetadata(); - const expected = await getFile('cover.png'); - const response = await getCurrentArtwork(); + const expected = await getFile('cover.png'); + const response = await getCurrentArtwork(); - assert.equal(response.status, 200); - assert.equal(response.headers['content-type'], 'image/png'); - assert.ok(response.data.equals(expected)); + assert.equal(response.status, 200); + assert.equal(response.headers['content-type'], 'image/png'); + assert.ok(response.data.equals(expected)); + }); }); -q.module('artwork 2', usePlayer()); +describe('artwork 2', () => { + setupPlayer(); -q.test('get from tag', async assert => -{ - await client.addPlaylistItems(0, [tracks.t2Alt]); - await client.waitPlaybackMetadata(); + test('get from tag', async () => { + await client.addPlaylistItems(0, [tracks.t2Alt]); + await client.waitPlaybackMetadata(); - const expected = await getFile('cover-white.png.hidden'); - const response = await getArtwork(0, 0); + const expected = await getFile('cover-white.png.hidden'); + const response = await getArtwork(0, 0); - assert.equal(response.status, 200); - assert.equal(response.headers['content-type'], 'image/png'); - assert.ok(response.data.equals(expected)); + assert.equal(response.status, 200); + assert.equal(response.headers['content-type'], 'image/png'); + assert.ok(response.data.equals(expected)); + }); }); -q.module('artwork 3', usePlayer()); +describe('artwork 3', () => { + setupPlayer(); -q.test('missing', async assert => -{ - await client.addPlaylistItems(0, [tracks.t3]); - await client.waitPlaybackMetadata(); + test('missing', async () => { + await client.addPlaylistItems(0, [tracks.t3]); + await client.waitPlaybackMetadata(); - const response = await getArtwork(0, 0); - assert.equal(response.status, 404); + const response = await getArtwork(0, 0); + assert.equal(response.status, 404); + }); }); diff --git a/js/api_tests/src/authentication_tests.js b/js/api_tests/src/authentication_tests.js index 9da3c6b9..de2f3854 100644 --- a/js/api_tests/src/authentication_tests.js +++ b/js/api_tests/src/authentication_tests.js @@ -1,6 +1,6 @@ -import q from 'qunit'; +import { describe, test, assert } from 'vitest'; import lodash from 'lodash'; -import { client, usePlayer } from './test_env.js'; +import { client, setupPlayer } from './test_env.js'; const { startsWith } = lodash; @@ -30,34 +30,33 @@ function makeRequest(config) return client.handler.axios.get('api/player', fullConfig); } -q.module('authentication', usePlayer({ pluginSettings, axiosConfig })); +describe('authentication', () => { + setupPlayer({ pluginSettings, axiosConfig }); -q.test('require auth', async assert => -{ - const response = await makeRequest(); - - assert.equal(response.status, 401); - assert.ok(response.data && response.data.error); - assert.ok(startsWith(response.headers['www-authenticate'], 'Basic')); -}); + test('require auth', async () => { + const response = await makeRequest(); -q.test('invalid auth', async assert => -{ - const response = await makeRequest({ - auth: { username: authUser, password: 'wrong' } + assert.equal(response.status, 401); + assert.ok(response.data && response.data.error); + assert.ok(startsWith(response.headers['www-authenticate'], 'Basic')); }); - assert.equal(response.status, 401); - assert.ok(response.data && response.data.error); - assert.ok(startsWith(response.headers['www-authenticate'], 'Basic')); -}); + test('invalid auth', async () => { + const response = await makeRequest({ + auth: { username: authUser, password: 'wrong' } + }); -q.test('valid auth', async assert => -{ - const response = await makeRequest({ - auth: { username: authUser, password: authPassword } + assert.equal(response.status, 401); + assert.ok(response.data && response.data.error); + assert.ok(startsWith(response.headers['www-authenticate'], 'Basic')); }); - assert.equal(response.status, 200); - assert.ok(response.data && response.data.player); + test('valid auth', async () => { + const response = await makeRequest({ + auth: { username: authUser, password: authPassword } + }); + + assert.equal(response.status, 200); + assert.ok(response.data && response.data.player); + }); }); diff --git a/js/api_tests/src/browser_api_tests.js b/js/api_tests/src/browser_api_tests.js index aca0e627..5eae8e63 100644 --- a/js/api_tests/src/browser_api_tests.js +++ b/js/api_tests/src/browser_api_tests.js @@ -1,14 +1,11 @@ import path from 'path'; -import { promisify } from 'util'; import fs from 'fs'; -import q from 'qunit'; -import lodash from 'lodash'; -import { client, config, usePlayer } from './test_env.js'; +import { omit, sortBy } from 'lodash'; +import { describe, test, assert } from 'vitest'; +import { client, config, setupPlayer } from './test_env.js'; -const { omit, sortBy } = lodash; - -const readdir = promisify(fs.readdir); -const stat = promisify(fs.stat); +const readdir = fs.promises.readdir; +const stat = fs.promises.stat; const musicSubdir = path.join(config.musicDir, 'subdir'); @@ -50,38 +47,37 @@ async function getFileSystemEntriesDirect(dirPath) return sortBy(items, ['type', 'path']); } -q.module('browser api', usePlayer()); - -q.test('get roots', async assert => -{ - const result = await client.getFileSystemRoots() - const actual = normalizeResult(result.roots); - const expected = [{ - name: config.musicDir, - path: config.musicDir, - type: 'D', - }]; - - assert.ok(isPathSeparator(result.pathSeparator)); - assert.deepEqual(actual, expected); -}); - -q.test('get entries root', async assert => -{ - const result = await client.getFileSystemEntries(config.musicDir); - const expected = await getFileSystemEntriesDirect(config.musicDir); - const actual = normalizeResult(result.entries); - - assert.ok(isPathSeparator(result.pathSeparator)); - assert.deepEqual(actual, expected); -}); - -q.test('get entries subdir', async assert => -{ - const result = await client.getFileSystemEntries(musicSubdir); - const expected = await getFileSystemEntriesDirect(musicSubdir); - const actual = normalizeResult(result.entries); - - assert.ok(isPathSeparator(result.pathSeparator)); - assert.deepEqual(actual, expected); -}); +describe('browser api', () => { + setupPlayer(); + + test('get roots', async () => { + const result = await client.getFileSystemRoots() + const actual = normalizeResult(result.roots); + const expected = [{ + name: config.musicDir, + path: config.musicDir, + type: 'D', + }]; + + assert.ok(isPathSeparator(result.pathSeparator)); + assert.deepEqual(actual, expected); + }); + + test('get entries root', async () => { + const result = await client.getFileSystemEntries(config.musicDir); + const expected = await getFileSystemEntriesDirect(config.musicDir); + const actual = normalizeResult(result.entries); + + assert.ok(isPathSeparator(result.pathSeparator)); + assert.deepEqual(actual, expected); + }); + + test('get entries subdir', async () => { + const result = await client.getFileSystemEntries(musicSubdir); + const expected = await getFileSystemEntriesDirect(musicSubdir); + const actual = normalizeResult(result.entries); + + assert.ok(isPathSeparator(result.pathSeparator)); + assert.deepEqual(actual, expected); + }); +}); \ No newline at end of file diff --git a/js/api_tests/src/client_config_api_tests.js b/js/api_tests/src/client_config_api_tests.js index a04fe1d5..387f602d 100644 --- a/js/api_tests/src/client_config_api_tests.js +++ b/js/api_tests/src/client_config_api_tests.js @@ -1,22 +1,23 @@ -import q from 'qunit'; -import { client, usePlayer } from './test_env.js'; +import { describe, test, assert } from 'vitest'; +import { client, setupPlayer } from './test_env.js'; -q.module('client config api', usePlayer()); +describe('client config api', () => { + setupPlayer(); -q.test('client config', async assert => -{ - const id = 'api_test_' + Math.round(1000000 * Math.random()); + test('client config', async () => { + const id = 'api_test_' + Math.round(1000000 * Math.random()); - const config1 = await client.getClientConfig(id); - assert.equal(config1, null); + const config1 = await client.getClientConfig(id); + assert.equal(config1, null); - const value = { prop1: true, prop2: 'hello', prop3: { prop4: 123, prop5: [ 'item' ] } }; - await client.setClientConfig(id, value); + const value = { prop1: true, prop2: 'hello', prop3: { prop4: 123, prop5: ['item'] } }; + await client.setClientConfig(id, value); - const config2 = await client.getClientConfig(id); - assert.deepEqual(config2, value); + const config2 = await client.getClientConfig(id); + assert.deepEqual(config2, value); - await client.removeClientConfig(id); - const config3 = await client.getClientConfig(id); - assert.deepEqual(config3, null); + await client.removeClientConfig(id); + const config3 = await client.getClientConfig(id); + assert.deepEqual(config3, null); + }); }); diff --git a/js/api_tests/src/http_features_tests.js b/js/api_tests/src/http_features_tests.js index ade8ea5b..7eaf5ee5 100644 --- a/js/api_tests/src/http_features_tests.js +++ b/js/api_tests/src/http_features_tests.js @@ -1,5 +1,5 @@ -import q from 'qunit'; -import { client, tracks, usePlayer } from './test_env.js'; +import { describe, test, assert } from 'vitest'; +import { client, tracks, setupPlayer } from './test_env.js'; const expectedValue = 'Very Custom, Much Configurable, Wow'; @@ -9,25 +9,25 @@ const pluginSettings = { } }; -q.module('http features', usePlayer({ pluginSettings })); +describe('http features', () => { + setupPlayer({ pluginSettings }); -q.test('custom headers', async assert => -{ - const response = await client.handler.axios.get('/api/player'); + test('custom headers', async () => { + const response = await client.handler.axios.get('/api/player'); - assert.strictEqual(response.headers['x-customheader'], expectedValue); -}); + assert.strictEqual(response.headers['x-customheader'], expectedValue); + }); -q.test('custom headers for async method', async assert => -{ - const response = await client.handler.axios.post('/api/playlists/0/items/add', { items: [tracks.t1] }); + test('custom headers for async method', async () => { + const response = await client.handler.axios.post('/api/playlists/0/items/add', { items: [tracks.t1] }); - assert.strictEqual(response.headers['x-customheader'], expectedValue); -}); + assert.strictEqual(response.headers['x-customheader'], expectedValue); + }); -q.test('options method', async assert => -{ - const response = await client.handler.axios.options('/api/player'); + test('options method', async () => { + const response = await client.handler.axios.options('/api/player'); - assert.strictEqual(response.headers['x-customheader'], expectedValue); -}); + assert.strictEqual(response.headers['x-customheader'], expectedValue); + }); + +}); \ No newline at end of file diff --git a/js/api_tests/src/main.js b/js/api_tests/src/main.js deleted file mode 100644 index fa678ac3..00000000 --- a/js/api_tests/src/main.js +++ /dev/null @@ -1,12 +0,0 @@ -import './artwork_api_tests.js'; -import './authentication_tests.js'; -import './browser_api_tests.js'; -import './client_config_api_tests.js' -import './http_features_tests.js'; -import './outputs_api_tests.js'; -import './permissions_tests.js'; -import './player_api_tests.js'; -import './playlists_api_tests.js'; -import './play_queue_api_tests.js' -import './query_api_tests.js'; -import './static_files_tests.js'; diff --git a/js/api_tests/src/outputs_api_tests.js b/js/api_tests/src/outputs_api_tests.js index a0daeef2..b2807322 100644 --- a/js/api_tests/src/outputs_api_tests.js +++ b/js/api_tests/src/outputs_api_tests.js @@ -1,33 +1,33 @@ -import q from 'qunit'; -import { client, outputConfigs, usePlayer } from './test_env.js'; +import { describe, test, assert } from 'vitest'; +import { client, outputConfigs, setupPlayer } from './test_env.js'; -q.module('outputs api', usePlayer()); +describe('outputs api', () => { + setupPlayer(); -q.test('get outputs config', async assert => -{ - const outputs = await client.getOutputs(); + test('get outputs config', async () => { + const outputs = await client.getOutputs(); - assert.ok(typeof outputs.supportsMultipleOutputTypes === 'boolean'); - assert.deepEqual(outputs.active, outputConfigs.default); - assert.ok(Array.isArray(outputs.types)); + assert.ok(typeof outputs.supportsMultipleOutputTypes === 'boolean'); + assert.deepEqual(outputs.active, outputConfigs.default); + assert.ok(Array.isArray(outputs.types)); - const type = outputs.types[0]; - assert.ok(type.id); - assert.ok(type.name); - assert.ok(Array.isArray(type.devices)); + const type = outputs.types[0]; + assert.ok(type.id); + assert.ok(type.name); + assert.ok(Array.isArray(type.devices)); - const device = type.devices[0]; - assert.ok(device.id); - assert.ok(device.name); -}); + const device = type.devices[0]; + assert.ok(device.id); + assert.ok(device.name); + }); -q.test('set output device', async assert => -{ - for (const config of outputConfigs.alternate) - { - await client.setOutputDevice(config.typeId, config.deviceId); - const output = (await client.getOutputs()).active; - assert.equal(output.typeId, config.typeId); - assert.equal(output.deviceId, config.deviceId); - } + test('set output device', async () => { + for (const config of outputConfigs.alternate) + { + await client.setOutputDevice(config.typeId, config.deviceId); + const output = (await client.getOutputs()).active; + assert.equal(output.typeId, config.typeId); + assert.equal(output.deviceId, config.deviceId); + } + }); }); diff --git a/js/api_tests/src/permissions_tests.js b/js/api_tests/src/permissions_tests.js index 12978d24..7e543710 100644 --- a/js/api_tests/src/permissions_tests.js +++ b/js/api_tests/src/permissions_tests.js @@ -1,5 +1,5 @@ -import q from 'qunit'; -import { client, outputConfigs, usePlayer } from './test_env.js'; +import { describe, test, assert } from 'vitest'; +import { client, outputConfigs, setupPlayer } from './test_env.js'; const pluginSettings = { permissions: { @@ -23,28 +23,26 @@ function post(path, data) return client.handler.axios.post(path, data, axiosConfig); } -q.module('permissions', usePlayer({ pluginSettings, resetOptions })); +describe('permissions', () => { + setupPlayer({ pluginSettings, resetOptions }); -q.test('get permissions', async assert => -{ - const state = await client.getPlayerState(); - assert.deepEqual(state.permissions, pluginSettings.permissions); -}); + test('get permissions', async () => { + const state = await client.getPlayerState(); + assert.deepEqual(state.permissions, pluginSettings.permissions); + }); -q.test('change playlist', async assert => -{ - const response = await post('/api/playlists/add'); - assert.equal(response.status, 403); -}); + test('change playlist', async () => { + const response = await post('/api/playlists/add'); + assert.equal(response.status, 403); + }); -q.test('change output', async assert => -{ - const response = await post('/api/outputs/active', outputConfigs.alternate[0]); - assert.equal(response.status, 403); -}); + test('change output', async () => { + const response = await post('/api/outputs/active', outputConfigs.alternate[0]); + assert.equal(response.status, 403); + }); -q.test('change client config', async assert => -{ - const response = await post('/api/clientconfig/perm_test', {}); - assert.equal(response.status, 403); + test('change client config', async () => { + const response = await post('/api/clientconfig/perm_test', {}); + assert.equal(response.status, 403); + }); }); diff --git a/js/api_tests/src/play_queue_api_tests.js b/js/api_tests/src/play_queue_api_tests.js index 4596c5f9..929110ab 100644 --- a/js/api_tests/src/play_queue_api_tests.js +++ b/js/api_tests/src/play_queue_api_tests.js @@ -1,5 +1,6 @@ -import q from 'qunit'; -import { client, config, tracks, usePlayer } from './test_env.js'; +import { describe, test, assert } from 'vitest'; +import { client, config, tracks, setupPlayer } from './test_env.js'; +import { PlayerId } from './test_context.js'; // DeaDBeeF clears play queue asynchronously on stop // Avoid resetting player state for stable runs @@ -7,8 +8,6 @@ const resetOptions = { playerState: false }; -q.module('play queue api', usePlayer({ resetOptions })); - async function setupTracks() { await client.addPlaylist(); @@ -25,87 +24,81 @@ async function setupTracks() return [p1, p2]; } -q.test('get play queue with columns', async assert => { - const [p1] = await setupTracks(); +describe('play queue api', () => { + setupPlayer({ resetOptions }); - await client.addToPlayQueue(p1, 0); - await client.addToPlayQueue(p1, 1); + test('get play queue with columns', async () => { + const [p1] = await setupTracks(); - const queue = await client.getPlayQueue(['%artist%', '%title%']); + await client.addToPlayQueue(p1, 0); + await client.addToPlayQueue(p1, 1); - assert.deepEqual(queue, [ - { playlistIndex: 0, playlistId: p1, itemIndex: 0, columns: ['Hyperblast', 'Silence Rocks - Part 1'] }, - { playlistIndex: 0, playlistId: p1, itemIndex: 1, columns: ['Hyperblast', 'Silence Rocks - Part 2'] }, - ]); -}) + const queue = await client.getPlayQueue(['%artist%', '%title%']); -q.test('add to queue', async assert => -{ - const [p1, p2] = await setupTracks(); + assert.deepEqual(queue, [ + { playlistIndex: 0, playlistId: p1, itemIndex: 0, columns: ['Hyperblast', 'Silence Rocks - Part 1'] }, + { playlistIndex: 0, playlistId: p1, itemIndex: 1, columns: ['Hyperblast', 'Silence Rocks - Part 2'] }, + ]); + }); - await client.addToPlayQueue(p1, 1); - await client.addToPlayQueue(1, 0); + test('add to queue', async () => { + const [p1, p2] = await setupTracks(); - const queue = await client.getPlayQueue(); + await client.addToPlayQueue(p1, 1); + await client.addToPlayQueue(1, 0); - assert.deepEqual(queue, [ - { playlistIndex: 0, playlistId: p1, itemIndex: 1, columns: [] }, - { playlistIndex: 1, playlistId: p2, itemIndex: 0, columns: [] }, - ]); -}); + const queue = await client.getPlayQueue(); -q.test('add to queue at index', async assert => -{ - if (config.playerId !== 'deadbeef') - { - assert.ok('adding to queue at index is not supported by current player'); - return; - } + assert.deepEqual(queue, [ + { playlistIndex: 0, playlistId: p1, itemIndex: 1, columns: [] }, + { playlistIndex: 1, playlistId: p2, itemIndex: 0, columns: [] }, + ]); + }); - const [p1, p2] = await setupTracks(); + test('add to queue at index', { skip: config.playerId !== PlayerId.deadbeef }, async () => { + const [p1, p2] = await setupTracks(); - await client.addToPlayQueue(p1, 0); - await client.addToPlayQueue(0, 1, 1); - await client.addToPlayQueue(p2, 0, 0); + await client.addToPlayQueue(p1, 0); + await client.addToPlayQueue(0, 1, 1); + await client.addToPlayQueue(p2, 0, 0); - let queue = await client.getPlayQueue(); + let queue = await client.getPlayQueue(); - assert.deepEqual(queue, [ - { playlistIndex: 1, playlistId: p2, itemIndex: 0, columns: [] }, - { playlistIndex: 0, playlistId: p1, itemIndex: 0, columns: [] }, - { playlistIndex: 0, playlistId: p1, itemIndex: 1, columns: [] }, - ]); -}); + assert.deepEqual(queue, [ + { playlistIndex: 1, playlistId: p2, itemIndex: 0, columns: [] }, + { playlistIndex: 0, playlistId: p1, itemIndex: 0, columns: [] }, + { playlistIndex: 0, playlistId: p1, itemIndex: 1, columns: [] }, + ]); + }); -q.test('remove from queue', async assert => -{ - const [p1, p2] = await setupTracks(); + test('remove from queue', async () => { + const [p1, p2] = await setupTracks(); - await client.addToPlayQueue(p1, 0); - await client.addToPlayQueue(p1, 1); - await client.addToPlayQueue(p2, 0); + await client.addToPlayQueue(p1, 0); + await client.addToPlayQueue(p1, 1); + await client.addToPlayQueue(p2, 0); - await client.removeFromPlayQueueByQueueIndex(0); - await client.removeFromPlayQueueByItemIndex(p2, 0); + await client.removeFromPlayQueueByQueueIndex(0); + await client.removeFromPlayQueueByItemIndex(p2, 0); - let queue = await client.getPlayQueue(); + let queue = await client.getPlayQueue(); - assert.deepEqual(queue, [ - { playlistIndex: 0, playlistId: p1, itemIndex: 1, columns: [] }, - ]); -}); + assert.deepEqual(queue, [ + { playlistIndex: 0, playlistId: p1, itemIndex: 1, columns: [] }, + ]); + }); -q.test('clear queue', async assert => -{ - const [p1, p2] = await setupTracks(); + test('clear queue', async () => { + const [p1, p2] = await setupTracks(); - await client.addToPlayQueue(p1, 0); - await client.addToPlayQueue(p1, 1); - await client.addToPlayQueue(p2, 0); + await client.addToPlayQueue(p1, 0); + await client.addToPlayQueue(p1, 1); + await client.addToPlayQueue(p2, 0); - await client.clearPlayQueue(); + await client.clearPlayQueue(); - let queue = await client.getPlayQueue(); + let queue = await client.getPlayQueue(); - assert.equal(queue.length, 0); -}); + assert.equal(queue.length, 0); + }); +}); \ No newline at end of file diff --git a/js/api_tests/src/player_api_tests.js b/js/api_tests/src/player_api_tests.js index 1f3327fe..011dee67 100644 --- a/js/api_tests/src/player_api_tests.js +++ b/js/api_tests/src/player_api_tests.js @@ -1,372 +1,352 @@ -import q from 'qunit'; -import { client, config, tracks, usePlayer } from './test_env.js'; - -q.module('player api', usePlayer()); - -q.test('get state', async assert => -{ - const state = await client.getPlayerState(); - assert.ok(state); - - const { info, activeItem, playbackState, volume, playbackMode, playbackModes } = state; - - assert.ok(info); - assert.ok(info.name); - assert.ok(info.title); - assert.ok(info.version); - assert.ok(info.pluginVersion); - - assert.ok(activeItem); - const { playlistId, playlistIndex, index, position, duration } = activeItem; - assert.equal(typeof playlistId, 'string'); - assert.equal(typeof playlistIndex, 'number'); - assert.equal(typeof index, 'number'); - assert.equal(typeof position, 'number'); - assert.equal(typeof duration, 'number'); - - assert.ok(playbackState); - assert.equal(typeof playbackState, 'string'); - - assert.ok(volume); - const { type, min, max, value, isMuted } = volume; - assert.equal(typeof type, 'string'); - assert.equal(typeof min, 'number'); - assert.equal(typeof max, 'number'); - assert.equal(typeof value, 'number'); - assert.equal(typeof isMuted, 'boolean'); - - assert.equal(typeof playbackMode, 'number'); - assert.ok(Array.isArray(playbackModes)); -}); +import { describe, test, assert } from 'vitest' +import { client, config, tracks, setupPlayer } from './test_env.js'; + +describe('player api', () => { + setupPlayer(); + + test('get state', async () => { + const state = await client.getPlayerState(); + assert.ok(state); + + const { info, activeItem, playbackState, volume, playbackMode, playbackModes } = state; + + assert.ok(info); + assert.ok(info.name); + assert.ok(info.title); + assert.ok(info.version); + assert.ok(info.pluginVersion); + + assert.ok(activeItem); + const { playlistId, playlistIndex, index, position, duration } = activeItem; + assert.equal(typeof playlistId, 'string'); + assert.equal(typeof playlistIndex, 'number'); + assert.equal(typeof index, 'number'); + assert.equal(typeof position, 'number'); + assert.equal(typeof duration, 'number'); + + assert.ok(playbackState); + assert.equal(typeof playbackState, 'string'); + + assert.ok(volume); + const { type, min, max, value, isMuted } = volume; + assert.equal(typeof type, 'string'); + assert.equal(typeof min, 'number'); + assert.equal(typeof max, 'number'); + assert.equal(typeof value, 'number'); + assert.equal(typeof isMuted, 'boolean'); + + assert.equal(typeof playbackMode, 'number'); + assert.ok(Array.isArray(playbackModes)); + }); -q.test('query current track', async assert => -{ - await client.addPlaylistItems(0, [tracks.t3]); - - await client.play(0, 0); - await client.waitForState('playing'); - await client.waitPlaybackMetadata(); - - let backslash = '\\'; - - if (config.playerId === 'deadbeef') - backslash = '\\\\'; - - const state = await client.getPlayerState([ - '%genre%', - '%artist%', - '%album%', - '%tracknumber%', - '%title%', - '%length%', - ` %artist% ${backslash} %album%, %title% `, - ]); - - assert.deepEqual(state.activeItem.columns, [ - 'Ambient', - 'Hyperblast', - 'Silence Rocks', - '03', - 'Silence Rocks - Part 3', - '1:10', - ' Hyperblast \\ Silence Rocks, Silence Rocks - Part 3 ' - ]); -}); + test('query current track', async () => { + await client.addPlaylistItems(0, [tracks.t3]); + + await client.play(0, 0); + await client.waitForState('playing'); + await client.waitPlaybackMetadata(); + + let backslash = '\\'; + + if (config.playerId === 'deadbeef') + backslash = '\\\\'; + + const state = await client.getPlayerState([ + '%genre%', + '%artist%', + '%album%', + '%tracknumber%', + '%title%', + '%length%', + ` %artist% ${backslash} %album%, %title% `, + ]); + + assert.deepEqual(state.activeItem.columns, [ + 'Ambient', + 'Hyperblast', + 'Silence Rocks', + '03', + 'Silence Rocks - Part 3', + '1:10', + ' Hyperblast \\ Silence Rocks, Silence Rocks - Part 3 ' + ]); + }); -q.test('set volume absolute', async assert => -{ - let state = await client.getPlayerState(); - const newVolume = (state.volume.min + state.volume.max) / 2; - await client.setVolume(newVolume); + test('set volume absolute', async () => { + let state = await client.getPlayerState(); + const newVolume = (state.volume.min + state.volume.max) / 2; + await client.setVolume(newVolume); - state = await client.getPlayerState(); - assert.equal(state.volume.value, newVolume); -}); + state = await client.getPlayerState(); + assert.equal(state.volume.value, newVolume); + }); -q.test('set volume relative', async assert => -{ - const state1 = await client.getPlayerState(); + test('set volume relative', async () => { + const state1 = await client.getPlayerState(); - await client.setVolumeRelative(-1); - const state2 = await client.getPlayerState(); - assert.ok(state2.volume.value < state1.volume.value); + await client.setVolumeRelative(-1); + const state2 = await client.getPlayerState(); + assert.ok(state2.volume.value < state1.volume.value); - await client.setVolumeRelative(1); - const state3 = await client.getPlayerState(); - assert.equal(state3.volume.value, state1.volume.value); -}); + await client.setVolumeRelative(1); + const state3 = await client.getPlayerState(); + assert.equal(state3.volume.value, state1.volume.value); + }); -q.test('volume up/down', async assert => -{ - const state1 = await client.getPlayerState(); + test('volume up/down', async () => { + const state1 = await client.getPlayerState(); - await client.volumeDown(); - const state2 = await client.getPlayerState(); - assert.ok(state2.volume.value < state1.volume.value); + await client.volumeDown(); + const state2 = await client.getPlayerState(); + assert.ok(state2.volume.value < state1.volume.value); - await client.volumeUp(); - const state3 = await client.getPlayerState(); - assert.equal(state3.volume.value, state1.volume.value); -}); + await client.volumeUp(); + const state3 = await client.getPlayerState(); + assert.equal(state3.volume.value, state1.volume.value); + }); -q.test('set muted', async assert => -{ - await client.setMuted(true); + test('set muted', async () => { + await client.setMuted(true); - const state = await client.getPlayerState(); - assert.equal(state.volume.isMuted, true); -}); + const state = await client.getPlayerState(); + assert.equal(state.volume.isMuted, true); + }); -q.test('set playback mode', async assert => -{ - let state = await client.getPlayerState(); - const newMode = state.playbackModes.length - 1; - await client.setPlaybackMode(newMode); + test('set playback mode', async () => { + let state = await client.getPlayerState(); + const newMode = state.playbackModes.length - 1; + await client.setPlaybackMode(newMode); - state = await client.getPlayerState(); - assert.equal(state.playbackMode, newMode); -}); + state = await client.getPlayerState(); + assert.equal(state.playbackMode, newMode); + }); -q.test('set bool option', async assert => -{ - let state = await client.getPlayerState(); - let option = state.options.find(o => o.type === 'bool'); - assert.ok(option.name); - assert.equal(option.value, false); + test('set bool option', async () => { + let state = await client.getPlayerState(); + let option = state.options.find(o => o.type === 'bool'); + assert.ok(option.name); + assert.equal(option.value, false); - await client.setOption(option.id, true); + await client.setOption(option.id, true); - state = await client.getPlayerState(); - option = state.options.find(o => o.id === option.id); - assert.ok(option.value); -}); + state = await client.getPlayerState(); + option = state.options.find(o => o.id === option.id); + assert.ok(option.value); + }); -q.test('set enum option', async assert => -{ - let state = await client.getPlayerState(); - let option = state.options.find(o => o.type === 'enum'); - assert.ok(option.name); - assert.ok(Array.isArray(option.enumNames)); - assert.equal(option.value, 0); + test('set enum option', async () => { + let state = await client.getPlayerState(); + let option = state.options.find(o => o.type === 'enum'); + assert.ok(option.name); + assert.ok(Array.isArray(option.enumNames)); + assert.equal(option.value, 0); - await client.setOption(option.id, 1); + await client.setOption(option.id, 1); - state = await client.getPlayerState(); - option = state.options.find(o => o.id === option.id); - assert.equal(option.value, 1); -}); + state = await client.getPlayerState(); + option = state.options.find(o => o.id === option.id); + assert.equal(option.value, 1); + }); -q.test('play', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); + test('play', async () => { + await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); - await client.play(0, 1); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 1; + await client.play(0, 1); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 1; + }); + + assert.ok(true); }); - assert.ok(true); -}); + test('stop', async () => { + await client.addPlaylistItems(0, [tracks.t1]); -q.test('stop', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); + await client.play(0, 0); + await client.waitForState('playing'); - await client.play(0, 0); - await client.waitForState('playing'); + await client.stop(); + await client.waitForState('stopped'); - await client.stop(); - await client.waitForState('stopped'); + assert.ok(true); + }); - assert.ok(true); -}); + test('play random', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); + await client.addPlaylistItems(0, [tracks.t3]); -q.test('play random', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); - await client.addPlaylistItems(0, [tracks.t3]); + await client.playRandom(); + await client.waitForState('playing'); - await client.playRandom(); - await client.waitForState('playing'); + assert.ok(true); + }); - assert.ok(true); -}); + test('play current', async () => { + await client.addPlaylistItems(0, [tracks.t1]); -q.test('play current', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); + await client.play(0, 0); + await client.waitForState('playing'); - await client.play(0, 0); - await client.waitForState('playing'); + await client.pause(); + await client.waitForState('paused'); - await client.pause(); - await client.waitForState('paused'); + await client.playCurrent(); + await client.waitForState('playing'); - await client.playCurrent(); - await client.waitForState('playing'); + assert.ok(true); + }); - assert.ok(true); -}); + test('pause', async () => { + await client.addPlaylistItems(0, [tracks.t1]); -q.test('pause', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); + await client.play(0, 0); + await client.waitForState('playing'); - await client.play(0, 0); - await client.waitForState('playing'); + await client.pause(); + await client.waitForState('paused'); - await client.pause(); - await client.waitForState('paused'); + assert.ok(true); + }); - assert.ok(true); -}); + test('toggle pause', async () => { + await client.addPlaylistItems(0, [tracks.t1]); -q.test('toggle pause', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); + await client.play(0, 0); + await client.waitForState('playing'); - await client.play(0, 0); - await client.waitForState('playing'); + await client.togglePause(); + await client.waitForState('paused'); - await client.togglePause(); - await client.waitForState('paused'); + await client.togglePause(); + await client.waitForState('playing'); - await client.togglePause(); - await client.waitForState('playing'); + assert.ok(true); + }); - assert.ok(true); -}); + test('play or pause', async () => { + await client.addPlaylistItems(0, [tracks.t1]); -q.test('play or pause', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); + await client.playOrPause(); + await client.waitForState('playing'); - await client.playOrPause(); - await client.waitForState('playing'); + await client.playOrPause(); + await client.waitForState('paused'); - await client.playOrPause(); - await client.waitForState('paused'); + await client.playOrPause(); + await client.waitForState('playing'); - await client.playOrPause(); - await client.waitForState('playing'); + assert.ok(true); + }); - assert.ok(true); -}); + test('next', async () => { + await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); -q.test('next', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); + await client.play(0, 0); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 0; + }); - await client.play(0, 0); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 0; - }); + await client.next(); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 1; + }); - await client.next(); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 1; + assert.ok(true); }); - assert.ok(true); -}); + test('next by', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); -q.test('next by', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); + await client.play(0, 0); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 0; + }); - await client.play(0, 0); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 0; - }); + await client.next({ by: '%title%' }); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 2; + }); - await client.next({ by: '%title%' }); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 2; + assert.ok(true); }); - assert.ok(true); -}); + test('previous', async () => { + await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); -q.test('previous', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); + await client.play(0, 1); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 1; + }); - await client.play(0, 1); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 1; - }); + await client.previous(); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 0; + }); - await client.previous(); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 0; + assert.ok(true); }); - assert.ok(true); -}); + test('previous by', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); + await client.addPlaylistItems(0, [tracks.t2]); -q.test('previous by', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); - await client.addPlaylistItems(0, [tracks.t2]); + await client.play(0, 2); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 2; + }); - await client.play(0, 2); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 2; - }); + await client.previous({ by: '%title%' }); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 0; + }); - await client.previous({ by: '%title%' }); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 0; + assert.ok(true); }); - assert.ok(true); -}); + test('set playback position', async () => { + await client.addPlaylistItems(0, [tracks.t3]); -q.test('set playback position', async assert => -{ - await client.addPlaylistItems(0, [tracks.t3]); + await client.play(0, 0); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 0; + }); - await client.play(0, 0); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 0; - }); + await client.pause(); + await client.waitForState('paused'); - await client.pause(); - await client.waitForState('paused'); + await client.setPlaybackPosition(33.0); + await client.waitForState(s => { + return s.activeItem.position === 33.0; + }); - await client.setPlaybackPosition(33.0); - await client.waitForState(s => { - return s.activeItem.position === 33.0; + assert.ok(true); }); - assert.ok(true); -}); + test('move playback position', async () => { + await client.addPlaylistItems(0, [tracks.t3]); -q.test('move playback position', async assert => -{ - await client.addPlaylistItems(0, [tracks.t3]); + await client.play(0, 0); + await client.waitForState(s => { + return s.playbackState === 'playing' && s.activeItem.index === 0; + }); - await client.play(0, 0); - await client.waitForState(s => { - return s.playbackState === 'playing' && s.activeItem.index === 0; - }); + await client.pause(); + await client.waitForState('paused'); - await client.pause(); - await client.waitForState('paused'); + await client.setPlaybackPosition(33.0); + await client.waitForState(s => { + return s.activeItem.position === 33.0; + }); - await client.setPlaybackPosition(33.0); - await client.waitForState(s => { - return s.activeItem.position === 33.0; - }); + await client.movePlaybackPosition(11.0); + await client.waitForState(s => { + return s.activeItem.position === 44.0; + }); - await client.movePlaybackPosition(11.0); - await client.waitForState(s => { - return s.activeItem.position === 44.0; + assert.ok(true); }); - - assert.ok(true); }); diff --git a/js/api_tests/src/playlists_api_tests.js b/js/api_tests/src/playlists_api_tests.js index 641d2e9b..ab248432 100644 --- a/js/api_tests/src/playlists_api_tests.js +++ b/js/api_tests/src/playlists_api_tests.js @@ -1,413 +1,384 @@ -import q from 'qunit'; +import { describe, test, assert } from 'vitest'; import { pathCollectionsEqual, waitUntil } from './utils.js'; -import { client, config, tracks, usePlayer } from './test_env.js'; +import { client, tracks, setupPlayer } from './test_env.js'; -q.module('playlists api', usePlayer()); +describe('playlists api', () => { + setupPlayer(); -function assertPlaylist(assert, playlist) -{ - assert.equal(typeof playlist.id, 'string'); - assert.equal(typeof playlist.title, 'string'); + function assertPlaylist(assert, playlist) + { + assert.equal(typeof playlist.id, 'string'); + assert.equal(typeof playlist.title, 'string'); + + delete playlist.id; + delete playlist.title; + + assert.deepEqual(playlist, { + index: 0, + isCurrent: true, + itemCount: 0, + totalTime: 0, + }); + } + + test('get playlists', async () => { + const playlists = await client.getPlaylists(); + + assert.ok(playlists); + assert.equal(playlists.length, 1); + + const playlist = playlists[0]; - delete playlist.id; - delete playlist.title; + assertPlaylist(assert, playlist); + }); + + test('get single playlist', async () => { + const p1 = await client.getPlaylist('current'); + const p2 = await client.getPlaylist(0); - assert.deepEqual(playlist, { - index: 0, - isCurrent: true, - itemCount: 0, - totalTime: 0, + assert.deepEqual(p1, p2); + assertPlaylist(assert, p1); }); -} - -q.test('get playlists', async assert => -{ - const playlists = await client.getPlaylists(); - - assert.ok(playlists); - assert.equal(playlists.length, 1); - - const playlist = playlists[0]; - - assertPlaylist(assert, playlist); -}); - -q.test('get single playlist', async assert => -{ - const p1 = await client.getPlaylist('current'); - const p2 = await client.getPlaylist(0); - - assert.deepEqual(p1, p2); - assertPlaylist(assert, p1); -}); - -q.test('get playlist items', async assert => -{ - const columns = ['%track%']; - - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); - await client.addPlaylistItems(0, [tracks.t3]); - - const expected = [ - { columns: ['01'] }, - { columns: ['02'] }, - { columns: ['03'] }, - ]; - - const result1 = await client.getPlaylistItems(0, columns, '0:3'); - assert.equal(result1.offset, 0); - assert.equal(result1.totalCount, 3); - assert.deepEqual(result1.items, expected); - - const result2 = await client.getPlaylistItems(0, columns, '0:2'); - assert.equal(result2.offset, 0); - assert.equal(result2.totalCount, 3); - assert.deepEqual(result2.items, expected.slice(0, 2)); - - const result3 = await client.getPlaylistItems(0, columns, '2:2'); - assert.equal(result3.offset, 2); - assert.equal(result3.totalCount, 3); - assert.deepEqual(result3.items, expected.slice(2, 3)); - - const result4 = await client.getPlaylistItems(0, columns, '4:4'); - assert.equal(result4.offset, 3); - assert.equal(result4.totalCount, 3); - assert.deepEqual(result4.items, []); -}); - -q.test('add playlist simple', async assert => -{ - await client.addPlaylist(); - - const playlists = await client.getPlaylists(); - assert.equal(playlists.length, 2); - - const playlist = playlists[1]; - assert.equal(typeof playlist.id, 'string'); - delete playlist.id; - - assert.deepEqual(playlist, { - index: 1, - title: 'New playlist', - isCurrent: false, - itemCount: 0, - totalTime: 0, + + test('get playlist items', async () => { + const columns = ['%track%']; + + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); + await client.addPlaylistItems(0, [tracks.t3]); + + const expected = [ + { columns: ['01'] }, + { columns: ['02'] }, + { columns: ['03'] }, + ]; + + const result1 = await client.getPlaylistItems(0, columns, '0:3'); + assert.equal(result1.offset, 0); + assert.equal(result1.totalCount, 3); + assert.deepEqual(result1.items, expected); + + const result2 = await client.getPlaylistItems(0, columns, '0:2'); + assert.equal(result2.offset, 0); + assert.equal(result2.totalCount, 3); + assert.deepEqual(result2.items, expected.slice(0, 2)); + + const result3 = await client.getPlaylistItems(0, columns, '2:2'); + assert.equal(result3.offset, 2); + assert.equal(result3.totalCount, 3); + assert.deepEqual(result3.items, expected.slice(2, 3)); + + const result4 = await client.getPlaylistItems(0, columns, '4:4'); + assert.equal(result4.offset, 3); + assert.equal(result4.totalCount, 3); + assert.deepEqual(result4.items, []); }); -}); -q.test('add playlist full', async assert => -{ - await client.addPlaylist({ title: 'My playlist', index: 0, setCurrent: true }); + test('add playlist simple', async () => { + await client.addPlaylist(); - const playlists = await client.getPlaylists(); - assert.equal(playlists.length, 2); + const playlists = await client.getPlaylists(); + assert.equal(playlists.length, 2); - const playlist = playlists[0]; - assert.equal(typeof playlist.id, 'string'); - delete playlist.id; + const playlist = playlists[1]; + assert.equal(typeof playlist.id, 'string'); + delete playlist.id; - assert.deepEqual(playlist, { - index: 0, - title: 'My playlist', - isCurrent: true, - itemCount: 0, - totalTime: 0, + assert.deepEqual(playlist, { + index: 1, + title: 'New playlist', + isCurrent: false, + itemCount: 0, + totalTime: 0, + }); }); -}); - -q.test('set current playlist', async assert => -{ - await client.addPlaylist(); - await client.setCurrentPlaylist(1); - - const playlists = await client.getPlaylists(); - assert.equal(playlists[0].isCurrent, false); - assert.equal(playlists[1].isCurrent, true); -}); - -q.test('remove playlist', async assert => -{ - await client.addPlaylist(); - let playlists = await client.getPlaylists(); - - const id = playlists[1].id; - await client.removePlaylist(id); - - playlists = await client.getPlaylists(); - assert.equal(playlists.findIndex(i => i.id === id), -1); -}); - -q.test('move playlist', async assert => -{ - await client.addPlaylist(); - await client.addPlaylist(); - let playlists = await client.getPlaylists(); - - const id1 = playlists[1].id; - const id2 = playlists[2].id; - - await client.movePlaylist(id1, 2); - - playlists = await client.getPlaylists(); - assert.equal(playlists[1].id, id2); - assert.equal(playlists[2].id, id1); -}); - -q.test('clear playlist', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.clearPlaylist(0); - - const files = await client.getPlaylistFiles(0); - assert.deepEqual(files, []); -}); - -q.test('rename playlist', async assert => -{ - await client.renamePlaylist(0, 'My cool list'); - const playlists = await client.getPlaylists(); - assert.equal(playlists[0].title, 'My cool list'); -}); - -q.test('add playlist items single', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t1])); -}); - -q.test('add playlist items url', async assert => -{ - const streamUrl = 'https://upload.wikimedia.org/wikipedia/en/d/d0/Rick_Astley_-_Never_Gonna_Give_You_Up.ogg'; - - await client.addPlaylistItems(0, [streamUrl]); - - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [streamUrl])); -}); - -q.test('add playlist items multiple', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); - - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t2, tracks.t3], true)); -}); - -q.test('add playlist items to position', async assert => -{ - await client.addPlaylistItems(0, [tracks.t2]); - await client.addPlaylistItems(0, [tracks.t1], { index: 0 }); - await client.addPlaylistItems(0, [tracks.t3], { index: 1 }); - - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t3, tracks.t2])); -}); - -q.test('add playlist items async', async assert => -{ - await client.addPlaylistItems( - 0, [tracks.t1, tracks.t2, tracks.t3], { async: true }); - - assert.equal(client.handler.lastStatus, 202); - - const files = await waitUntil(async () => - { - const result = await client.getPlaylistFiles(0); - return result.length === 3 ? result : null; + + test('add playlist full', async () => { + await client.addPlaylist({ title: 'My playlist', index: 0, setCurrent: true }); + + const playlists = await client.getPlaylists(); + assert.equal(playlists.length, 2); + + const playlist = playlists[0]; + assert.equal(typeof playlist.id, 'string'); + delete playlist.id; + + assert.deepEqual(playlist, { + index: 0, + title: 'My playlist', + isCurrent: true, + itemCount: 0, + totalTime: 0, + }); + }); + + test('set current playlist', async () => { + await client.addPlaylist(); + await client.setCurrentPlaylist(1); + + const playlists = await client.getPlaylists(); + assert.equal(playlists[0].isCurrent, false); + assert.equal(playlists[1].isCurrent, true); }); - assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t2, tracks.t3], true)); -}); + test('remove playlist', async () => { + await client.addPlaylist(); + let playlists = await client.getPlaylists(); -q.test('sort playlist items asc', async assert => -{ - await client.addPlaylistItems(0, [tracks.t2, tracks.t1, tracks.t3]); - await client.sortPlaylistItems(0, { by: '%tracknumber%' }); + const id = playlists[1].id; + await client.removePlaylist(id); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t2, tracks.t3])); -}); + playlists = await client.getPlaylists(); + assert.equal(playlists.findIndex(i => i.id === id), -1); + }); -q.test('sort playlist items desc', async assert => -{ - await client.addPlaylistItems(0, [tracks.t2, tracks.t1, tracks.t3]); - await client.sortPlaylistItems(0, { by: '%tracknumber%', desc: true }); + test('move playlist', async () => { + await client.addPlaylist(); + await client.addPlaylist(); + let playlists = await client.getPlaylists(); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t3, tracks.t2, tracks.t1])); -}); + const id1 = playlists[1].id; + const id2 = playlists[2].id; -q.test('sort playlist items random', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); - const initialFiles = await client.getPlaylistFiles(0); + await client.movePlaylist(id1, 2); + + playlists = await client.getPlaylists(); + assert.equal(playlists[1].id, id2); + assert.equal(playlists[2].id, id1); + }); + + test('clear playlist', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.clearPlaylist(0); - for (let i = 0; i < 10; i++) - { - await client.sortPlaylistItems(0, { random: true }); const files = await client.getPlaylistFiles(0); + assert.deepEqual(files, []); + }); - if (!pathCollectionsEqual(initialFiles, files)) - { - assert.ok(true); - return; - } - } + test('rename playlist', async () => { + await client.renamePlaylist(0, 'My cool list'); + const playlists = await client.getPlaylists(); + assert.equal(playlists[0].title, 'My cool list'); + }); + + test('add playlist items single', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t1])); + }); + + test('add playlist items url', async () => { + const streamUrl = 'https://upload.wikimedia.org/wikipedia/en/d/d0/Rick_Astley_-_Never_Gonna_Give_You_Up.ogg'; + + await client.addPlaylistItems(0, [streamUrl]); + + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [streamUrl])); + }); + + test('add playlist items multiple', async () => { + await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); + + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t2, tracks.t3], true)); + }); - assert.ok(false, 'expected to sort playlist randomly'); -}); + test('add playlist items to position', async () => { + await client.addPlaylistItems(0, [tracks.t2]); + await client.addPlaylistItems(0, [tracks.t1], { index: 0 }); + await client.addPlaylistItems(0, [tracks.t3], { index: 1 }); -q.test('remove playlist items', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); - await client.addPlaylistItems(0, [tracks.t3]); + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t3, tracks.t2])); + }); - await client.removePlaylistItems(0, [0, 2]); + test('add playlist items async', async () => { + await client.addPlaylistItems( + 0, [tracks.t1, tracks.t2, tracks.t3], { async: true }); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t2])); -}); + assert.equal(client.handler.lastStatus, 202); -q.test('move playlist items', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); - await client.addPlaylistItems(0, [tracks.t3]); + const files = await waitUntil(async () => { + const result = await client.getPlaylistFiles(0); + return result.length === 3 ? result : null; + }); - await client.movePlaylistItems({ - playlist: 0, - items: [1, 2], - targetIndex: 0 + assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t2, tracks.t3], true)); }); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t2, tracks.t3, tracks.t1])); -}); - -q.test('move playlist items between playlists', async assert => -{ - await client.addPlaylist(); - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); - await client.addPlaylistItems(0, [tracks.t3]); - await client.addPlaylistItems(1, [tracks.t3]); - await client.movePlaylistItems({ - from: 0, - to: 1, - items: [1, 2] + test('sort playlist items asc', async () => { + await client.addPlaylistItems(0, [tracks.t2, tracks.t1, tracks.t3]); + await client.sortPlaylistItems(0, { by: '%tracknumber%' }); + + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t2, tracks.t3])); }); - const files1 = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files1, [tracks.t1])); - - const files2 = await client.getPlaylistFiles(1); - assert.ok(pathCollectionsEqual(files2, [tracks.t3, tracks.t2, tracks.t3])); -}); - -q.test('copy playlist items', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); - await client.addPlaylistItems(0, [tracks.t3]); - await client.copyPlaylistItems({ - playlist: 0, - items: [0, 1], - targetIndex: 1 + test('sort playlist items desc', async () => { + await client.addPlaylistItems(0, [tracks.t2, tracks.t1, tracks.t3]); + await client.sortPlaylistItems(0, { by: '%tracknumber%', desc: true }); + + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t3, tracks.t2, tracks.t1])); }); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t1, tracks.t2, tracks.t2, tracks.t3])); -}); - -q.test('copy playlist items between playlists', async assert => -{ - await client.addPlaylist(); - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); - await client.addPlaylistItems(0, [tracks.t3]); - await client.addPlaylistItems(1, [tracks.t3]); - await client.copyPlaylistItems({ - from: 0, - to: 1, - items: [0, 1] + test('sort playlist items random', async () => { + await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); + const initialFiles = await client.getPlaylistFiles(0); + + for (let i = 0; i < 10; i++) + { + await client.sortPlaylistItems(0, { random: true }); + const files = await client.getPlaylistFiles(0); + + if (!pathCollectionsEqual(initialFiles, files)) + { + assert.ok(true); + return; + } + } + + assert.ok(false, 'expected to sort playlist randomly'); }); - const files1 = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files1, [tracks.t1, tracks.t2, tracks.t3])); + test('remove playlist items', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); + await client.addPlaylistItems(0, [tracks.t3]); - const files2 = await client.getPlaylistFiles(1); - assert.ok(pathCollectionsEqual(files2, [tracks.t3, tracks.t1, tracks.t2])); -}); + await client.removePlaylistItems(0, [0, 2]); -q.test('replace empty playlist items', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1], {replace: true}); + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t2])); + }); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t1])); -}); + test('move playlist items', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); + await client.addPlaylistItems(0, [tracks.t3]); -q.test('replace non-empty playlist items', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2], {replace: true}); + await client.movePlaylistItems({ + playlist: 0, + items: [1, 2], + targetIndex: 0 + }); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t2])); -}); + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t2, tracks.t3, tracks.t1])); + }); -q.test('add items to empty playlist and play', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1], {play: true}); + test('move playlist items between playlists', async () => { + await client.addPlaylist(); + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); + await client.addPlaylistItems(0, [tracks.t3]); + await client.addPlaylistItems(1, [tracks.t3]); + await client.movePlaylistItems({ + from: 0, + to: 1, + items: [1, 2] + }); + + const files1 = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files1, [tracks.t1])); + + const files2 = await client.getPlaylistFiles(1); + assert.ok(pathCollectionsEqual(files2, [tracks.t3, tracks.t2, tracks.t3])); + }); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t1])); + test('copy playlist items', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); + await client.addPlaylistItems(0, [tracks.t3]); + await client.copyPlaylistItems({ + playlist: 0, + items: [0, 1], + targetIndex: 1 + }); - await client.waitForState(s => s.playbackState === 'playing' && s.activeItem.index === 0); -}); + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t1, tracks.t2, tracks.t2, tracks.t3])); + }); -q.test('add items to non-empty playlist and play', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2], {play: true}); + test('copy playlist items between playlists', async () => { + await client.addPlaylist(); + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); + await client.addPlaylistItems(0, [tracks.t3]); + await client.addPlaylistItems(1, [tracks.t3]); + await client.copyPlaylistItems({ + from: 0, + to: 1, + items: [0, 1] + }); + + const files1 = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files1, [tracks.t1, tracks.t2, tracks.t3])); + + const files2 = await client.getPlaylistFiles(1); + assert.ok(pathCollectionsEqual(files2, [tracks.t3, tracks.t1, tracks.t2])); + }); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t2])); + test('replace empty playlist items', async () => { + await client.addPlaylistItems(0, [tracks.t1], { replace: true }); - await client.waitForState(s => s.playbackState === 'playing' && s.activeItem.index === 1); -}); + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t1])); + }); -q.test('replace items in empty playlist and play', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1], {play: true, replace: true}); + test('replace non-empty playlist items', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2], { replace: true }); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t1])); + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t2])); + }); + + test('add items to empty playlist and play', async () => { + await client.addPlaylistItems(0, [tracks.t1], { play: true }); + + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t1])); - await client.waitForState(s => s.playbackState === 'playing' && s.activeItem.index === 0); -}); + await client.waitForState(s => s.playbackState === 'playing' && s.activeItem.index === 0); + }); -q.test('replace items in non-empty playlist and play', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2], {play: true, replace: true}); + test('add items to non-empty playlist and play', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2], { play: true }); - const files = await client.getPlaylistFiles(0); - assert.ok(pathCollectionsEqual(files, [tracks.t2])); + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t1, tracks.t2])); - await client.waitForState(s => s.playbackState === 'playing' && s.activeItem.index === 0); -}); + await client.waitForState(s => s.playbackState === 'playing' && s.activeItem.index === 1); + }); -q.test('stop playback when adding empty dir', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.play(0, 0); - await client.waitForState('playing'); - await client.addPlaylistItems(0, [tracks.emptyDir], {play: true}); - await client.waitForState('stopped'); - assert.ok(true); -}); + test('replace items in empty playlist and play', async () => { + await client.addPlaylistItems(0, [tracks.t1], { play: true, replace: true }); + + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t1])); + + await client.waitForState(s => s.playbackState === 'playing' && s.activeItem.index === 0); + }); + + test('replace items in non-empty playlist and play', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2], { play: true, replace: true }); + + const files = await client.getPlaylistFiles(0); + assert.ok(pathCollectionsEqual(files, [tracks.t2])); + + await client.waitForState(s => s.playbackState === 'playing' && s.activeItem.index === 0); + }); + + test('stop playback when adding empty dir', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.play(0, 0); + await client.waitForState('playing'); + await client.addPlaylistItems(0, [tracks.emptyDir], { play: true }); + await client.waitForState('stopped'); + assert.ok(true); + }); +}); \ No newline at end of file diff --git a/js/api_tests/src/query_api_tests.js b/js/api_tests/src/query_api_tests.js index 516fb89b..cb5bc279 100644 --- a/js/api_tests/src/query_api_tests.js +++ b/js/api_tests/src/query_api_tests.js @@ -1,341 +1,322 @@ -import q from 'qunit'; -import { client, tracks, outputConfigs, usePlayer } from './test_env.js'; +import { describe, test, assert } from 'vitest'; +import { client, tracks, outputConfigs, setupPlayer } from './test_env.js'; -q.module('query api', usePlayer()); +describe('query api', () => { + setupPlayer(); -q.test('query player', async assert => -{ - await client.addPlaylistItems(0, [tracks.t3]); + test('query player', async () => { + await client.addPlaylistItems(0, [tracks.t3]); - await client.play(0, 0); - await client.waitForState('playing'); + await client.play(0, 0); + await client.waitForState('playing'); - await client.pause(); - await client.waitForState('paused'); + await client.pause(); + await client.waitForState('paused'); - const columns = ['%title%']; - const player = await client.getPlayerState(columns); - const result = await client.query({ player: true, trcolumns: columns }); + const columns = ['%title%']; + const player = await client.getPlayerState(columns); + const result = await client.query({ player: true, trcolumns: columns }); - assert.deepEqual(result.player, player); -}); + assert.deepEqual(result.player, player); + }); + + test('query playlists', async () => { + await client.addPlaylist({ title: 'My playlist' }); + + const playlists = await client.getPlaylists(); + const result = await client.query({ playlists: true }); + + assert.deepEqual(result.playlists, playlists); + }); + + test('query playlist items', async () => { + await client.addPlaylistItems(0, [tracks.t2, tracks.t3]); + + const columns = ['%title%']; + const playlistItems = await client.getPlaylistItems(0, columns); + + const result = await client.query({ + playlistItems: true, + plref: 0, + plcolumns: columns, + }); + + assert.deepEqual(result.playlistItems, playlistItems); + }); + + test('query outputs', async () => { + const queue = await client.getOutputs(); + const result = await client.query({ outputs: true }); + assert.deepEqual(result.outputs, queue); + }); + + test('query all', async () => { + await client.addPlaylistItems(0, [tracks.t2, tracks.t3]); + await client.addToPlayQueue(0, 1); + + await client.play(0, 0); + await client.waitForState('playing'); + + await client.pause(); + await client.waitForState('paused'); + + await client.addPlaylist({ title: 'My playlist' }); + + const columns = ['%title%']; + + const expected = { + player: await client.getPlayerState(columns), + playlists: await client.getPlaylists(), + playlistItems: await client.getPlaylistItems(0, columns), + playQueue: await client.getPlayQueue(), + outputs: await client.getOutputs(), + }; + + const result = await client.query({ + player: true, + trcolumns: columns, + playlists: true, + playlistItems: true, + plref: 0, + plcolumns: columns, + playQueue: true, + outputs: true, + }); -q.test('query playlists', async assert => -{ - await client.addPlaylist({ title: 'My playlist' }); + assert.deepEqual(result, expected); + }); + + test('expect player events', async () => { + await client.addPlaylistItems(0, [tracks.t1]); - const playlists = await client.getPlaylists(); - const result = await client.query({ playlists: true }); + const expectation = client.expectEvent({ player: true }, e => e.player === true); - assert.deepEqual(result.playlists, playlists); -}); + await expectation.ready; + await client.play(0, 0); + await expectation.done; -q.test('query playlist items', async assert => -{ - await client.addPlaylistItems(0, [tracks.t2, tracks.t3]); + assert.ok(true); + }); - const columns = ['%title%']; - const playlistItems = await client.getPlaylistItems(0, columns); + test('expect playlist events', async () => { + const expectation = client.expectEvent({ playlists: true }, e => e.playlists === true); - const result = await client.query({ - playlistItems: true, - plref: 0, - plcolumns: columns, + await expectation.ready; + await client.addPlaylist(); + await expectation.done; + + assert.ok(true); }); - assert.deepEqual(result.playlistItems, playlistItems); -}); - -q.test('query outputs', async assert => -{ - const queue = await client.getOutputs(); - const result = await client.query({ outputs: true }); - assert.deepEqual(result.outputs, queue); -}); - -q.test('query all', async assert => -{ - await client.addPlaylistItems(0, [tracks.t2, tracks.t3]); - await client.addToPlayQueue(0, 1); - - await client.play(0, 0); - await client.waitForState('playing'); - - await client.pause(); - await client.waitForState('paused'); - - await client.addPlaylist({ title: 'My playlist' }); - - const columns = ['%title%']; - - const expected = { - player: await client.getPlayerState(columns), - playlists: await client.getPlaylists(), - playlistItems: await client.getPlaylistItems(0, columns), - playQueue: await client.getPlayQueue(), - outputs: await client.getOutputs(), - }; - - const result = await client.query({ - player: true, - trcolumns: columns, - playlists: true, - playlistItems: true, - plref: 0, - plcolumns: columns, - playQueue: true, - outputs: true, + test('expect playlist items events', async () => { + const expectation = client.expectEvent({ playlistItems: true }, e => e.playlistItems === true); + + await expectation.ready; + await client.addPlaylistItems(0, [tracks.t1]); + await expectation.done; + + assert.ok(true); }); - assert.deepEqual(result, expected); -}); + test('expect play queue events', async () => { + await client.addPlaylistItems(0, [tracks.t1]); -q.test('expect player events', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); + const expectation = client.expectEvent({ playQueue: true }, e => e.playQueue === true); - const expectation = client.expectEvent({ player: true }, e => e.player === true); + await expectation.ready; + await client.addToPlayQueue(0, 0); + await expectation.done; - await expectation.ready; - await client.play(0, 0); - await expectation.done; + assert.ok(true); + }); - assert.ok(true); -}); + test('expect output config events', async () => { + const expectation = client.expectEvent({ outputs: true }, e => e.outputs === true); + await expectation.ready; + await client.setOutputDevice(outputConfigs.alternate[0].typeId, outputConfigs.alternate[0].deviceId); + await expectation.done; + assert.ok(true); + }); -q.test('expect playlist events', async assert => -{ - const expectation = client.expectEvent({ playlists: true }, e => e.playlists === true); + test('expect player updates', async () => { + await client.addPlaylistItems(0, [tracks.t1]); - await expectation.ready; - await client.addPlaylist(); - await expectation.done; + const expectation = client.expectUpdate({ player: true }, e => typeof e.player === 'object'); - assert.ok(true); -}); + await expectation.ready; + await client.play(0, 0); + await expectation.done; -q.test('expect playlist items events', async assert => -{ - const expectation = client.expectEvent({ playlistItems: true }, e => e.playlistItems === true); + const expected = await client.getPlayerState(); + delete expected.activeItem.position; - await expectation.ready; - await client.addPlaylistItems(0, [tracks.t1]); - await expectation.done; + const actual = expectation.lastEvent.player; + delete actual.activeItem.position; - assert.ok(true); -}); + assert.deepEqual(actual, expected); + }); -q.test('expect play queue events', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); + test('expect playlist updates', async () => { + const expectation = client.expectUpdate({ playlists: true }, e => typeof e.playlists === 'object'); - const expectation = client.expectEvent({ playQueue: true }, e => e.playQueue === true); + await expectation.ready; + await client.addPlaylist({ title: 'My list' }); + await expectation.done; - await expectation.ready; - await client.addToPlayQueue(0, 0); - await expectation.done; + const expected = await client.getPlaylists(); + const actual = expectation.lastEvent.playlists; - assert.ok(true); -}); + assert.deepEqual(actual, expected); + }); -q.test('expect output config events', async assert => -{ - const expectation = client.expectEvent({ outputs: true }, e => e.outputs === true); - await expectation.ready; - await client.setOutputDevice(outputConfigs.alternate[0].typeId, outputConfigs.alternate[0].deviceId); - await expectation.done; - assert.ok(true); -}); + test('expect playlist items updates when adding items', async () => { + const columns = ['%title%']; + const options = { + playlistItems: true, + plref: 0, + plcolumns: columns, + }; -q.test('expect player updates', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); + const expectation = client.expectUpdate( + options, e => typeof e.playlistItems === 'object'); - const expectation = client.expectUpdate({ player: true }, e => typeof e.player === 'object'); + await expectation.ready; + await client.addPlaylistItems(0, [tracks.t1]); + await expectation.done; - await expectation.ready; - await client.play(0, 0); - await expectation.done; + const expected = await client.getPlaylistItems(0, columns); + const actual = expectation.lastEvent.playlistItems; - const expected = await client.getPlayerState(); - delete expected.activeItem.position; + assert.deepEqual(actual, expected); + }); - const actual = expectation.lastEvent.player; - delete actual.activeItem.position; + test('expect playlist items updates when removing items', async () => { + const columns = ['%title%']; + const options = { + playlistItems: true, + plref: 0, + plcolumns: columns, + }; - assert.deepEqual(actual, expected); -}); + await client.addPlaylistItems(0, [tracks.t1, tracks.t2]); -q.test('expect playlist updates', async assert => -{ - const expectation = client.expectUpdate({ playlists: true }, e => typeof e.playlists === 'object'); + const expectation = client.expectUpdate( + options, e => typeof e.playlistItems === 'object'); - await expectation.ready; - await client.addPlaylist({ title: 'My list' }); - await expectation.done; + await expectation.ready; + await client.removePlaylistItems(0, [0]); + await expectation.done; - const expected = await client.getPlaylists(); - const actual = expectation.lastEvent.playlists; + const expected = await client.getPlaylistItems(0, columns); + const actual = expectation.lastEvent.playlistItems; - assert.deepEqual(actual, expected); -}); + assert.deepEqual(actual, expected); + }); -q.test('expect playlist items updates when adding items', async assert => -{ - const columns = ['%title%']; - const options = { - playlistItems: true, - plref: 0, - plcolumns: columns, - }; + test('expect volume updates', async () => { + const { volume } = await client.getPlayerState(); - const expectation = client.expectUpdate( - options, e => typeof e.playlistItems === 'object'); + const targetVolume = (volume.min + volume.max) / 2; - await expectation.ready; - await client.addPlaylistItems(0, [tracks.t1]); - await expectation.done; + const expectation = client.expectUpdate( + { player: true }, + e => e.player && e.player.volume.value === targetVolume); - const expected = await client.getPlaylistItems(0, columns); - const actual = expectation.lastEvent.playlistItems; + await expectation.ready; + await client.setVolume(targetVolume); + await expectation.done; - assert.deepEqual(actual, expected); -}); + assert.ok(true); + }); -q.test('expect playlist items updates when removing items', async assert => -{ - const columns = ['%title%']; - const options = { - playlistItems: true, - plref: 0, - plcolumns: columns, - }; + test('expect mute state updates', async () => { + const expectation = client.expectUpdate( + { player: true }, + e => e.player && e.player.volume.isMuted); - await client.addPlaylistItems(0, [tracks.t1, tracks.t2]); + await expectation.ready; + await client.setMuted(true); + await expectation.done; - const expectation = client.expectUpdate( - options, e => typeof e.playlistItems === 'object'); + assert.ok(true); + }); - await expectation.ready; - await client.removePlaylistItems(0, [0]); - await expectation.done; + test('expect active item updates when sorting playlist items', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.addPlaylistItems(0, [tracks.t2]); + await client.play(0, 0); + await client.waitForState('playing'); - const expected = await client.getPlaylistItems(0, columns); - const actual = expectation.lastEvent.playlistItems; + const expectation = client.expectUpdate( + { player: true }, + e => e.player && e.player.activeItem.index === 1); - assert.deepEqual(actual, expected); -}); + await expectation.ready; + await client.sortPlaylistItems(0, { by: '%tracknumber%', desc: true }); + await expectation.done; -q.test('expect volume updates', async assert => -{ - const { volume } = await client.getPlayerState(); + assert.ok(true); + }); - const targetVolume = (volume.min + volume.max) / 2; - - const expectation = client.expectUpdate( - { player: true }, - e => e.player && e.player.volume.value === targetVolume); - - await expectation.ready; - await client.setVolume(targetVolume); - await expectation.done; - - assert.ok(true); -}); + test('expect active item updates when adding playlist items', async () => { + await client.addPlaylistItems(0, [tracks.t1]); + await client.play(0, 0); + await client.waitForState('playing'); -q.test('expect mute state updates', async assert => -{ - const expectation = client.expectUpdate( - { player: true }, - e => e.player && e.player.volume.isMuted); + const expectation = client.expectUpdate( + { player: true }, + e => e.player && e.player.activeItem.index === 1); - await expectation.ready; - await client.setMuted(true); - await expectation.done; + await expectation.ready; + await client.addPlaylistItems(0, [tracks.t2], { index: 0 }); + await expectation.done; - assert.ok(true); -}); + assert.ok(true); + }); -q.test('expect active item updates when sorting playlist items', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.addPlaylistItems(0, [tracks.t2]); - await client.play(0, 0); - await client.waitForState('playing'); + test('expect active item updates when removing playlist items', async () => { + await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); + await client.play(0, 2); + await client.waitForState('playing'); - const expectation = client.expectUpdate( - { player: true }, - e => e.player && e.player.activeItem.index === 1); - - await expectation.ready; - await client.sortPlaylistItems(0, { by: '%tracknumber%', desc: true }); - await expectation.done; - - assert.ok(true); -}); + const expectation = client.expectUpdate( + { player: true }, + e => e.player && e.player.activeItem.index === 1); -q.test('expect active item updates when adding playlist items', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); - await client.play(0, 0); - await client.waitForState('playing'); - - const expectation = client.expectUpdate( - { player: true }, - e => e.player && e.player.activeItem.index === 1); - - await expectation.ready; - await client.addPlaylistItems(0, [tracks.t2], { index: 0 }); - await expectation.done; + await expectation.ready; + await client.removePlaylistItems(0, [0]); + await expectation.done; - assert.ok(true); -}); + assert.ok(true); + }); -q.test('expect active item updates when removing playlist items', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1, tracks.t2, tracks.t3]); - await client.play(0, 2); - await client.waitForState('playing'); + test('expect play queue updates', async () => { + await client.addPlaylistItems(0, [tracks.t1]); - const expectation = client.expectUpdate( - { player: true }, - e => e.player && e.player.activeItem.index === 1); + const columns = ['%artist%', '%title%']; + const expectation = client.expectUpdate( + { playQueue: true, qcolumns: columns }, + e => typeof e.playQueue === 'object' && e.playQueue.length > 0); - await expectation.ready; - await client.removePlaylistItems(0, [0]); - await expectation.done; + await expectation.ready; + await client.addToPlayQueue(0, 0); + await expectation.done; - assert.ok(true); -}); + const expected = await client.getPlayQueue(columns); + const actual = expectation.lastEvent.playQueue; -q.test('expect play queue updates', async assert => -{ - await client.addPlaylistItems(0, [tracks.t1]); + assert.deepEqual(actual, expected); + }); - const columns = ['%artist%', '%title%']; - const expectation = client.expectUpdate( - { playQueue: true, qcolumns: columns }, - e => typeof e.playQueue === 'object' && e.playQueue.length > 0); + test('expect output config updates', async () => { + const expectation = client.expectUpdate({ outputs: true }, e => typeof e.outputs === 'object'); + await expectation.ready; + await client.setOutputDevice(outputConfigs.alternate[0].typeId, outputConfigs.alternate[0].deviceId); + await expectation.done; - await expectation.ready; - await client.addToPlayQueue(0, 0); - await expectation.done; + const expected = await client.getOutputs(); + const actual = expectation.lastEvent.outputs; - const expected = await client.getPlayQueue(columns); - const actual = expectation.lastEvent.playQueue; - - assert.deepEqual(actual, expected); -}); - -q.test('expect output config updates', async assert => -{ - const expectation = client.expectUpdate({ outputs: true }, e => typeof e.outputs === 'object'); - await expectation.ready; - await client.setOutputDevice(outputConfigs.alternate[0].typeId, outputConfigs.alternate[0].deviceId); - await expectation.done; - - const expected = await client.getOutputs(); - const actual = expectation.lastEvent.outputs; - - assert.deepEqual(actual, expected); -}); + assert.deepEqual(actual, expected); + }); +}); \ No newline at end of file diff --git a/js/api_tests/src/static_files_tests.js b/js/api_tests/src/static_files_tests.js index 7447ea8b..38b5248c 100644 --- a/js/api_tests/src/static_files_tests.js +++ b/js/api_tests/src/static_files_tests.js @@ -1,10 +1,9 @@ import path from 'path'; -import { promisify } from 'util'; import fs from 'fs'; -import q from 'qunit'; -import { client, config, usePlayer } from './test_env.js'; +import { describe, test, assert } from 'vitest'; +import { client, config, setupPlayer } from './test_env.js'; -const readFile = promisify(fs.readFile); +const readFile = fs.promises.readFile; const pluginSettings = { urlMappings: { @@ -28,221 +27,199 @@ function assertRedirect(assert, result, location) assert.equal(result.headers["location"], location); } -q.module('static files', usePlayer({ pluginSettings, axiosConfig })); +describe('static files', () => { + setupPlayer({ pluginSettings, axiosConfig }); -function getFile(url, config) -{ - return client.handler.axios.get(url, config); -} - -function getFileData(url) -{ - return readFile(path.join(config.webRootDir, url), 'utf8'); -} + function getFile(url, config) + { + return client.handler.axios.get(url, config); + } -q.test('get index of root', async assert => -{ - const result = await getFile('/'); - assert.equal(result.data, 'index.html\n'); -}); + function getFileData(url) + { + return readFile(path.join(config.webRootDir, url), 'utf8'); + } -q.test('get index of prefix', async assert => -{ - const result = await getFile('/prefix/'); - assert.equal(result.data, 'index.html\n'); -}); + test('get index of root', async () => { + const result = await getFile('/'); + assert.equal(result.data, 'index.html\n'); + }); -q.test('get index of nested prefix', async assert => -{ - const result = await getFile('/prefix/nested/'); - assert.equal(result.data, 'index.html\n'); -}); + test('get index of prefix', async () => { + const result = await getFile('/prefix/'); + assert.equal(result.data, 'index.html\n'); + }); -q.test('redirect index of prefix', async assert => -{ - const result = await getFile('/prefix'); - assert.equal(result.headers["location"], '/prefix/'); -}); + test('get index of nested prefix', async () => { + const result = await getFile('/prefix/nested/'); + assert.equal(result.data, 'index.html\n'); + }); -q.test('redirect index of nested prefix', async assert => -{ - const result = await getFile('/prefix/nested'); - assertRedirect(assert, result, '/prefix/nested/'); -}); + test('redirect index of prefix', async () => { + const result = await getFile('/prefix'); + assert.equal(result.headers["location"], '/prefix/'); + }); -q.test('get file of root', async assert => -{ - const result = await getFile('/file.html'); - assert.equal(result.data, 'file.html\n'); -}); + test('redirect index of nested prefix', async () => { + const result = await getFile('/prefix/nested'); + assertRedirect(assert, result, '/prefix/nested/'); + }); -q.test('get file of prefix', async assert => -{ - const result = await getFile('/prefix/file.html'); - assert.equal(result.data, 'file.html\n'); -}); + test('get file of root', async () => { + const result = await getFile('/file.html'); + assert.equal(result.data, 'file.html\n'); + }); -q.test('get file of nested prefix', async assert => -{ - const result = await getFile('/prefix/nested/file.html'); - assert.equal(result.data, 'file.html\n'); -}); + test('get file of prefix', async () => { + const result = await getFile('/prefix/file.html'); + assert.equal(result.data, 'file.html\n'); + }); -q.test('get subdir index of root', async assert => -{ - const result = await getFile('/subdir/'); - assert.equal(result.data, 'subdir/index.html\n'); -}); + test('get file of nested prefix', async () => { + const result = await getFile('/prefix/nested/file.html'); + assert.equal(result.data, 'file.html\n'); + }); -q.test('get subdir index of prefix', async assert => -{ - const result = await getFile('/prefix/subdir/'); - assert.equal(result.data, 'subdir/index.html\n'); -}); + test('get subdir index of root', async () => { + const result = await getFile('/subdir/'); + assert.equal(result.data, 'subdir/index.html\n'); + }); -q.test('get subdir index of nested prefix', async assert => -{ - const result = await getFile('/prefix/nested/subdir/'); - assert.equal(result.data, 'subdir/index.html\n'); -}); + test('get subdir index of prefix', async () => { + const result = await getFile('/prefix/subdir/'); + assert.equal(result.data, 'subdir/index.html\n'); + }); -q.test('redirect subdir index of root', async assert => -{ - const result = await getFile('/subdir'); - assertRedirect(assert, result, '/subdir/'); -}); + test('get subdir index of nested prefix', async () => { + const result = await getFile('/prefix/nested/subdir/'); + assert.equal(result.data, 'subdir/index.html\n'); + }); -q.test('redirect subdir index of prefix', async assert => -{ - const result = await getFile('/prefix/subdir'); - assertRedirect(assert, result, '/prefix/subdir/'); -}); + test('redirect subdir index of root', async () => { + const result = await getFile('/subdir'); + assertRedirect(assert, result, '/subdir/'); + }); -q.test('redirect subdir index of nested prefix', async assert => -{ - const result = await getFile('/prefix/nested/subdir'); - assertRedirect(assert, result, '/prefix/nested/subdir/'); -}); + test('redirect subdir index of prefix', async () => { + const result = await getFile('/prefix/subdir'); + assertRedirect(assert, result, '/prefix/subdir/'); + }); -q.test('get subdir file of root', async assert => -{ - const result = await getFile('/subdir/file.html'); - assert.equal(result.data, 'subdir/file.html\n'); -}); + test('redirect subdir index of nested prefix', async () => { + const result = await getFile('/prefix/nested/subdir'); + assertRedirect(assert, result, '/prefix/nested/subdir/'); + }); -q.test('get subdir file of prefix', async assert => -{ - const result = await getFile('/prefix/subdir/file.html'); - assert.equal(result.data, 'subdir/file.html\n'); -}); + test('get subdir file of root', async () => { + const result = await getFile('/subdir/file.html'); + assert.equal(result.data, 'subdir/file.html\n'); + }); -q.test('get subdir file of nested prefix', async assert => -{ - const result = await getFile('/prefix/nested/subdir/file.html'); - assert.equal(result.data, 'subdir/file.html\n'); -}); + test('get subdir file of prefix', async () => { + const result = await getFile('/prefix/subdir/file.html'); + assert.equal(result.data, 'subdir/file.html\n'); + }); -q.test('provide content type', async assert => -{ - const contentTypes = { - 'file.html': 'text/html; charset=utf-8', - 'file.htm': 'text/html; charset=utf-8', - 'file.css': 'text/css', - 'file.svg': 'image/svg+xml', - 'file.js': 'application/javascript', - 'file.png': 'image/png', - 'file.jpeg': 'image/jpeg', - 'file.jpg': 'image/jpeg', - 'file.txt': 'text/plain; charset=utf-8', - }; - - for (let file of Object.keys(contentTypes)) - { - const result = await getFile(file); - assert.equal(result.headers['content-type'], contentTypes[file]); - } -}); + test('get subdir file of nested prefix', async () => { + const result = await getFile('/prefix/nested/subdir/file.html'); + assert.equal(result.data, 'subdir/file.html\n'); + }); -q.test('etag support', async assert => -{ - const initialResult = await getFile('file.html'); + test('provide content type', async () => { + const contentTypes = { + 'file.html': 'text/html; charset=utf-8', + 'file.htm': 'text/html; charset=utf-8', + 'file.css': 'text/css', + 'file.svg': 'image/svg+xml', + 'file.js': 'application/javascript', + 'file.png': 'image/png', + 'file.jpeg': 'image/jpeg', + 'file.jpg': 'image/jpeg', + 'file.txt': 'text/plain; charset=utf-8', + }; + + for (let file of Object.keys(contentTypes)) + { + const result = await getFile(file); + assert.equal(result.headers['content-type'], contentTypes[file]); + } + }); - const etag = initialResult.headers['etag']; - assert.ok(etag); + test('etag support', async () => { + const initialResult = await getFile('file.html'); - const cacheControl = initialResult.headers['cache-control']; - assert.equal(cacheControl, 'max-age=3, must-revalidate'); + const etag = initialResult.headers['etag']; + assert.ok(etag); - const cachedResult = await getFile('file.html', { - headers: { 'If-None-Match': etag }, - validateStatus: () => true, - }); + const cacheControl = initialResult.headers['cache-control']; + assert.equal(cacheControl, 'max-age=3, must-revalidate'); - assert.equal(cachedResult.status, 304); - assert.equal(cachedResult.headers['etag'], etag); - assert.equal(cachedResult.headers['cache-control'], cacheControl); -}); + const cachedResult = await getFile('file.html', { + headers: { 'If-None-Match': etag }, + validateStatus: () => true, + }); -q.test('enable compression', async assert => -{ - const expectedData = await getFileData('large.txt'); - const result = await getFile('large.txt', { - headers: { 'Accept-Encoding': 'whatever, gzip' }, + assert.equal(cachedResult.status, 304); + assert.equal(cachedResult.headers['etag'], etag); + assert.equal(cachedResult.headers['cache-control'], cacheControl); }); - assert.equal(result.data, expectedData); + test('enable compression', async () => { + const expectedData = await getFileData('large.txt'); + const result = await getFile('large.txt', { + headers: { 'Accept-Encoding': 'whatever, gzip' }, + }); - const contentLength = parseInt(result.headers['content-length']); - assert.ok(contentLength < expectedData.length); -}); + assert.equal(result.data, expectedData); -q.test('disable compression', async assert => -{ - const expectedData = await getFileData('large.txt'); - const result = await getFile('large.txt', { - headers: { 'Accept-Encoding': 'whatever' }, + const contentLength = parseInt(result.headers['content-length']); + assert.ok(contentLength < expectedData.length); }); - assert.equal(result.data, expectedData); + test('disable compression', async () => { + const expectedData = await getFileData('large.txt'); + const result = await getFile('large.txt', { + headers: { 'Accept-Encoding': 'whatever' }, + }); - const contentLength = parseInt(result.headers['content-length']); - assert.equal(contentLength, expectedData.length); -}); + assert.equal(result.data, expectedData); -q.test('get via parent directory', async assert => -{ - const expectedData = await getFileData('file.txt'); + const contentLength = parseInt(result.headers['content-length']); + assert.equal(contentLength, expectedData.length); + }); - const result1 = await getFile('/test/../file.txt'); - assert.equal(result1.data, expectedData); + test('get via parent directory', async () => { + const expectedData = await getFileData('file.txt'); - const result2 = await getFile('/test/%2E%2E/file.txt'); - assert.equal(result2.data, expectedData); -}); + const result1 = await getFile('/test/../file.txt'); + assert.equal(result1.data, expectedData); -q.test('get non-existing file', async assert => -{ - const result = await getFile('/non-existing.html', ignoreStatus); - assert.equal(result.status, 404); -}); + const result2 = await getFile('/test/%2E%2E/file.txt'); + assert.equal(result2.data, expectedData); + }); -q.test('escape root dir', async assert => -{ - const result1 = await getFile('/../package.json', ignoreStatus); - assert.equal(result1.status, 404); + test('get non-existing file', async () => { + const result = await getFile('/non-existing.html', ignoreStatus); + assert.equal(result.status, 404); + }); - const result2 = await getFile('/%2E%2E/package.json', ignoreStatus); - assert.equal(result2.status, 404); + test('escape root dir', async () => { + const result1 = await getFile('/../package.json', ignoreStatus); + assert.equal(result1.status, 404); - const result3 = await getFile('/prefix/../package.json', ignoreStatus); - assert.equal(result3.status, 404); + const result2 = await getFile('/%2E%2E/package.json', ignoreStatus); + assert.equal(result2.status, 404); - const result4 = await getFile('/prefix/%2E%2E/package.json', ignoreStatus); - assert.equal(result4.status, 404); + const result3 = await getFile('/prefix/../package.json', ignoreStatus); + assert.equal(result3.status, 404); - const result5 = await getFile('/prefix/nested/../package.json', ignoreStatus); - assert.equal(result3.status, 404); + const result4 = await getFile('/prefix/%2E%2E/package.json', ignoreStatus); + assert.equal(result4.status, 404); - const result6 = await getFile('/prefix/nested/%2E%2E/package.json', ignoreStatus); - assert.equal(result4.status, 404); + const result5 = await getFile('/prefix/nested/../package.json', ignoreStatus); + assert.equal(result5.status, 404); + + const result6 = await getFile('/prefix/nested/%2E%2E/package.json', ignoreStatus); + assert.equal(result6.status, 404); + }); }); diff --git a/js/api_tests/src/test_context.js b/js/api_tests/src/test_context.js index f6e26fc0..876d4dc4 100644 --- a/js/api_tests/src/test_context.js +++ b/js/api_tests/src/test_context.js @@ -3,7 +3,7 @@ import fsObj from 'fs'; import { getBuildConfig } from '../../config.mjs'; import RequestHandler from './request_handler.js'; import TestPlayerClient from './test_player_client.js'; -import { appsDir, rootDir, testsRootDir } from './utils.js'; +import { testsRootDir } from './utils.js'; const fs = fsObj.promises; diff --git a/js/api_tests/src/test_env.js b/js/api_tests/src/test_env.js index a0cbe5d6..a4d13045 100644 --- a/js/api_tests/src/test_env.js +++ b/js/api_tests/src/test_env.js @@ -1,7 +1,7 @@ import { Foobar2000TestContextFactory } from './test_context_foobar2000.js' import { DeadbeefTestContextFactory } from './test_context_deadbeef.js' import { selectBySystem } from './utils.js'; -import qunit from 'qunit' +import { beforeAll, afterAll, beforeEach, afterEach } from 'vitest'; function getContextFactory() { @@ -31,26 +31,10 @@ export const config = context.config; export const client = context.client; export const outputConfigs = context.outputConfigs; -export function usePlayer(options) +export function setupPlayer(options) { - return { - before: () => context.beginSuite(options), - after: () => context.endSuite(), - beforeEach: () => context.beginTest(), - afterEach: () => context.endTest(), - }; + beforeAll(() => context.beginSuite(options)); + afterAll(() => context.endSuite()); + beforeEach(() => context.beginTest()); + afterEach(() => context.endTest()); } - -const maxFailedTests = 10; -let failedTests = 0; - -qunit.on('testEnd', event => { - if (event.status !== 'failed') - return; - - if (++failedTests < maxFailedTests) - return; - - console.error('Too many test failures, stopping'); - qunit.config.queue.length = 0; -}); diff --git a/js/api_tests/vitest.config.js b/js/api_tests/vitest.config.js new file mode 100644 index 00000000..0184ca70 --- /dev/null +++ b/js/api_tests/vitest.config.js @@ -0,0 +1,13 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + include: ['./src/*_tests.js'], + bail: 10, + retry: 1, + maxConcurrency: 1, + fileParallelism: false, + testTimeout: 10000, + teardownTimeout: 10000, + } +}); diff --git a/js/webui/package.json b/js/webui/package.json index 5625fa59..5e520f47 100644 --- a/js/webui/package.json +++ b/js/webui/package.json @@ -38,7 +38,6 @@ "less": "^4.1.3", "less-loader": "^10.2.0", "mini-css-extract-plugin": "^2.7.2", - "qunit": "^2.19.3", "style-loader": "^3.3.1", "terser-webpack-plugin": "5.3.6", "url-loader": "^4.1.1", diff --git a/js/webui/sources.cmake b/js/webui/sources.cmake index 83b631f5..59ff6f0e 100644 --- a/js/webui/sources.cmake +++ b/js/webui/sources.cmake @@ -63,8 +63,6 @@ src/settings_store.js src/sortable.js src/status_bar.js src/style.less -src/tests/index.html -src/tests/index.js src/timer.js src/touch_mode_controller.js src/urls.js diff --git a/js/webui/src/tests/index.html b/js/webui/src/tests/index.html deleted file mode 100644 index 7f54ccbe..00000000 --- a/js/webui/src/tests/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - -
- -