1import { vol } from 'memfs';
2import path from 'path';
3
4import { BunPackageManager } from '../../node/BunPackageManager';
5import { NpmPackageManager } from '../../node/NpmPackageManager';
6import { PnpmPackageManager } from '../../node/PnpmPackageManager';
7import { YarnPackageManager } from '../../node/YarnPackageManager';
8import { createForProject, resolvePackageManager } from '../nodeManagers';
9import {
10  BUN_LOCK_FILE,
11  NPM_LOCK_FILE,
12  PNPM_LOCK_FILE,
13  PNPM_WORKSPACE_FILE,
14  YARN_LOCK_FILE,
15} from '../nodeWorkspaces';
16
17jest.mock('fs');
18
19describe(createForProject, () => {
20  const projectRoot = '/foo';
21
22  afterEach(() => vol.reset());
23
24  it(`creates npm package manager from options`, () => {
25    expect(createForProject(projectRoot, { npm: true })).toBeInstanceOf(NpmPackageManager);
26  });
27
28  it(`creates yarn package manager from options`, () => {
29    expect(createForProject(projectRoot, { yarn: true })).toBeInstanceOf(YarnPackageManager);
30  });
31
32  it(`creates pnpm package manager from options`, () => {
33    expect(createForProject(projectRoot, { pnpm: true })).toBeInstanceOf(PnpmPackageManager);
34  });
35
36  it(`creates bun package manager from options`, () => {
37    expect(createForProject(projectRoot, { bun: true })).toBeInstanceOf(BunPackageManager);
38  });
39
40  it(`defaults to npm package manager`, () => {
41    expect(createForProject(projectRoot)).toBeInstanceOf(NpmPackageManager);
42  });
43
44  it(`creates npm package manager from project`, () => {
45    vol.fromJSON(
46      {
47        'package.json': JSON.stringify({ name: 'project' }),
48        [NPM_LOCK_FILE]: '',
49      },
50      projectRoot
51    );
52
53    expect(createForProject(projectRoot)).toBeInstanceOf(NpmPackageManager);
54  });
55
56  it(`creates yarn package manager from project`, () => {
57    vol.fromJSON(
58      {
59        'package.json': JSON.stringify({ name: 'project' }),
60        [YARN_LOCK_FILE]: '',
61      },
62      projectRoot
63    );
64
65    expect(createForProject(projectRoot)).toBeInstanceOf(YarnPackageManager);
66  });
67
68  it(`creates pnpm package manager from project`, () => {
69    vol.fromJSON(
70      {
71        'package.json': JSON.stringify({ name: 'project' }),
72        [PNPM_LOCK_FILE]: '',
73      },
74      projectRoot
75    );
76
77    expect(createForProject(projectRoot)).toBeInstanceOf(PnpmPackageManager);
78  });
79
80  it(`creates bun package manager from project`, () => {
81    vol.fromJSON(
82      {
83        'package.json': JSON.stringify({ name: 'project' }),
84        [BUN_LOCK_FILE]: '',
85      },
86      projectRoot
87    );
88
89    expect(createForProject(projectRoot)).toBeInstanceOf(BunPackageManager);
90  });
91
92  it(`defaults to npm package manager`, () => {
93    vol.fromJSON(
94      {
95        'package.json': JSON.stringify({ name: 'project' }),
96      },
97      projectRoot
98    );
99
100    expect(createForProject(projectRoot)).toBeInstanceOf(NpmPackageManager);
101  });
102});
103
104describe(resolvePackageManager, () => {
105  const workspaceRoot = path.resolve('/monorepo/');
106  const projectRoot = path.resolve('/monorepo/packages/test/');
107
108  afterEach(() => vol.reset());
109
110  it(`resolves npm from monorepo workspace`, () => {
111    vol.fromJSON(
112      {
113        'packages/test/package.json': JSON.stringify({ name: 'project' }),
114        'package.json': JSON.stringify({
115          private: true,
116          name: 'monorepo',
117          workspaces: ['packages/*'],
118        }),
119        [NPM_LOCK_FILE]: '',
120      },
121      workspaceRoot
122    );
123
124    expect(resolvePackageManager(projectRoot)).toBe('npm');
125    expect(resolvePackageManager(projectRoot, 'npm')).toBe('npm');
126    expect(resolvePackageManager(projectRoot, 'pnpm')).toBeNull();
127    expect(resolvePackageManager(projectRoot, 'yarn')).toBeNull();
128    expect(resolvePackageManager(projectRoot, 'bun')).toBeNull();
129  });
130
131  it(`resolves pnpm from monorepo workspace`, () => {
132    vol.fromJSON(
133      {
134        'packages/test/package.json': JSON.stringify({ name: 'project' }),
135        'package.json': JSON.stringify({
136          private: true,
137          name: 'monorepo',
138        }),
139        [PNPM_LOCK_FILE]: '',
140        [PNPM_WORKSPACE_FILE]: 'packages:\n  - packages/*',
141      },
142      workspaceRoot
143    );
144
145    expect(resolvePackageManager(projectRoot)).toBe('pnpm');
146    expect(resolvePackageManager(projectRoot, 'pnpm')).toBe('pnpm');
147    expect(resolvePackageManager(projectRoot, 'npm')).toBeNull();
148    expect(resolvePackageManager(projectRoot, 'yarn')).toBeNull();
149    expect(resolvePackageManager(projectRoot, 'bun')).toBeNull();
150  });
151
152  it(`resolves yarn from monorepo workspace`, () => {
153    vol.fromJSON(
154      {
155        'packages/test/package.json': JSON.stringify({ name: 'project' }),
156        'package.json': JSON.stringify({
157          private: true,
158          name: 'monorepo',
159          workspaces: ['packages/*'],
160        }),
161        [YARN_LOCK_FILE]: '',
162      },
163      workspaceRoot
164    );
165
166    expect(resolvePackageManager(projectRoot)).toBe('yarn');
167    expect(resolvePackageManager(projectRoot, 'yarn')).toBe('yarn');
168    expect(resolvePackageManager(projectRoot, 'npm')).toBeNull();
169    expect(resolvePackageManager(projectRoot, 'pnpm')).toBeNull();
170    expect(resolvePackageManager(projectRoot, 'bun')).toBeNull();
171  });
172
173  it(`resolves bun from monorepo workspace`, () => {
174    vol.fromJSON(
175      {
176        'packages/test/package.json': JSON.stringify({ name: 'project' }),
177        'package.json': JSON.stringify({
178          private: true,
179          name: 'monorepo',
180          workspaces: ['packages/*'],
181        }),
182        [BUN_LOCK_FILE]: '',
183      },
184      workspaceRoot
185    );
186
187    expect(resolvePackageManager(projectRoot)).toBe('bun');
188    expect(resolvePackageManager(projectRoot, 'bun')).toBe('bun');
189    expect(resolvePackageManager(projectRoot, 'npm')).toBeNull();
190    expect(resolvePackageManager(projectRoot, 'pnpm')).toBeNull();
191    expect(resolvePackageManager(projectRoot, 'yarn')).toBeNull();
192  });
193});
194