Changeset e679bce in Klonkt for test/mixtape-ui.test.js


Ignore:
Timestamp:
08/22/2026 09:54:51 AM (3 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
8bb3b09
Parents:
16fd4fe
Message:

Het bandje speelt als bandje: een cassette, een object, spoelen in seconden

Robins correctie (21-8): vooruit en achteruit deden hier next()/prev(), en dat
is een playlistgebaar. Dan is het een lijst met een cassetteplaatje erboven.
Een cassette kent geen "volgend nummer" -- je houdt de knop ingedrukt, de band
loopt door, en je laat los waar je bent.

Dat kan omdat audio-player.js een wachtrij al in EEN doorlopende
MediaSource-tijdlijn giet: "een trackwissel is een positie, geen omschakeling".
Een bandje IS die tijdlijn. Dus:

  • seekBy(seconden) op de speler, over de nummergrenzen heen. Op de blob-motor (iOS, geen MSE) bestaat die tijdlijn niet; daar loopt spoelen tot de rand van het nummer en stapt dan naar de buur. Grover, maar eerlijker dan doen alsof.
  • Bandmodus: de speler toont het BANDJE als titel met het lopende nummer eronder, en de teller loopt over de hele band in plaats van per nummer. Dat is wat "een object, geen losse tracks" betekent op het scherm.
  • Vasthouden versnelt (4x tot 16x), loslaten stopt -- ook als je buiten de knop loslaat. Een korte tik spoelt vijf seconden, want vasthouden is met een spatiebalk geen gebaar.

Een echte cassette, als SVG. Verhouding 100,4 x 63,8 mm, de maat van een
compact cassette, dus viewBox 314x200: behuizing, labelvlak met de titel erop,
venster, twee spoelen met tandjes die meedraaien, de bandpakketten, vier
schroefjes en de openingen voor de kop en de capstans. De vorige versie waren
twee CSS-schijfjes.

Twee dingen die alleen door het echt te draaien boven kwamen:

  • audio-player.js kiest zijn knoppen met een lijst KLASSENAMEN (PLAY_SELECTOR), niet met een regel over data-attributen. De cassetteknop droeg alle juiste data-pcms-* en deed niets. Er staat nu een test op.
  • De sessie sloeg displayTimes().cur op als trackpositie. In bandmodus is dat de bandteller, dus een hersteld bandje sprong naar een plek die in dat nummer niet bestaat. Daarvoor is trackTijd() afgesplitst.

MOD_V 53, style.css v107, audio-player v35.

Co-Authored-By: Claude Opus 5 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/mixtape-ui.test.js

    r16fd4fe re679bce  
    8686  // bestaat en sloeg zichzelf dan over -- groen zonder iets te meten.
    8787  const html = AudioEmbedService.embedPlaylistShortcodes('<p>[[playlist:tape]]</p>', (id) => (id === 'tape' ? pl : null));
    88   assert.match(html, /📼 Mixtape/, 'een mixtape hoort zichzelf zo te noemen');
     88  // Het teken zat eerst in de tekst; nu staat er een echte cassette getekend en
     89  // is het woord genoeg. De eis blijft dezelfde: hij noemt zichzelf goed.
     90  assert.match(html, /class="tape-kind">Mixtape</, 'een mixtape hoort zichzelf zo te noemen');
    8991  assert.doesNotMatch(html, /💿 Album/, 'en niet het jasje van een album te dragen');
    9092});
     
    129131  assert.doesNotMatch(html, /class="post-album"/);
    130132});
     133
     134test('de cassetteknop staat in de selectorlijst van de speler', () => {
     135  // DIT IS DE TEST DIE ONTBRAK. De markup-tests hierboven waren groen terwijl
     136  // op de knop drukken niets deed: audio-player.js kiest zijn knoppen met een
     137  // lijst met KLASSENAMEN, niet met een regel over data-attributen. Alle juiste
     138  // data-pcms-* dragen helpt dan niets.
     139  const speler = fs.readFileSync('src/assets/js/audio-player.js', 'utf8');
     140  const m = speler.match(/const PLAY_SELECTOR =\s*\n?\s*'([^']+)'/);
     141  assert.ok(m, 'PLAY_SELECTOR moet te vinden zijn -- is hij hernoemd, dan dekt deze test niets meer');
     142  assert.match(m[1], /\.tape-btn--play/,
     143    'zonder deze klasse doet de afspeelknop van het bandje niets');
     144});
     145
     146test('een bandje gaat als EEN object de speler in', () => {
     147  const speler = fs.readFileSync('src/assets/js/audio-player.js', 'utf8');
     148  // De stand moet vanaf het blok worden doorgegeven; zonder dit is een mixtape
     149  // in de speler gewoon weer een rij nummers.
     150  assert.match(speler, /asTape: album\.dataset\.pcmsAlbumKind === 'mixtape'/);
     151  // En hij moet een paginawissel overleven, anders valt de speler halverwege
     152  // terug op de nummertitel.
     153  assert.match(speler, /queue, currentIndex, albumName, tapeMode,/, 'in de sessie opslaan');
     154  assert.match(speler, /tapeMode = !!s\.tapeMode;/, 'en terugzetten');
     155  // De opgeslagen tijd is de positie BINNEN het nummer, ook in bandmodus: bij
     156  // herstellen begint de keten opnieuw. Slaat hij de bandteller op, dan springt
     157  // een hersteld bandje naar een plek die in dat nummer niet bestaat.
     158  assert.match(speler, /time: trackTijd\(\)\.cur \|\| 0,/);
     159});
     160
     161test('spoelen gaat in seconden, niet per nummer', () => {
     162  const mod = fs.readFileSync('src/assets/js/mod/tape.js', 'utf8');
     163  assert.match(mod, /seekBy\(/, 'spoelen hoort over de tijdlijn te gaan');
     164  // next()/prev() mag hier niet meer voorkomen als spoelgebaar: dat is een
     165  // playlistknop en maakt van de cassette een lijst met een plaatje.
     166  assert.doesNotMatch(mod, /p\.next\(\); else p\.prev\(\)/, 'de oude sprong per nummer');
     167});
Note: See TracChangeset for help on using the changeset viewer.