UNPKG

8.95 kBJavaScriptView Raw
1var Combine = require('../')
2var test = require('tape')
3
4test('combine is a function', function (t) {
5 t.equal(typeof Combine, 'function')
6 t.end()
7})
8
9test('combine one module', function (t) {
10 const cats = {
11 gives: 'cats',
12 create: () => {
13 t.ok(true, 'create is called')
14 return () => () => true
15 }
16 }
17
18 var api = Combine([cats])
19
20 t.ok(api.cats, 'Combine returns an object with keys that match the keys given by all the modules')
21 t.end()
22})
23
24test('combine two modules', function (t) {
25 const cats = {
26 gives: 'cats',
27 create: () => {
28 t.ok(true, 'create is called')
29 return () => () => true
30 }
31 }
32
33 const client = {
34 needs: {cats: 'first'},
35 gives: 'client',
36 create: (api) => {
37 t.ok(api.cats, 'create is called with object that has keys given by other modules')
38 return () => () => true
39 }
40 }
41
42 var api = Combine([client, cats])
43
44 t.ok(api.cats && api.client, 'Combine returns an object with keys that match the keys given by all the modules')
45 t.end()
46})
47
48test('combine can take a single module', function (t) {
49 t.plan(1)
50
51 const cats = {
52 gives: 'cats',
53 create: () => {
54 return () => () => true
55 }
56 }
57
58 const sockets = Combine(cats)
59
60 t.ok(sockets.cats, 'Combine returns an object with keys that match the keys given by all the modules')
61 t.end()
62})
63
64test('one module depends on a module that depends on another', function (t) {
65 const a = {
66 needs: {b: 'first'},
67 gives: 'a',
68 create: (api) => api.b
69 }
70 const b = {
71 needs: {c: 'first'},
72 gives: 'b',
73 create: (api) => api.c
74 }
75 const c = {
76 gives: 'c',
77 create: () => () => true
78 }
79
80 var api = Combine([a, c, b])
81 t.ok(api.a[0]())
82 api = Combine([a, b, c])
83 t.ok(api.a[0]())
84 api = Combine([c, b, a])
85 t.ok(api.a[0]())
86 t.end()
87})
88
89test('two modules depend on each other', function (t) {
90 const cats = {
91 needs: {dogs: 'first'},
92 gives: 'cats',
93 create: (api) => {
94 t.ok(api.dogs, 'api provides the needed dep')
95 return () => true
96 }
97 }
98
99 const dogs = {
100 needs: {cats: 'first'},
101 gives: 'dogs',
102 create: (api) => {
103 t.ok(api.cats, 'api provides the needed dep')
104 return () => true
105 }
106 }
107 var api = Combine([cats, dogs])
108 t.ok(api.cats && api.dogs, 'Combine returns an object with keys that match the keys given by all the modules')
109 t.end()
110})
111
112test('a module depends on itself', function (t) {
113 const factorial = {
114 needs: {factorial: 'first'},
115 gives: 'factorial',
116 create: (api) => {
117 t.ok(api.factorial, 'api provides the needed dep')
118 return (num) => {
119 if (num === 1) return 1
120 else return num * api.factorial(num - 1)
121 }
122 }
123 }
124
125 var api = Combine([factorial])
126 t.ok(api.factorial, 'Combine returns an object with keys that match the keys given by all the modules')
127 t.equal(api.factorial[0](4), 24)
128 t.end()
129})
130
131test('throws if need type is not first, map or reduce', function (t) {
132 const cats = {
133 gives: 'cats',
134 create: () => {
135 t.ok(true, 'create is called')
136 return () => () => true
137 }
138 }
139
140 const client = {
141 needs: {cats: 'nope'},
142 gives: 'client',
143 create: (api) => {
144 t.ok(api.cats, 'create is called with object that has keys given by other modules')
145 return () => ({ client: api.cats })
146 }
147 }
148
149 t.throws(() => Combine([client, cats]))
150
151 client.needs.cats = 'first'
152 var api = Combine([client, cats])
153 t.ok(api, 'needs first is ok')
154
155 client.needs.cats = 'map'
156 api = Combine([client, cats])
157 t.ok(api, 'needs map is ok')
158
159 client.needs.cats = 'reduce'
160 api = Combine([client, cats])
161 t.ok(api, 'needs reduce is ok')
162
163 t.end()
164})
165
166test('when a module needs a map of dependencies it receives an array of all the modules', function (t) {
167 const a = {
168 needs: {ideas: 'map'},
169 gives: 'a',
170 create: (api) => api.ideas
171 }
172 const b = {
173 gives: 'ideas',
174 create: () => () => 'sink'
175 }
176 const c = {
177 gives: 'ideas',
178 create: () => () => 'swim'
179 }
180
181 var api = Combine([a, b, c])
182 t.ok(Array.isArray(api.a[0]()))
183 t.end()
184})
185
186test('when a module needs the first of dependencies it receives the first module to return a value', function (t) {
187 const a = {
188 needs: {ideas: 'first'},
189 gives: 'a',
190 create: (api) => api.ideas
191 }
192 const b = {
193 gives: 'ideas',
194 create: () => () => {}
195 }
196 const c = {
197 gives: 'ideas',
198 create: () => () => 'swim'
199 }
200
201 var api = Combine([a, b, c])
202 t.equal(api.a[0](), 'swim')
203 t.end()
204})
205
206test('when a module needs the first of dependencies it receives the first module to return a value. Depends on order passed to combine', function (t) {
207 const a = {
208 needs: {ideas: 'first'},
209 gives: 'a',
210 create: (api) => api.ideas
211 }
212 const b = {
213 gives: 'ideas',
214 create: () => () => 'sink'
215 }
216 const c = {
217 gives: 'ideas',
218 create: () => () => 'swim'
219 }
220
221 var api = Combine([a, b, c])
222 t.equal(api.a[0](), 'sink')
223 t.end()
224})
225
226test('when a module needs the reduce of dependencies it receives the result of applying all', function (t) {
227 const a = {
228 needs: {ideas: 'reduce'},
229 gives: 'a',
230 create: (api) => api.ideas
231 }
232 const b = {
233 gives: 'ideas',
234 create: () => (ideas) => ideas + 'sink'
235 }
236 const c = {
237 gives: 'ideas',
238 create: () => (ideas) => ideas + 'swim'
239 }
240
241 var api = Combine([a, b, c])
242 t.equal(api.a[0](''), 'sinkswim')
243 api = Combine([a, c, b])
244 t.equal(api.a[0](''), 'swimsink', 'ordering works correctly')
245 t.end()
246})
247
248test('a module can give multiple exports', function (t) {
249 const a = {
250 gives: {ideas: true, thoughts: true},
251 create: () => ({
252 ideas: () => 'idea',
253 thoughts: () => 'thought'
254 })
255 }
256
257 var api = Combine([a])
258 t.ok(api.ideas && api.thoughts)
259 t.end()
260})
261
262test('a module can need multiple imports', function (t) {
263 const a = {
264 needs: {ideas: 'first', thoughts: 'first'},
265 gives: 'a',
266 create: (api) => () => api.ideas() + api.thoughts()
267 }
268
269 const b = {
270 gives: 'ideas',
271 create: () => () => 'idea'
272 }
273 const c = {
274 gives: 'thoughts',
275 create: () => () => 'thought'
276 }
277
278 var api = Combine([a, b, c])
279 t.equal(api.a[0](), 'ideathought')
280 t.end()
281})
282
283test('a needed module can return 0', function (t) {
284 t.plan(2)
285
286 const decrement = {
287 gives: 'decrement',
288 create: () => i => i - 1
289 }
290
291 const decrementOne = {
292 gives: 'decrementOne',
293 needs: {decrement: 'first'},
294 create: api => () => api.decrement(1)
295 }
296
297 const sockets = Combine([decrement, decrementOne])
298
299 t.equal(sockets.decrement[0](1), 0, 'decrement returns zero')
300 t.equal(sockets.decrementOne[0](), 0, 'decrementOne returns zero')
301 t.end()
302})
303
304test('throws an error when a needed module is not given', function (t) {
305 const a = {
306 needs: {ideas: 'first'},
307 create: (api) => api.b
308 }
309 t.throws(() => Combine([a]), /unmet need/)
310 t.end()
311})
312
313test('map throws an error when no functions are provided to map', function (t) {
314 const a = {
315 gives: 'a',
316 needs: {ideas: 'map'},
317 create: (api) => api.ideas()
318 }
319 const b = {
320 gives: 'ideas',
321 create: (api) => null
322 }
323 t.throws(() => Combine([a, b]), /no functions available/)
324
325 t.end()
326})
327
328test('reduce throws an error when no functions are provided to reduce', function (t) {
329 const a = {
330 gives: 'a',
331 needs: {ideas: 'reduce'},
332 create: (api) => api.ideas()
333 }
334 const b = {
335 gives: 'ideas',
336 create: (api) => null
337 }
338 t.throws(() => Combine([a, b]), /no functions available/)
339
340 t.end()
341})
342
343test('first throws an error when no functions are provided to take first', function (t) {
344 const a = {
345 needs: {ideas: 'first'},
346 create: (api) => api.ideas()
347 }
348 const b = {
349 gives: 'ideas',
350 create: (api) => null
351 }
352 t.throws(() => Combine([a, b]), /no functions available/)
353
354 t.end()
355})
356
357test('combine throws an error when module does not have a create function', function (t) {
358 t.throws(() => Combine([{}]), /could not resolve any modules/)
359 t.end()
360})
361
362test('combine throws an error when not passed anything', function (t) {
363 t.throws(() => Combine(), /could not resolve any modules/)
364 t.end()
365})
366
367test('combine throws an error when passed a module with a create but no gives', function (t) {
368 const a = {
369 create: (api) => () => true
370 }
371 t.throws(() => Combine([a]), /could not resolve any modules/)
372 t.end()
373})
374
375test('combine throws an error when passed a module with a create when gives a string', function (t) {
376 const a = {
377 gives: 'nope',
378 create: (api) => {}
379 }
380 t.throws(() => Combine([a]), /create function should return a function or an object/)
381 t.end()
382})
383
384test('combine throws an error when passed a module with a create when gives is an object', function (t) {
385 const a = {
386 gives: {nope: true},
387 create: (api) => {}
388 }
389 t.throws(() => Combine([a]), /create function should return a function or an object/)
390 t.end()
391})
392
\No newline at end of file