• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const { resolve } = require('path')
2const t = require('tap')
3const { explainNode, printNode } = require('../../../lib/utils/explain-dep.js')
4const { cleanCwd } = require('../../fixtures/clean-snapshot')
5
6t.cleanSnapshot = (str) => cleanCwd(str)
7
8const getCases = (testdir) => {
9  const cases = {
10    prodDep: {
11      name: 'prod-dep',
12      version: '1.2.3',
13      location: 'node_modules/prod-dep',
14      dependents: [
15        {
16          type: 'prod',
17          name: 'prod-dep',
18          spec: '1.x',
19          from: {
20            location: '/path/to/project',
21          },
22        },
23      ],
24    },
25
26    deepDev: {
27      name: 'deep-dev',
28      version: '2.3.4',
29      location: 'node_modules/deep-dev',
30      dev: true,
31      dependents: [
32        {
33          type: 'prod',
34          name: 'deep-dev',
35          spec: '2.x',
36          from: {
37            name: 'metadev',
38            version: '3.4.5',
39            location: 'node_modules/dev/node_modules/metadev',
40            dependents: [
41              {
42                type: 'prod',
43                name: 'metadev',
44                spec: '3.x',
45                from: {
46                  name: 'topdev',
47                  version: '4.5.6',
48                  location: 'node_modules/topdev',
49                  dependents: [
50                    {
51                      type: 'dev',
52                      name: 'topdev',
53                      spec: '4.x',
54                      from: {
55                        location: '/path/to/project',
56                      },
57                    },
58                  ],
59                },
60              },
61            ],
62          },
63        },
64      ],
65    },
66
67    optional: {
68      name: 'optdep',
69      version: '1.0.0',
70      location: 'node_modules/optdep',
71      optional: true,
72      dependents: [
73        {
74          type: 'optional',
75          name: 'optdep',
76          spec: '1.0.0',
77          from: {
78            location: '/path/to/project',
79          },
80        },
81      ],
82    },
83
84    peer: {
85      name: 'peer',
86      version: '1.0.0',
87      location: 'node_modules/peer',
88      peer: true,
89      dependents: [
90        {
91          type: 'peer',
92          name: 'peer',
93          spec: '1.0.0',
94          from: {
95            location: '/path/to/project',
96          },
97        },
98      ],
99    },
100
101    bundled: {
102      name: 'bundle-of-joy',
103      version: '1.0.0',
104      location: 'node_modules/bundle-of-joy',
105      bundled: true,
106      dependents: [
107        {
108          type: 'prod',
109          name: 'prod-dep',
110          spec: '1.x',
111          bundled: true,
112          from: {
113            location: '/path/to/project',
114          },
115        },
116      ],
117    },
118
119    extraneous: {
120      name: 'extra-neos',
121      version: '1337.420.69-lol',
122      location: 'node_modules/extra-neos',
123      dependents: [],
124      extraneous: true,
125    },
126
127    overridden: {
128      name: 'overridden-root',
129      version: '1.0.0',
130      location: 'node_modules/overridden-root',
131      overridden: true,
132      dependents: [{
133        type: 'prod',
134        name: 'overridden-dep',
135        spec: '1.0.0',
136        rawSpec: '^2.0.0',
137        overridden: true,
138        from: {
139          location: '/path/to/project',
140        },
141      }],
142    },
143  }
144
145  cases.manyDeps = {
146    name: 'manydep',
147    version: '1.0.0',
148    dependents: [
149      {
150        type: 'prod',
151        name: 'manydep',
152        spec: '1.0.0',
153        from: cases.prodDep,
154      },
155      {
156        type: 'optional',
157        name: 'manydep',
158        spec: '1.x',
159        from: cases.optional,
160      },
161      {
162        type: 'prod',
163        name: 'manydep',
164        spec: '1.0.x',
165        from: cases.extraneous,
166      },
167      {
168        type: 'dev',
169        name: 'manydep',
170        spec: '*',
171        from: cases.deepDev,
172      },
173      {
174        type: 'peer',
175        name: 'manydep',
176        spec: '>1.0.0-beta <1.0.1',
177        from: cases.peer,
178      },
179      {
180        type: 'prod',
181        name: 'manydep',
182        spec: '>1.0.0-beta <1.0.1',
183        from: {
184          location: '/path/to/project',
185        },
186      },
187      {
188        type: 'prod',
189        name: 'manydep',
190        spec: '1',
191        from: {
192          name: 'a package with a pretty long name',
193          version: '1.2.3',
194          dependents: {
195            location: '/path/to/project',
196          },
197        },
198      },
199      {
200        type: 'prod',
201        name: 'manydep',
202        spec: '1',
203        from: {
204          name: 'another package with a pretty long name',
205          version: '1.2.3',
206          dependents: {
207            location: '/path/to/project',
208          },
209        },
210      },
211      {
212        type: 'prod',
213        name: 'manydep',
214        spec: '1',
215        from: {
216          name: 'yet another a package with a pretty long name',
217          version: '1.2.3',
218          dependents: {
219            location: '/path/to/project',
220          },
221        },
222      },
223    ],
224  }
225
226  cases.workspaces = {
227    name: 'a',
228    version: '1.0.0',
229    location: 'a',
230    isWorkspace: true,
231    dependents: [],
232    linksIn: [
233      {
234        name: 'a',
235        version: '1.0.0',
236        location: 'node_modules/a',
237        isWorkspace: true,
238        dependents: [
239          {
240            type: 'workspace',
241            name: 'a',
242            spec: `file:${resolve(testdir, 'ws-project', 'a')}`,
243            from: { location: resolve(testdir, 'ws-project') },
244          },
245        ],
246      },
247    ],
248  }
249
250  return cases
251}
252
253t.test('basic', async t => {
254  const { Chalk } = await import('chalk')
255  const color = new Chalk({ level: 3 })
256  const noColor = new Chalk({ level: 0 })
257
258  const testdir = t.testdir()
259  const cases = getCases(testdir)
260
261  for (const [name, expl] of Object.entries(getCases(testdir))) {
262    t.test(name, t => {
263      t.matchSnapshot(printNode(expl, color), 'print color')
264      t.matchSnapshot(printNode(expl, noColor), 'print nocolor')
265      t.matchSnapshot(explainNode(expl, Infinity, color), 'explain color deep')
266      t.matchSnapshot(explainNode(expl, 2, noColor), 'explain nocolor shallow')
267      t.end()
268    })
269  }
270
271  // make sure that we show the last one if it's the only one that would
272  // hit the ...
273  cases.manyDeps.dependents.pop()
274  t.matchSnapshot(explainNode(cases.manyDeps, 2, noColor), 'ellipses test one')
275  cases.manyDeps.dependents.pop()
276  t.matchSnapshot(explainNode(cases.manyDeps, 2, noColor), 'ellipses test two')
277})
278