1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
import t from 'tap';
import {testContentFunctions} from '#test-lib';
t.test('generateContributionLinks (unit)', async t => {
const artist1 = {
name: 'Clark Powell',
directory: 'clark-powell',
urls: ['https://soundcloud.com/plazmataz'],
};
const artist2 = {
name: 'Grounder & Scratch',
directory: 'the-big-baddies',
urls: [],
};
const artist3 = {
name: 'Toby Fox',
directory: 'toby-fox',
urls: ['https://tobyfox.bandcamp.com/', 'https://toby.fox/'],
};
const annotation1 = null;
const annotation2 = 'Snooping';
const annotation3 = 'Arrangement';
await testContentFunctions(t, 'generateContributionLinks (unit 1)', async (t, evaluate) => {
const slots = {
showContribution: true,
showExternalLinks: true,
};
await evaluate.load({
mock: evaluate.mock(mock => ({
linkArtist: {
relations: mock
.function('linkArtist.relations', () => ({}))
.args([undefined, artist1]).next()
.args([undefined, artist2]).next()
.args([undefined, artist3]),
data: mock
.function('linkArtist.data', () => ({}))
.args([artist1]).next()
.args([artist2]).next()
.args([artist3]),
// This can be tweaked to return a specific (mocked) template
// for each artist if we need to test for slots in the future.
generate: mock.function('linkArtist.generate', () => 'artist link')
.repeat(3),
},
generateExternalIcon: {
data: mock
.function('generateExternalIcon.data', () => ({}))
.args([artist1.urls[0]]).next()
.args([artist3.urls[0]]).next()
.args([artist3.urls[1]]),
generate: mock
.function('generateExternalIcon.generate', () => ({
toString: () => 'icon',
setSlot: () => {},
}))
.repeat(3),
}
})),
});
evaluate({
name: 'linkContribution',
multiple: [
{args: [{artist: artist1, annotation: annotation1}]},
{args: [{artist: artist2, annotation: annotation2}]},
{args: [{artist: artist3, annotation: annotation3}]},
],
slots,
});
});
await testContentFunctions(t, 'generateContributionLinks (unit 2)', async (t, evaluate) => {
const slots = {
showContribution: false,
showExternalLinks: false,
};
await evaluate.load({
mock: evaluate.mock(mock => ({
linkArtist: {
relations: mock
.function('linkArtist.relations', () => ({}))
.args([undefined, artist1]).next()
.args([undefined, artist2]).next()
.args([undefined, artist3]),
data: mock
.function('linkArtist.data', () => ({}))
.args([artist1]).next()
.args([artist2]).next()
.args([artist3]),
generate: mock
.function(() => 'artist link')
.repeat(3),
},
// Even though icons are hidden, these are still called! The dependency
// tree is the same since whether or not the external icon links are
// shown is dependent on a slot, which is undefined and arbitrary at
// relations/data time (it might change on a whim at generate time).
generateExternalIcon: {
data: mock
.function('generateExternalIcon.data', () => ({}))
.repeat(3),
generate: mock
.function('generateExternalIcon.generate', () => ({
toString: () => 'icon',
setSlot: () => {},
}))
.repeat(3),
},
})),
});
evaluate({
name: 'linkContribution',
multiple: [
{args: [{artist: artist1, annotation: annotation1}]},
{args: [{artist: artist2, annotation: annotation2}]},
{args: [{artist: artist3, annotation: annotation3}]},
],
slots,
});
});
});
|