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