jevstrudel.git / test / metadata.test.mjs
1import { describe, expect, it } from 'vitest';
2import { getMetadata } from '../website/src/metadata_parser';
3
4describe.concurrent('Metadata parser', () => {
5  it('loads a tag from inline comment', async () => {
6    const tune = `// @title Awesome song`;
7    expect(getMetadata(tune)).toStrictEqual({
8      title: 'Awesome song',
9    });
10  });
11
12  it('loads many tags from inline comments', async () => {
13    const tune = `// @title Awesome song
14// @by Sam`;
15    expect(getMetadata(tune)).toStrictEqual({
16      title: 'Awesome song',
17      by: ['Sam'],
18    });
19  });
20
21  it('loads many tags from one inline comment', async () => {
22    const tune = `// @title Awesome song @by Sam`;
23    expect(getMetadata(tune)).toStrictEqual({
24      title: 'Awesome song',
25      by: ['Sam'],
26    });
27  });
28
29  it('loads a tag from a block comment', async () => {
30    const tune = `/* @title Awesome song */`;
31    expect(getMetadata(tune)).toStrictEqual({
32      title: 'Awesome song',
33    });
34  });
35
36  it('loads many tags from a block comment', async () => {
37    const tune = `/*
38@title Awesome song
39@by Sam
40*/`;
41    expect(getMetadata(tune)).toStrictEqual({
42      title: 'Awesome song',
43      by: ['Sam'],
44    });
45  });
46
47  it('loads many tags from many block comments', async () => {
48    const tune = `/* @title Awesome song */
49/* @by Sam */`;
50    expect(getMetadata(tune)).toStrictEqual({
51      title: 'Awesome song',
52      by: ['Sam'],
53    });
54  });
55
56  it('loads many tags from mixed comments', async () => {
57    const tune = `/* @title Awesome song */
58// @by Sam
59`;
60    expect(getMetadata(tune)).toStrictEqual({
61      title: 'Awesome song',
62      by: ['Sam'],
63    });
64  });
65
66  it('loads a title tag with quotes syntax', async () => {
67    const tune = `// "Awesome song"`;
68    expect(getMetadata(tune)).toStrictEqual({
69      title: 'Awesome song',
70    });
71  });
72
73  it('loads a title tag with quotes syntax among other tags', async () => {
74    const tune = `// "Awesome song" made @by Sam`;
75    expect(getMetadata(tune)).toStrictEqual({
76      title: 'Awesome song',
77      by: ['Sam'],
78    });
79  });
80
81  it('loads a title tag with quotes syntax from block comment', async () => {
82    const tune = `/* "Awesome song"
83@by Sam */`;
84    expect(getMetadata(tune)).toStrictEqual({
85      title: 'Awesome song',
86      by: ['Sam'],
87    });
88  });
89
90  it('does not load a title tag with quotes syntax after a prefix', async () => {
91    const tune = `// I don't care about those "metadata".`;
92    expect(getMetadata(tune)).toStrictEqual({});
93  });
94
95  it('does not load a title tag with quotes syntax after an other comment', async () => {
96    const tune = `// I don't care about those
97// "metadata"`;
98    expect(getMetadata(tune)).toStrictEqual({});
99  });
100
101  it('does not load a title tag with quotes syntax after other tags', async () => {
102    const tune = `/*
103@by Sam aka "Lady Strudel"
104    "Sandyyy"
105*/`;
106    expect(getMetadata(tune)).toStrictEqual({
107      by: ['Sam aka "Lady Strudel"', '"Sandyyy"'],
108    });
109  });
110
111  it('loads a tag list with comma-separated values syntax', async () => {
112    const tune = `// @by Sam, Sandy`;
113    expect(getMetadata(tune)).toStrictEqual({
114      by: ['Sam', 'Sandy'],
115    });
116  });
117
118  it('loads a tag list with duplicate keys syntax', async () => {
119    const tune = `// @by Sam
120// @by Sandy`;
121    expect(getMetadata(tune)).toStrictEqual({
122      by: ['Sam', 'Sandy'],
123    });
124  });
125
126  it('loads a tag list with duplicate keys syntax, with prefixes', async () => {
127    const tune = `// song @by Sam
128// samples @by Sandy`;
129    expect(getMetadata(tune)).toStrictEqual({
130      by: ['Sam', 'Sandy'],
131    });
132  });
133
134  it('loads many tag lists with duplicate keys syntax, within code', async () => {
135    const tune = `note("a3 c#4 e4 a4") // @by Sam @license CC0
136    s("bd hh sd hh") // @by Sandy @license CC BY-NC-SA`;
137    expect(getMetadata(tune)).toStrictEqual({
138      by: ['Sam', 'Sandy'],
139      license: ['CC0', 'CC BY-NC-SA'],
140    });
141  });
142
143  it('loads a tag list with duplicate keys syntax from block comment', async () => {
144    const tune = `/* @by Sam
145@by Sandy */`;
146    expect(getMetadata(tune)).toStrictEqual({
147      by: ['Sam', 'Sandy'],
148    });
149  });
150
151  it('loads a tag list with newline syntax', async () => {
152    const tune = `/*
153@by Sam
154    Sandy */`;
155    expect(getMetadata(tune)).toStrictEqual({
156      by: ['Sam', 'Sandy'],
157    });
158  });
159
160  it('loads a multiline tag from block comment', async () => {
161    const tune = `/*
162@details I wrote this song in February 19th, 2023.
163         It was around midnight and I was lying on
164         the sofa in the living room.
165*/`;
166    expect(getMetadata(tune)).toStrictEqual({
167      details:
168        'I wrote this song in February 19th, 2023. ' +
169        'It was around midnight and I was lying on the sofa in the living room.',
170    });
171  });
172
173  it('loads a multiline tag from block comment with duplicate keys', async () => {
174    const tune = `/*
175@details I wrote this song in February 19th, 2023.
176@details It was around midnight and I was lying on
177         the sofa in the living room.
178*/`;
179    expect(getMetadata(tune)).toStrictEqual({
180      details:
181        'I wrote this song in February 19th, 2023. ' +
182        'It was around midnight and I was lying on the sofa in the living room.',
183    });
184  });
185
186  it('loads a multiline tag from inline comments', async () => {
187    const tune = `// @details I wrote this song in February 19th, 2023.
188// @details It was around midnight and I was lying on
189// @details the sofa in the living room.
190*/`;
191    expect(getMetadata(tune)).toStrictEqual({
192      details:
193        'I wrote this song in February 19th, 2023. ' +
194        'It was around midnight and I was lying on the sofa in the living room.',
195    });
196  });
197
198  it('loads empty tags from inline comments', async () => {
199    const tune = `// @title
200// @by`;
201    expect(getMetadata(tune)).toStrictEqual({
202      title: '',
203      by: [],
204    });
205  });
206
207  it('loads tags with whitespaces from inline comments', async () => {
208    const tune = `   //   @title   Awesome   song   
209   //    @by   Sam   Tagada   `;
210    expect(getMetadata(tune)).toStrictEqual({
211      title: 'Awesome song',
212      by: ['Sam Tagada'],
213    });
214  });
215
216  it('loads tags with whitespaces from block comment', async () => {
217    const tune = `   /*   @title   Awesome   song   
218       @by   Sam   Tagada   */   `;
219    expect(getMetadata(tune)).toStrictEqual({
220      title: 'Awesome song',
221      by: ['Sam Tagada'],
222    });
223  });
224
225  it('loads empty tags from block comment', async () => {
226    const tune = `/* @title
227@by */`;
228    expect(getMetadata(tune)).toStrictEqual({
229      title: '',
230      by: [],
231    });
232  });
233
234  it('does not load tags if there is not', async () => {
235    const tune = `note("a3 c#4 e4 a4")`;
236    expect(getMetadata(tune)).toStrictEqual({});
237  });
238
239  it('does not load code that looks like a metadata tag', async () => {
240    const tune = `const str1 = '@title Awesome song'`;
241    // need a lexer to avoid this one, but it's a pretty rare use case:
242    // const tune = `const str1 = '// @title Awesome song'`;
243
244    expect(getMetadata(tune)).toStrictEqual({});
245  });
246});