11import {
22 capitalizeReleaseType ,
3+ guessDjMixRelease ,
34 guessLiveRelease ,
45 guessTypesForRelease ,
56 guessTypesFromTitle ,
@@ -15,7 +16,7 @@ import type { FunctionSpec } from '../utils/test_spec.ts';
1516
1617describe ( 'release types' , ( ) => {
1718 describe ( 'guess types for release' , ( ) => {
18- const passingCases : Array < [ string , HarmonyRelease , string [ ] ] > = [
19+ const passingCases : Array < [ string , HarmonyRelease , ReleaseGroupType [ ] ] > = [
1920 [ 'should detect EP type from title' , makeRelease ( 'Wake of a Nation (EP)' ) , [ 'EP' ] ] ,
2021 [ 'should keep existing types' , makeRelease ( 'Wake of a Nation (EP)' , [ 'Interview' ] ) , [ 'EP' , 'Interview' ] ] ,
2122 [ 'should detect live type from title' , makeRelease ( 'One Second (Live)' ) , [ 'Live' ] ] ,
@@ -24,6 +25,15 @@ describe('release types', () => {
2425 makeRelease ( 'One Second' , undefined , [ { title : 'One Second - Live' } , { title : 'Darker Thoughts - Live' } ] ) ,
2526 [ 'Live' ] ,
2627 ] ,
28+ [ 'should detect DJ-mix type from title' , makeRelease ( 'DJ-Kicks (Forest Swords) [DJ Mix]' ) , [ 'DJ-mix' ] ] ,
29+ [
30+ 'should detect DJ-mix type from tracks' ,
31+ makeRelease ( 'DJ-Kicks: Modeselektor' , undefined , [
32+ { title : 'PREY - Mixed' } ,
33+ { title : 'Permit Riddim - Mixed' } ,
34+ ] ) ,
35+ [ 'DJ-mix' ] ,
36+ ] ,
2737 ] ;
2838
2939 passingCases . forEach ( ( [ description , release , expected ] ) => {
@@ -42,10 +52,132 @@ describe('release types', () => {
4252 [ 'should detect type before comment' , 'Enter Suicidal Angels - EP (Remastered 2021)' , new Set ( [ 'EP' ] ) ] ,
4353 [ 'should detect EP suffix' , 'Zero Distance EP' , new Set ( [ 'EP' ] ) ] ,
4454 [ 'should detect demo type' , 'Parasite Inc. (Demo)' , new Set ( [ 'Demo' ] ) ] ,
55+ // Soundtrack releases
56+ ...( [
57+ // Titles with original/official <medium> soundtrack
58+ 'The Lord of the Rings: The Return of the King (Original Motion Picture Soundtrack)' ,
59+ 'The Bodyguard - Original Soundtrack Album' ,
60+ 'Plants Vs. Zombies (Original Video Game Soundtrack)' ,
61+ 'Stardew Valley (Original Game Soundtrack)' ,
62+ 'L.A. Noire Official Soundtrack' ,
63+ 'Tarzan (Deutscher Original Film-Soundtrack)' ,
64+ 'Die Eiskönigin Völlig Unverfroren (Deutscher Original Film Soundtrack)' ,
65+ // Soundtrack from the ... <medium>
66+ 'KPop Demon Hunters (Soundtrack from the Netflix Film)' ,
67+ 'The Witcher: Season 2 (Soundtrack from the Netflix Original Series)' ,
68+ 'The White Lotus (Soundtrack from the HBO® Original Limited Series)' ,
69+ 'Inception (Music from the Motion Picture)' ,
70+ // Releases referring to score instead of soundtrack
71+ 'Fantastic Mr. Fox - Additional Music From The Original Score By Alexandre Desplat - The Abbey Road Mixes' ,
72+ 'Scott Pilgrim Vs. The World (Original Score Composed by Nigel Godrich)' ,
73+ 'F1® The Movie (Original Score By Hans Zimmer)' ,
74+ 'EUPHORIA SEASON 2 OFFICIAL SCORE (FROM THE HBO ORIGINAL SERIES)' ,
75+ 'The Bible (Official Score Soundtrack)' ,
76+ 'The Good Wife (The Official TV Score)' ,
77+ // German release titles
78+ 'Get Up (Der Original Soundtrack zum Kinofilm)' ,
79+ 'Ein Mädchen namens Willow - Soundtrack zum Film' ,
80+ 'Das Boot (Soundtrack zur TV Serie, zweite Staffel)' ,
81+ // Swedish release titles
82+ 'Fucking Åmål - Musiken från filmen' ,
83+ 'Fejkpatient (Musik från TV-serien)' ,
84+ 'Kärlek Fårever (Soundtrack till Netflix-filmen)' ,
85+ // Norwegian release titles
86+ 'Kvitebjørn (Musikken fra filmen)' ,
87+ 'Døden på Oslo S (Musikken fra teaterforestillingen)' ,
88+ // Musical releases
89+ 'The Lion King: Original Broadway Cast Recording' ,
90+ ] . map ( (
91+ title ,
92+ ) : FunctionSpec < typeof guessTypesFromTitle > [ number ] => [
93+ `should detect soundtrack type (${ title } )` ,
94+ title ,
95+ new Set ( [ 'Soundtrack' ] ) ,
96+ ] ) ) ,
97+ // Remix releases
98+ ...( [
99+ 'Human (Paul Woolford Remix)' ,
100+ 'Paper Romance (Purple Disco Machine Remix - Edit)' ,
101+ 'Paper Romance (Purple Disco Machine Remix) [Edit]' ,
102+ 'Paper Romance (Purple Disco Machine Remix) (Edit)' ,
103+ 'Paper Romance (Purple Disco Machine Remix; Edit)' ,
104+ "Stay (Don't Go Away) [feat. Raye] [Nicky Romero Remix]" ,
105+ 'Anti‐Hero (Kungs remix extended version)' ,
106+ 'Remix' ,
107+ 'Anti‐Hero (Remixes)' ,
108+ 'The One (feat. Daddy Yankee) [The Remixes]' ,
109+ 'The Remixes' ,
110+ 'The Remixes - Vol.1' ,
111+ 'The Remixes, Pt. 1' ,
112+ 'Remixes' ,
113+ 'Remixes 81>04' ,
114+ 'Never Say Never - The Remixes' ,
115+ 'Skin: The Remixes' ,
116+ 'The Hills Remixes' ,
117+ 'MIDI Kittyy - The Remixes Vol 1' ,
118+ 'The Slow Rush B-Sides & Remixes' ,
119+ 'Remixed' ,
120+ 'Remixed (2003 Remaster)' ,
121+ 'Remixed Sides' ,
122+ 'Remixed: The Definitive Collection' ,
123+ 'The Hits: Remixed' ,
124+ 'Remixed & Revisited' ,
125+ 'Revived Remixed Revisited' ,
126+ 'Welcome To My World (Remixed)' ,
127+ 'Mörkrets Narr Remixed' ,
128+ ] . map ( (
129+ title ,
130+ ) : FunctionSpec < typeof guessTypesFromTitle > [ number ] => [
131+ `should detect remix type (${ title } )` ,
132+ title ,
133+ new Set ( [ 'Remix' ] ) ,
134+ ] ) ) ,
135+ [ 'should not treat a premix as remix' , 'Wild (premix version)' , new Set ( ) ] ,
136+ // DJ Mix releases
137+ ...( [
138+ 'Kitsuné Musique Mixed by YOU LOVE HER (DJ Mix)' ,
139+ 'Club Life - Volume One Las Vegas (Continuous DJ Mix)' ,
140+ 'DJ-Kicks (Forest Swords) [DJ Mix]' ,
141+ 'Paragon Continuous DJ Mix' ,
142+ 'Babylicious (Continuous DJ Mix by Baby Anne)' ,
143+ ] . map ( (
144+ title ,
145+ ) : FunctionSpec < typeof guessTypesFromTitle > [ number ] => [
146+ `should detect DJ-mix type (${ title } )` ,
147+ title ,
148+ new Set ( [ 'DJ-mix' ] ) ,
149+ ] ) ) ,
150+ [ 'should not treat just DJ mix as DJ-mix' , 'DJ mix' , new Set ( ) ] ,
151+ // Multiple types
152+ [
153+ 'should detect both remix and soundtrack type' ,
154+ 'The Sims 2: Nightlife (Remixes) (Original Soundtrack)' ,
155+ new Set ( [ 'Remix' , 'Soundtrack' ] ) ,
156+ ] ,
157+ [
158+ 'should detect both remix and soundtrack type' ,
159+ 'Remixes - EP' ,
160+ new Set ( [ 'EP' , 'Remix' ] ) ,
161+ ] ,
162+ ] ;
163+
164+ const passingCaseSensitiveCases : FunctionSpec < typeof guessTypesFromTitle > = [
165+ // Soundtrack releases
166+ ...( [
167+ // Releases with OST abbreviation
168+ 'O.S.T. Das Boot' ,
169+ 'Alvin & The Chipmunks / OST' ,
170+ ] . map ( (
171+ title ,
172+ ) : FunctionSpec < typeof guessTypesFromTitle > [ number ] => [
173+ `should detect soundtrack type (${ title } )` ,
174+ title ,
175+ new Set ( [ 'Soundtrack' ] ) ,
176+ ] ) ) ,
45177 ] ;
46178
47179 describe ( 'exact case match' , ( ) => {
48- passingCases . forEach ( ( [ description , input , expected ] ) => {
180+ [ ... passingCases , ... passingCaseSensitiveCases ] . forEach ( ( [ description , input , expected ] ) => {
49181 it ( description , ( ) => {
50182 assertEquals ( guessTypesFromTitle ( input ) , expected ) ;
51183 } ) ;
@@ -87,6 +219,81 @@ describe('release types', () => {
87219 } ) ;
88220 } ) ;
89221
222+ describe ( 'guess DJ-mix release' , ( ) => {
223+ const passingCases : FunctionSpec < typeof guessDjMixRelease > = [
224+ [ 'should be true if all tracks have mixed type' , [
225+ {
226+ tracklist : [
227+ { title : 'Heavenly Hell (feat. Ne-Yo) (Mixed)' } ,
228+ { title : 'Clap Back (feat. Raphaella) (Mixed)' } ,
229+ { title : '2x2 (Mixed)' } ,
230+ ] ,
231+ } ,
232+ ] , true ] ,
233+ [ 'should be true if all tracks on one medium have mixed type' , [
234+ {
235+ tracklist : [
236+ { title : 'PREY - Mixed' } ,
237+ { title : 'Permit Riddim - Mixed' } ,
238+ { title : 'MEGA MEGA MEGA (DJ-Kicks) - Mixed' } ,
239+ ] ,
240+ } ,
241+ {
242+ tracklist : [
243+ { title : 'PREY' } ,
244+ { title : 'Permit Riddim' } ,
245+ { title : 'MEGA MEGA MEGA (DJ-Kicks)' } ,
246+ ] ,
247+ } ,
248+ ] , true ] ,
249+ [ 'should support " - Mixed" style' , [
250+ {
251+ tracklist : [
252+ { title : 'Salute - Mixed' } ,
253+ { title : 'Friday - Mixed' } ,
254+ ] ,
255+ } ,
256+ ] , true ] ,
257+ [ 'should support case insensitive of mixed' , [
258+ {
259+ tracklist : [
260+ { title : 'Heavenly Hell (feat. Ne-Yo) (mixed)' } ,
261+ { title : 'Clap Back (feat. Raphaella) (mixed)' } ,
262+ { title : '2x2 (mixed)' } ,
263+ ] ,
264+ } ,
265+ ] , true ] ,
266+ [ 'should support mixed usage of formats' , [
267+ {
268+ tracklist : [
269+ { title : 'Heavenly Hell (feat. Ne-Yo) [Mixed]' } ,
270+ { title : 'Clap Back (feat. Raphaella) (Mixed)' } ,
271+ { title : '2x2 - Mixed' } ,
272+ ] ,
273+ } ,
274+ ] , true ] ,
275+ [ 'should be false if not all tracks are mixed' , [
276+ {
277+ tracklist : [
278+ { title : 'Heavenly Hell (feat. Ne-Yo) (Mixed)' } ,
279+ { title : 'Clap Back (feat. Raphaella)' } ,
280+ { title : '2x2 (Mixed)' } ,
281+ ] ,
282+ } ,
283+ ] , false ] ,
284+ [ 'should be false for empty tracklist' , [ {
285+ tracklist : [ ] ,
286+ } ] , false ] ,
287+ [ 'should be false for no medium' , [ ] , false ] ,
288+ ] ;
289+
290+ passingCases . forEach ( ( [ description , input , expected ] ) => {
291+ it ( description , ( ) => {
292+ assertEquals ( guessDjMixRelease ( input ) , expected ) ;
293+ } ) ;
294+ } ) ;
295+ } ) ;
296+
90297 describe ( 'capitalize release type' , ( ) => {
91298 const passingCases : FunctionSpec < typeof capitalizeReleaseType > = [
92299 [ 'should uppercase first letter' , 'single' , 'Single' ] ,
0 commit comments