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