55 * Tauri backend or API mocking.
66 */
77
8- import { describe , it , expect , beforeEach , vi } from 'vitest' ;
9- import { test , fc } from '@fast-check/vitest' ;
8+ import { beforeEach , describe , expect , it , vi } from 'vitest' ;
9+ import { fc , test } from '@fast-check/vitest' ;
1010
1111// -----------------------------------------------------------------------------
1212// Test Helpers: Create isolated library store instances for testing
@@ -59,38 +59,6 @@ function createTestLibraryStore(initialTracks = []) {
5959 return Array . from ( albumSet ) . sort ( ) ;
6060 } ,
6161
62- /**
63- * Get tracks grouped by artist
64- * Uses Object.create(null) to avoid prototype pollution with artist names like "toString"
65- */
66- get tracksByArtist ( ) {
67- const grouped = Object . create ( null ) ;
68- for ( const track of this . filteredTracks ) {
69- const artist = track . artist || 'Unknown Artist' ;
70- if ( ! grouped [ artist ] ) {
71- grouped [ artist ] = [ ] ;
72- }
73- grouped [ artist ] . push ( track ) ;
74- }
75- return grouped ;
76- } ,
77-
78- /**
79- * Get tracks grouped by album
80- * Uses Object.create(null) to avoid prototype pollution with album names like "valueOf"
81- */
82- get tracksByAlbum ( ) {
83- const grouped = Object . create ( null ) ;
84- for ( const track of this . filteredTracks ) {
85- const album = track . album || 'Unknown Album' ;
86- if ( ! grouped [ album ] ) {
87- grouped [ album ] = [ ] ;
88- }
89- grouped [ album ] . push ( track ) ;
90- }
91- return grouped ;
92- } ,
93-
9462 /**
9563 * Get track by ID
9664 * @param {string } trackId - Track ID
@@ -120,7 +88,6 @@ const trackArb = fc.record({
12088/** Generate an array of tracks */
12189const tracksArb = fc . array ( trackArb , { minLength : 0 , maxLength : 30 } ) ;
12290
123-
12491// -----------------------------------------------------------------------------
12592// Tests: formattedTotalDuration Getter
12693// -----------------------------------------------------------------------------
@@ -165,7 +132,7 @@ describe('Library Store - formattedTotalDuration', () => {
165132
166133 // Should match either "Xh Ym" or "X min"
167134 expect ( result ) . toMatch ( / ^ ( \d + h \d + m | \d + m i n ) $ / ) ;
168- }
135+ } ,
169136 ) ;
170137
171138 test . prop ( [ fc . integer ( { min : 0 , max : 59 * 60 * 1000 } ) ] ) (
@@ -176,7 +143,7 @@ describe('Library Store - formattedTotalDuration', () => {
176143 const result = store . formattedTotalDuration ;
177144
178145 expect ( result ) . toMatch ( / ^ \d + m i n $ / ) ;
179- }
146+ } ,
180147 ) ;
181148
182149 test . prop ( [ fc . integer ( { min : 60 * 60 * 1000 , max : 100 * 60 * 60 * 1000 } ) ] ) (
@@ -187,7 +154,7 @@ describe('Library Store - formattedTotalDuration', () => {
187154 const result = store . formattedTotalDuration ;
188155
189156 expect ( result ) . toMatch ( / ^ \d + h \d + m $ / ) ;
190- }
157+ } ,
191158 ) ;
192159} ) ;
193160
@@ -282,101 +249,6 @@ describe('Library Store - albums getter', () => {
282249 } ) ;
283250} ) ;
284251
285- // -----------------------------------------------------------------------------
286- // Tests: tracksByArtist and tracksByAlbum Getters
287- // -----------------------------------------------------------------------------
288-
289- describe ( 'Library Store - tracksByArtist getter' , ( ) => {
290- it ( 'returns empty object for empty library' , ( ) => {
291- const store = createTestLibraryStore ( [ ] ) ;
292- expect ( store . tracksByArtist ) . toEqual ( { } ) ;
293- } ) ;
294-
295- it ( 'groups tracks by artist' , ( ) => {
296- const tracks = [
297- { id : '1' , artist : 'Artist A' , title : 'Song 1' } ,
298- { id : '2' , artist : 'Artist B' , title : 'Song 2' } ,
299- { id : '3' , artist : 'Artist A' , title : 'Song 3' } ,
300- ] ;
301- const store = createTestLibraryStore ( tracks ) ;
302- const grouped = store . tracksByArtist ;
303-
304- expect ( Object . keys ( grouped ) ) . toEqual ( [ 'Artist A' , 'Artist B' ] ) ;
305- expect ( grouped [ 'Artist A' ] . length ) . toBe ( 2 ) ;
306- expect ( grouped [ 'Artist B' ] . length ) . toBe ( 1 ) ;
307- } ) ;
308-
309- it ( 'uses "Unknown Artist" for tracks without artist' , ( ) => {
310- const tracks = [
311- { id : '1' , artist : null , title : 'Song 1' } ,
312- { id : '2' , artist : '' , title : 'Song 2' } ,
313- { id : '3' , artist : undefined , title : 'Song 3' } ,
314- ] ;
315- const store = createTestLibraryStore ( tracks ) ;
316- const grouped = store . tracksByArtist ;
317-
318- expect ( Object . keys ( grouped ) ) . toEqual ( [ 'Unknown Artist' ] ) ;
319- expect ( grouped [ 'Unknown Artist' ] . length ) . toBe ( 3 ) ;
320- } ) ;
321-
322- test . prop ( [ tracksArb ] ) ( 'total tracks equals sum of grouped tracks' , ( tracks ) => {
323- const store = createTestLibraryStore ( tracks ) ;
324- const grouped = store . tracksByArtist ;
325- const totalGrouped = Object . values ( grouped ) . reduce ( ( sum , arr ) => sum + arr . length , 0 ) ;
326- expect ( totalGrouped ) . toBe ( tracks . length ) ;
327- } ) ;
328-
329- test . prop ( [ tracksArb ] ) ( 'each track appears exactly once' , ( tracks ) => {
330- const store = createTestLibraryStore ( tracks ) ;
331- const grouped = store . tracksByArtist ;
332- const allGroupedIds = Object . values ( grouped )
333- . flat ( )
334- . map ( ( t ) => t . id ) ;
335- const uniqueIds = new Set ( allGroupedIds ) ;
336- expect ( uniqueIds . size ) . toBe ( tracks . length ) ;
337- } ) ;
338- } ) ;
339-
340- describe ( 'Library Store - tracksByAlbum getter' , ( ) => {
341- it ( 'returns empty object for empty library' , ( ) => {
342- const store = createTestLibraryStore ( [ ] ) ;
343- expect ( store . tracksByAlbum ) . toEqual ( { } ) ;
344- } ) ;
345-
346- it ( 'groups tracks by album' , ( ) => {
347- const tracks = [
348- { id : '1' , album : 'Album A' , title : 'Song 1' } ,
349- { id : '2' , album : 'Album B' , title : 'Song 2' } ,
350- { id : '3' , album : 'Album A' , title : 'Song 3' } ,
351- ] ;
352- const store = createTestLibraryStore ( tracks ) ;
353- const grouped = store . tracksByAlbum ;
354-
355- expect ( Object . keys ( grouped ) ) . toEqual ( [ 'Album A' , 'Album B' ] ) ;
356- expect ( grouped [ 'Album A' ] . length ) . toBe ( 2 ) ;
357- expect ( grouped [ 'Album B' ] . length ) . toBe ( 1 ) ;
358- } ) ;
359-
360- it ( 'uses "Unknown Album" for tracks without album' , ( ) => {
361- const tracks = [
362- { id : '1' , album : null , title : 'Song 1' } ,
363- { id : '2' , album : '' , title : 'Song 2' } ,
364- ] ;
365- const store = createTestLibraryStore ( tracks ) ;
366- const grouped = store . tracksByAlbum ;
367-
368- expect ( Object . keys ( grouped ) ) . toEqual ( [ 'Unknown Album' ] ) ;
369- expect ( grouped [ 'Unknown Album' ] . length ) . toBe ( 2 ) ;
370- } ) ;
371-
372- test . prop ( [ tracksArb ] ) ( 'total tracks equals sum of grouped tracks' , ( tracks ) => {
373- const store = createTestLibraryStore ( tracks ) ;
374- const grouped = store . tracksByAlbum ;
375- const totalGrouped = Object . values ( grouped ) . reduce ( ( sum , arr ) => sum + arr . length , 0 ) ;
376- expect ( totalGrouped ) . toBe ( tracks . length ) ;
377- } ) ;
378- } ) ;
379-
380252// -----------------------------------------------------------------------------
381253// Tests: getTrack Method
382254// -----------------------------------------------------------------------------
@@ -414,7 +286,6 @@ describe('Library Store - getTrack', () => {
414286 } ) ;
415287} ) ;
416288
417-
418289// -----------------------------------------------------------------------------
419290// Tests: Statistics and State
420291// -----------------------------------------------------------------------------
0 commit comments