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(`creates bun package manager from project using "yarn.lock" and "bun.lockb"`, () => { 93 vol.fromJSON( 94 { 95 'package.json': JSON.stringify({ name: 'project' }), 96 [BUN_LOCK_FILE]: '', 97 [YARN_LOCK_FILE]: '', 98 }, 99 projectRoot 100 ); 101 102 expect(createForProject(projectRoot)).toBeInstanceOf(BunPackageManager); 103 }); 104 105 it(`defaults to npm package manager`, () => { 106 vol.fromJSON( 107 { 108 'package.json': JSON.stringify({ name: 'project' }), 109 }, 110 projectRoot 111 ); 112 113 expect(createForProject(projectRoot)).toBeInstanceOf(NpmPackageManager); 114 }); 115}); 116 117describe(resolvePackageManager, () => { 118 const workspaceRoot = path.resolve('/monorepo/'); 119 const projectRoot = path.resolve('/monorepo/packages/test/'); 120 121 afterEach(() => vol.reset()); 122 123 it(`resolves npm from monorepo workspace`, () => { 124 vol.fromJSON( 125 { 126 'packages/test/package.json': JSON.stringify({ name: 'project' }), 127 'package.json': JSON.stringify({ 128 private: true, 129 name: 'monorepo', 130 workspaces: ['packages/*'], 131 }), 132 [NPM_LOCK_FILE]: '', 133 }, 134 workspaceRoot 135 ); 136 137 expect(resolvePackageManager(projectRoot)).toBe('npm'); 138 expect(resolvePackageManager(projectRoot, 'npm')).toBe('npm'); 139 expect(resolvePackageManager(projectRoot, 'pnpm')).toBeNull(); 140 expect(resolvePackageManager(projectRoot, 'yarn')).toBeNull(); 141 expect(resolvePackageManager(projectRoot, 'bun')).toBeNull(); 142 }); 143 144 it(`resolves pnpm from monorepo workspace`, () => { 145 vol.fromJSON( 146 { 147 'packages/test/package.json': JSON.stringify({ name: 'project' }), 148 'package.json': JSON.stringify({ 149 private: true, 150 name: 'monorepo', 151 }), 152 [PNPM_LOCK_FILE]: '', 153 [PNPM_WORKSPACE_FILE]: 'packages:\n - packages/*', 154 }, 155 workspaceRoot 156 ); 157 158 expect(resolvePackageManager(projectRoot)).toBe('pnpm'); 159 expect(resolvePackageManager(projectRoot, 'pnpm')).toBe('pnpm'); 160 expect(resolvePackageManager(projectRoot, 'npm')).toBeNull(); 161 expect(resolvePackageManager(projectRoot, 'yarn')).toBeNull(); 162 expect(resolvePackageManager(projectRoot, 'bun')).toBeNull(); 163 }); 164 165 it(`resolves yarn from monorepo workspace`, () => { 166 vol.fromJSON( 167 { 168 'packages/test/package.json': JSON.stringify({ name: 'project' }), 169 'package.json': JSON.stringify({ 170 private: true, 171 name: 'monorepo', 172 workspaces: ['packages/*'], 173 }), 174 [YARN_LOCK_FILE]: '', 175 }, 176 workspaceRoot 177 ); 178 179 expect(resolvePackageManager(projectRoot)).toBe('yarn'); 180 expect(resolvePackageManager(projectRoot, 'yarn')).toBe('yarn'); 181 expect(resolvePackageManager(projectRoot, 'npm')).toBeNull(); 182 expect(resolvePackageManager(projectRoot, 'pnpm')).toBeNull(); 183 expect(resolvePackageManager(projectRoot, 'bun')).toBeNull(); 184 }); 185 186 it(`resolves bun from monorepo workspace`, () => { 187 vol.fromJSON( 188 { 189 'packages/test/package.json': JSON.stringify({ name: 'project' }), 190 'package.json': JSON.stringify({ 191 private: true, 192 name: 'monorepo', 193 workspaces: ['packages/*'], 194 }), 195 [BUN_LOCK_FILE]: '', 196 }, 197 workspaceRoot 198 ); 199 200 expect(resolvePackageManager(projectRoot)).toBe('bun'); 201 expect(resolvePackageManager(projectRoot, 'bun')).toBe('bun'); 202 expect(resolvePackageManager(projectRoot, 'npm')).toBeNull(); 203 expect(resolvePackageManager(projectRoot, 'pnpm')).toBeNull(); 204 expect(resolvePackageManager(projectRoot, 'yarn')).toBeNull(); 205 }); 206 207 it(`resolves bun from monorepo workspace using "yarn.lock" and "bun.lockb"`, () => { 208 vol.fromJSON( 209 { 210 'packages/test/package.json': JSON.stringify({ name: 'project' }), 211 'package.json': JSON.stringify({ 212 private: true, 213 name: 'monorepo', 214 workspaces: ['packages/*'], 215 }), 216 [BUN_LOCK_FILE]: '', 217 [YARN_LOCK_FILE]: '', 218 }, 219 workspaceRoot 220 ); 221 222 expect(resolvePackageManager(projectRoot)).toBe('bun'); 223 expect(resolvePackageManager(projectRoot, 'bun')).toBe('bun'); 224 expect(resolvePackageManager(projectRoot, 'npm')).toBeNull(); 225 expect(resolvePackageManager(projectRoot, 'pnpm')).toBeNull(); 226 227 // Due to the `yarn.lock` file being present when running `bun install --yarn`, 228 // yarn can be returned as package manager when prefering `yarn`. 229 expect(resolvePackageManager(projectRoot, 'yarn')).toBe('yarn'); 230 }); 231}); 232