• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2
3const { test } = require('tap')
4const { retrieveFunding, getFundingInfo } = require('../../lib/utils/funding')
5
6test('empty tree', (t) => {
7  t.deepEqual(
8    getFundingInfo({}),
9    {
10      name: null,
11      dependencies: {},
12      length: 0
13    },
14    'should return empty list'
15  )
16  t.end()
17})
18
19test('single item missing funding', (t) => {
20  t.deepEqual(
21    getFundingInfo({ name: 'project',
22      dependencies: {
23        'single-item': {
24          name: 'single-item',
25          version: '1.0.0'
26        }
27      }}),
28    {
29      name: 'project',
30      dependencies: {},
31      length: 0
32    },
33    'should return empty list'
34  )
35  t.end()
36})
37
38test('funding object missing url', (t) => {
39  t.deepEqual(
40    getFundingInfo({ name: 'project',
41      dependencies: {
42        'single-item': {
43          name: 'single-item',
44          version: '1.0.0',
45          funding: {
46            type: 'Foo'
47          }
48        }
49      }}),
50    {
51      name: 'project',
52      dependencies: {},
53      length: 0
54    },
55    'should return empty list'
56  )
57  t.end()
58})
59
60test('use path if name is missing', (t) => {
61  t.deepEqual(
62    getFundingInfo({ name: undefined,
63      path: '/tmp/foo',
64      children: {
65        'single-item': {
66          name: 'single-item',
67          version: '1.0.0'
68        }
69      }}),
70    {
71      name: '/tmp/foo',
72      dependencies: {},
73      length: 0
74    },
75    'should use path as top level name'
76  )
77  t.end()
78})
79
80test('single item tree', (t) => {
81  t.deepEqual(
82    getFundingInfo({ name: 'project',
83      dependencies: {
84        'single-item': {
85          name: 'single-item',
86          version: '1.0.0',
87          funding: {
88            type: 'foo',
89            url: 'http://example.com'
90          }
91        }
92      }}),
93    {
94      name: 'project',
95      dependencies: {
96        'single-item': {
97          version: '1.0.0',
98          funding: {
99            type: 'foo',
100            url: 'http://example.com'
101          }
102        }
103      },
104      length: 1
105    },
106    'should return list with a single item'
107  )
108  t.end()
109})
110
111test('top-level funding info', (t) => {
112  t.deepEqual(
113    getFundingInfo({ name: 'project',
114      funding: 'http://example.com'
115    }),
116    {
117      name: 'project',
118      funding: {
119        url: 'http://example.com'
120      },
121      dependencies: {},
122      length: 0
123    },
124    'should return top-level item with normalized funding info'
125  )
126  t.end()
127})
128
129test('use string shorthand', (t) => {
130  t.deepEqual(
131    getFundingInfo({ name: 'project',
132      dependencies: {
133        'single-item': {
134          name: 'single-item',
135          version: '1.0.0',
136          funding: 'http://example.com'
137        }
138      }}),
139    {
140      name: 'project',
141      dependencies: {
142        'single-item': {
143          version: '1.0.0',
144          funding: {
145            url: 'http://example.com'
146          }
147        }
148      },
149      length: 1
150    },
151    'should return item with normalized funding info'
152  )
153  t.end()
154})
155
156test('duplicate items along the tree', (t) => {
157  t.deepEqual(
158    getFundingInfo({ name: 'project',
159      version: '2.3.4',
160      dependencies: {
161        'single-item': {
162          name: 'single-item',
163          version: '1.0.0',
164          funding: {
165            type: 'foo',
166            url: 'https://example.com'
167          },
168          dependencies: {
169            'shared-top-first': {
170              name: 'shared-top-first',
171              version: '1.0.0',
172              funding: {
173                type: 'foo',
174                url: 'https://example.com'
175              }
176            },
177            'sub-dep': {
178              name: 'sub-dep',
179              version: '1.0.0',
180              funding: {
181                type: 'foo',
182                url: 'https://example.com'
183              },
184              dependencies: {
185                'shared-nested-first': {
186                  name: 'shared-nested-first',
187                  version: '1.0.0',
188                  funding: {
189                    type: 'foo',
190                    url: 'https://example.com'
191                  },
192                  dependencies: {
193                    'shared-top-first': {
194                      name: 'shared-top-first',
195                      version: '1.0.0',
196                      funding: {
197                        type: 'foo',
198                        url: 'https://example.com'
199                      }
200                    }
201                  }
202                }
203              }
204            },
205            'shared-nested-first': {
206              name: 'shared-nested-first',
207              version: '1.0.0',
208              funding: {
209                type: 'foo',
210                url: 'https://example.com'
211              }
212            }
213          }
214        }
215      }}),
216    {
217      name: 'project',
218      version: '2.3.4',
219      dependencies: {
220        'single-item': {
221          version: '1.0.0',
222          funding: {
223            type: 'foo',
224            url: 'https://example.com'
225          },
226          dependencies: {
227            'shared-top-first': {
228              version: '1.0.0',
229              funding: {
230                type: 'foo',
231                url: 'https://example.com'
232              }
233            },
234            'sub-dep': {
235              version: '1.0.0',
236              funding: {
237                type: 'foo',
238                url: 'https://example.com'
239              }
240            },
241            'shared-nested-first': {
242              version: '1.0.0',
243              funding: {
244                type: 'foo',
245                url: 'https://example.com'
246              }
247            }
248          }
249        }
250      },
251      length: 4
252    },
253    'should return list with a single item'
254  )
255  t.end()
256})
257
258test('multi-level nested items tree', (t) => {
259  t.deepEqual(
260    getFundingInfo({ name: 'project',
261      dependencies: {
262        'first-level-dep': {
263          name: 'first-level-dep',
264          version: '1.0.0',
265          funding: {
266            type: 'foo',
267            url: 'https://example.com'
268          },
269          dependencies: {
270            'sub-dep': {
271              name: 'sub-dep',
272              version: '1.0.0',
273              funding: {
274                type: 'foo',
275                url: 'https://example.com'
276              },
277              dependencies: {
278                package: {
279                  name: 'sub-sub-dep',
280                  version: '1.0.0',
281                  funding: {
282                    type: 'foo',
283                    url: 'https://example.com'
284                  },
285                  dependencies: {}
286                }
287              }
288            }
289          }
290        }
291      }}),
292    {
293      name: 'project',
294      dependencies: {
295        'first-level-dep': {
296          version: '1.0.0',
297          funding: {
298            type: 'foo',
299            url: 'https://example.com'
300          },
301          dependencies: {
302            'sub-dep': {
303              version: '1.0.0',
304              funding: {
305                type: 'foo',
306                url: 'https://example.com'
307              },
308              dependencies: {
309                'sub-sub-dep': {
310                  version: '1.0.0',
311                  funding: {
312                    type: 'foo',
313                    url: 'https://example.com'
314                  }
315                }
316              }
317            }
318          }
319        }
320      },
321      length: 3
322    },
323    'should return list with all items'
324  )
325  t.end()
326})
327
328test('missing fund nested items tree', (t) => {
329  t.deepEqual(
330    getFundingInfo({ name: 'project',
331      dependencies: {
332        'first-level-dep': {
333          name: 'first-level-dep',
334          version: '1.0.0',
335          funding: {
336            type: 'foo'
337          },
338          dependencies: {
339            'sub-dep': {
340              name: 'sub-dep',
341              version: '1.0.0',
342              dependencies: {
343                'sub-sub-dep-01': {
344                  name: 'sub-sub-dep-01',
345                  version: '1.0.0',
346                  funding: {
347                    type: 'foo',
348                    url: 'https://example.com'
349                  },
350                  dependencies: {
351                    'non-funding-child': {
352                      name: 'non-funding-child',
353                      version: '1.0.0',
354                      dependencies: {
355                        'sub-sub-sub-dep': {
356                          name: 'sub-sub-sub-dep',
357                          version: '1.0.0',
358                          funding: {
359                            type: 'foo',
360                            url: 'https://example.com'
361                          }
362                        }
363                      }
364                    }
365                  }
366                },
367                'sub-sub-dep-02': {
368                  name: 'sub-sub-dep-02',
369                  version: '1.0.0',
370                  funding: {
371                    type: 'foo',
372                    url: 'https://example.com'
373                  },
374                  dependencies: {}
375                },
376                'sub-sub-dep-03': {
377                  name: 'sub-sub-dep-03',
378                  version: '1.0.0',
379                  funding: {
380                    type: 'foo',
381                    url: 'git://example.git'
382                  },
383                  dependencies: {
384                    'sub-sub-sub-dep-03': {
385                      name: 'sub-sub-sub-dep-03',
386                      version: '1.0.0',
387                      dependencies: {
388                        'sub-sub-sub-sub-dep': {
389                          name: 'sub-sub-sub-sub-dep',
390                          version: '1.0.0',
391                          funding: {
392                            type: 'foo',
393                            url: 'http://example.com'
394                          }
395                        }
396                      }
397                    }
398                  }
399                }
400              }
401            }
402          }
403        }
404      }}),
405    {
406      name: 'project',
407      dependencies: {
408        'sub-sub-dep-01': {
409          version: '1.0.0',
410          funding: {
411            type: 'foo',
412            url: 'https://example.com'
413          },
414          dependencies: {
415            'sub-sub-sub-dep': {
416              version: '1.0.0',
417              funding: {
418                type: 'foo',
419                url: 'https://example.com'
420              }
421            }
422          }
423        },
424        'sub-sub-dep-02': {
425          version: '1.0.0',
426          funding: {
427            type: 'foo',
428            url: 'https://example.com'
429          }
430        },
431        'sub-sub-sub-sub-dep': {
432          version: '1.0.0',
433          funding: {
434            type: 'foo',
435            url: 'http://example.com'
436          }
437        }
438      },
439      length: 4
440    },
441    'should return list excluding missing funding items'
442  )
443  t.end()
444})
445
446test('countOnly option', (t) => {
447  t.deepEqual(
448    getFundingInfo({ name: 'project',
449      dependencies: {
450        'first-level-dep': {
451          name: 'first-level-dep',
452          version: '1.0.0',
453          funding: {
454            type: 'foo'
455          },
456          dependencies: {
457            'sub-dep': {
458              name: 'sub-dep',
459              version: '1.0.0',
460              funding: {
461                type: 'foo',
462                url: 'https://example.com'
463              },
464              dependencies: {
465                'sub-sub-dep': {
466                  name: 'sub-sub-dep',
467                  version: '1.0.0',
468                  funding: {
469                    type: 'foo',
470                    url: 'https://example.com'
471                  }
472                },
473                dependencies: {}
474              }
475            },
476            'sub-sub-dep': {
477              name: 'sub-sub-dep',
478              version: '1.0.0',
479              funding: {
480                type: 'foo',
481                url: 'https://example.com'
482              }
483            }
484          }
485        }
486      }}, { countOnly: true }),
487    {
488      length: 2
489    },
490    'should return only the length property'
491  )
492  t.end()
493})
494
495test('handle different versions', (t) => {
496  t.deepEqual(
497    getFundingInfo({ name: 'project',
498      dependencies: {
499        foo: {
500          name: 'foo',
501          version: '1.0.0',
502          funding: {
503            type: 'foo',
504            url: 'https://example.com'
505          },
506          dependencies: {
507            bar: {
508              name: 'bar',
509              version: '1.0.0',
510              funding: {
511                type: 'foo',
512                url: 'https://example.com'
513              }
514            }
515          }
516        },
517        lorem: {
518          dependencies: {
519            fooo: {
520              name: 'foo',
521              version: '2.0.0',
522              funding: {
523                type: 'foo',
524                url: 'https://example.com'
525              },
526              dependencies: {
527                'foo-bar': {
528                  name: 'foo-bar',
529                  version: '1.0.0',
530                  funding: {
531                    type: 'foo',
532                    url: 'https://example.com'
533                  }
534                }
535              }
536            }
537          }
538        }
539      }
540    }, { countOnly: true }),
541    {
542      length: 4
543    },
544    'should treat different versions as diff packages'
545  )
546  t.end()
547})
548
549test('retrieve funding info from valid objects', (t) => {
550  t.deepEqual(
551    retrieveFunding({
552      url: 'http://example.com',
553      type: 'Foo'
554    }),
555    {
556      url: 'http://example.com',
557      type: 'Foo'
558    },
559    'should return standard object fields'
560  )
561  t.deepEqual(
562    retrieveFunding({
563      extra: 'Foo',
564      url: 'http://example.com',
565      type: 'Foo'
566    }),
567    {
568      extra: 'Foo',
569      url: 'http://example.com',
570      type: 'Foo'
571    },
572    'should leave untouched extra fields'
573  )
574  t.deepEqual(
575    retrieveFunding({
576      url: 'http://example.com'
577    }),
578    {
579      url: 'http://example.com'
580    },
581    'should accept url-only objects'
582  )
583  t.end()
584})
585
586test('retrieve funding info from invalid objects', (t) => {
587  t.deepEqual(
588    retrieveFunding({}),
589    {},
590    'should passthrough empty objects'
591  )
592  t.deepEqual(
593    retrieveFunding(),
594    undefined,
595    'should not care about undefined'
596  )
597  t.deepEqual(
598    retrieveFunding(),
599    null,
600    'should not care about null'
601  )
602  t.end()
603})
604
605test('retrieve funding info string shorthand', (t) => {
606  t.deepEqual(
607    retrieveFunding('http://example.com'),
608    {
609      url: 'http://example.com'
610    },
611    'should accept string shorthand'
612  )
613  t.end()
614})
615
616test('retrieve funding info from an array', (t) => {
617  t.deepEqual(
618    retrieveFunding([
619      'http://example.com',
620      {
621        url: 'http://two.example.com'
622      },
623      'http://three.example.com',
624      {
625        url: 'http://three.example.com',
626        type: 'dos'
627      },
628      {
629        url: 'http://three.example.com',
630        type: 'third copy!',
631        extra: 'extra metadata!'
632      }
633    ]),
634    [
635      {
636        url: 'http://example.com'
637      },
638      {
639        url: 'http://two.example.com'
640      },
641      {
642        url: 'http://three.example.com'
643      },
644      {
645        url: 'http://three.example.com',
646        type: 'dos'
647      },
648      {
649        url: 'http://three.example.com',
650        type: 'third copy!',
651        extra: 'extra metadata!'
652      }
653    ],
654    'should accept and normalize multiple funding sources'
655  )
656  t.end()
657})
658