| 1 | // De playlist-modal spreekt de taal van de pagina (16-8).
|
|---|
| 2 | //
|
|---|
| 3 | // Tot vandaag stonden de teksten hard in mod/playlist-editor.js. Dat viel niet
|
|---|
| 4 | // op omdat het toevallig de brontaal was: een Engelse of Duitse beheerder kreeg
|
|---|
| 5 | // een Nederlandse modal midden in een verder vertaalde pagina, en er is geen
|
|---|
| 6 | // foutmelding die dat meldt.
|
|---|
| 7 | //
|
|---|
| 8 | // Deze test sluit de KETEN, en dat is het punt -- er zijn drie schakels en elke
|
|---|
| 9 | // schakel kan los kloppen terwijl het geheel stuk is:
|
|---|
| 10 | //
|
|---|
| 11 | // het script vraagt T('x') -> de partial zet 'x' in het gegevensblok
|
|---|
| 12 | // -> i18n.js kent 'ple.x' in nl, en EN de
|
|---|
| 13 | //
|
|---|
| 14 | // Een nieuwe tekst toevoegen en een van de drie vergeten is de fout die dit
|
|---|
| 15 | // vangt, en juist de vergeten TAAL merkt niemand die in het Nederlands werkt.
|
|---|
| 16 | import { test } from 'node:test';
|
|---|
| 17 | import assert from 'node:assert/strict';
|
|---|
| 18 | import fs from 'node:fs';
|
|---|
| 19 |
|
|---|
| 20 | const script = fs.readFileSync('src/assets/js/mod/playlist-editor.js', 'utf8');
|
|---|
| 21 | const partial = fs.readFileSync('src/views/partials/playlist-editor.ejs', 'utf8');
|
|---|
| 22 | const i18n = fs.readFileSync('src/services/i18n.js', 'utf8');
|
|---|
| 23 |
|
|---|
| 24 | // Alle sleutels die het script opvraagt. De declaratie van T() zelf niet.
|
|---|
| 25 | const gevraagd = new Set(
|
|---|
| 26 | [...script.matchAll(/\bT\('([a-z0-9_]+)'\)/g)].map((m) => m[1])
|
|---|
| 27 | );
|
|---|
| 28 |
|
|---|
| 29 | test('het script vraagt uberhaupt sleutels op', () => {
|
|---|
| 30 | assert.ok(gevraagd.size > 20, `maar ${gevraagd.size} sleutels gevonden -- klopt het patroon nog?`);
|
|---|
| 31 | });
|
|---|
| 32 |
|
|---|
| 33 | test('elke gevraagde sleutel staat in het gegevensblok van de partial', () => {
|
|---|
| 34 | const blok = /data-playlist-editor-i18n><%-([\s\S]*?)%><\/script>/.exec(partial);
|
|---|
| 35 | assert.ok(blok, 'geen i18n-blok in de partial');
|
|---|
| 36 | const ontbreekt = [...gevraagd].filter((k) => !new RegExp(`\\b${k}:\\s*t\\('ple\\.${k}'\\)`).test(blok[1]));
|
|---|
| 37 | assert.deepEqual(ontbreekt, [], `niet doorgegeven vanuit de partial: ${ontbreekt.join(', ')}`);
|
|---|
| 38 | });
|
|---|
| 39 |
|
|---|
| 40 | test('elke sleutel bestaat in alle drie de talen', () => {
|
|---|
| 41 | // De taalblokken staan achter elkaar in i18n.js; per sleutel tellen hoe vaak
|
|---|
| 42 | // hij voorkomt is genoeg om een vergeten vertaling te vinden.
|
|---|
| 43 | const tekort = [];
|
|---|
| 44 | for (const k of gevraagd) {
|
|---|
| 45 | const n = (i18n.match(new RegExp(`'ple\\.${k}':`, 'g')) || []).length;
|
|---|
| 46 | if (n !== 3) tekort.push(`${k} (${n}x)`);
|
|---|
| 47 | }
|
|---|
| 48 | assert.deepEqual(tekort, [], `niet in alle drie de talen: ${tekort.join(', ')}`);
|
|---|
| 49 | });
|
|---|
| 50 |
|
|---|
| 51 | test('er staat geen losse Nederlandse knoptekst meer in het script', () => {
|
|---|
| 52 | // Grof maar effectief: dit zijn de woorden die er tot vandaag in stonden.
|
|---|
| 53 | // Komt er een terug, dan is iemand de T() vergeten.
|
|---|
| 54 | const verdacht = ['Annuleren', 'Opslaan', 'Aanmaken', 'Sluiten', 'Verslepen', 'Verwijderen',
|
|---|
| 55 | 'Beschikbare tracks', 'Geen resultaten', 'Uitgavedatum', 'Jaar', 'Artiest'];
|
|---|
| 56 | // COMMENTAAR ERAF. De eerste versie sloeg alarm op een regel die alleen
|
|---|
| 57 | // uitlegde wat er gebeurt -- en een test die op uitleg valt leert je hem
|
|---|
| 58 | // negeren.
|
|---|
| 59 | const code = script.replace(/\/\*[\s\S]*?\*\//g, ' ').replace(/^\s*\/\/.*$/gm, ' ');
|
|---|
| 60 | const gevonden = verdacht.filter((w) => new RegExp(`['"\`>]${w}`).test(code));
|
|---|
| 61 | assert.deepEqual(gevonden, [], `hardgecodeerde tekst terug in het script: ${gevonden.join(', ')}`);
|
|---|
| 62 | });
|
|---|
| 63 |
|
|---|
| 64 | test('het eigen gegevensblok botst niet met dat van de pagina', () => {
|
|---|
| 65 | // pageData() pakt met querySelector EEN blok. Zou deze partial het gewone
|
|---|
| 66 | // data-page-data gebruiken, dan won het blok van de gastpagina en bleef de
|
|---|
| 67 | // modal onvertaald -- zonder dat er iets omvalt.
|
|---|
| 68 | assert.ok(partial.includes('data-playlist-editor-i18n'), 'eigen kenmerk weg');
|
|---|
| 69 | assert.ok(!/data-page-data/.test(partial), 'de partial gebruikt het gedeelde blok');
|
|---|
| 70 | assert.ok(script.includes('data-playlist-editor-i18n'), 'het script leest het eigen blok niet');
|
|---|
| 71 | });
|
|---|