18d307f52SEvan Bacon/* eslint-env jest */
2e1bb5bdfSKudo Chienimport { ExecaError } from 'execa';
38d307f52SEvan Baconimport fs from 'fs/promises';
48d307f52SEvan Baconimport path from 'path';
58d307f52SEvan Bacon
68d307f52SEvan Baconimport { execute, projectRoot, getRoot, getLoadedModulesAsync } from './utils';
78d307f52SEvan Bacon
88d307f52SEvan Baconconst originalForceColor = process.env.FORCE_COLOR;
9*aaa8033fSEvan Bacon
108d307f52SEvan BaconbeforeAll(async () => {
118d307f52SEvan Bacon  await fs.mkdir(projectRoot, { recursive: true });
128d307f52SEvan Bacon  process.env.FORCE_COLOR = '0';
138d307f52SEvan Bacon});
14*aaa8033fSEvan Bacon
158d307f52SEvan BaconafterAll(() => {
168d307f52SEvan Bacon  process.env.FORCE_COLOR = originalForceColor;
178d307f52SEvan Bacon});
188d307f52SEvan Bacon
198d307f52SEvan Baconit('loads expected modules by default', async () => {
208d307f52SEvan Bacon  const modules = await getLoadedModulesAsync(`require('../../build/src/config').expoConfig`);
218d307f52SEvan Bacon  expect(modules).toStrictEqual([
224067174dSWill Schurman    '../node_modules/ansi-styles/index.js',
238d307f52SEvan Bacon    '../node_modules/arg/index.js',
248d307f52SEvan Bacon    '../node_modules/chalk/source/index.js',
258d307f52SEvan Bacon    '../node_modules/chalk/source/util.js',
268d307f52SEvan Bacon    '../node_modules/has-flag/index.js',
278d307f52SEvan Bacon    '../node_modules/supports-color/index.js',
288d307f52SEvan Bacon    '@expo/cli/build/src/config/index.js',
298d307f52SEvan Bacon    '@expo/cli/build/src/log.js',
308d307f52SEvan Bacon    '@expo/cli/build/src/utils/args.js',
318d307f52SEvan Bacon  ]);
328d307f52SEvan Bacon});
338d307f52SEvan Bacon
348d307f52SEvan Baconit('runs `npx expo config --help`', async () => {
358d307f52SEvan Bacon  const results = await execute('config', '--help');
368d307f52SEvan Bacon  expect(results.stdout).toMatchInlineSnapshot(`
378d307f52SEvan Bacon    "
3883d464dcSEvan Bacon      Info
398d307f52SEvan Bacon        Show the project config
408d307f52SEvan Bacon
418d307f52SEvan Bacon      Usage
428d307f52SEvan Bacon        $ npx expo config <dir>
438d307f52SEvan Bacon
448d307f52SEvan Bacon      Options
4583d464dcSEvan Bacon        <dir>                                    Directory of the Expo project. Default: Current working directory
468d307f52SEvan Bacon        --full                                   Include all project config data
478d307f52SEvan Bacon        --json                                   Output in JSON format
488d307f52SEvan Bacon        -t, --type <public|prebuild|introspect>  Type of config to show
4983d464dcSEvan Bacon        -h, --help                               Usage info
508d307f52SEvan Bacon    "
518d307f52SEvan Bacon  `);
528d307f52SEvan Bacon});
538d307f52SEvan Bacon
540a6ddb20SEvan Baconit(
550a6ddb20SEvan Bacon  'runs `npx expo config --json`',
560a6ddb20SEvan Bacon  async () => {
578d307f52SEvan Bacon    const projectName = 'basic-config';
588d307f52SEvan Bacon    const projectRoot = getRoot(projectName);
598d307f52SEvan Bacon    // Create the project root aot
608d307f52SEvan Bacon    await fs.mkdir(projectRoot, { recursive: true });
618d307f52SEvan Bacon    // Create a fake package.json -- this is a terminal file that cannot be overwritten.
628d307f52SEvan Bacon    await fs.writeFile(path.join(projectRoot, 'package.json'), '{ "version": "1.0.0" }');
638d307f52SEvan Bacon    await fs.writeFile(path.join(projectRoot, 'app.json'), '{ "expo": { "name": "foobar" } }');
64*aaa8033fSEvan Bacon    // Add an environment variable file to test that it's not included in the config.
65*aaa8033fSEvan Bacon    await fs.writeFile(path.join(projectRoot, '.env'), 'FOOBAR=1');
668d307f52SEvan Bacon
678d307f52SEvan Bacon    const results = await execute('config', projectName, '--json');
688d307f52SEvan Bacon    // @ts-ignore
698d307f52SEvan Bacon    const exp = JSON.parse(results.stdout);
708d307f52SEvan Bacon
718d307f52SEvan Bacon    expect(exp.name).toEqual('foobar');
728d307f52SEvan Bacon    expect(exp.slug).toEqual('foobar');
738d307f52SEvan Bacon    expect(exp.platforms).toStrictEqual([]);
748d307f52SEvan Bacon    expect(exp.version).toBe('1.0.0');
758d307f52SEvan Bacon    expect(exp._internal.dynamicConfigPath).toBe(null);
768d307f52SEvan Bacon    expect(exp._internal.staticConfigPath).toMatch(/\/basic-config\/app\.json$/);
770a6ddb20SEvan Bacon  }, // Could take 45s depending on how fast npm installs
780a6ddb20SEvan Bacon  120 * 1000
790a6ddb20SEvan Bacon);
808d307f52SEvan Bacon
818d307f52SEvan Baconit('throws on invalid project root', async () => {
828d307f52SEvan Bacon  expect.assertions(1);
838d307f52SEvan Bacon  try {
848d307f52SEvan Bacon    await execute('config', 'very---invalid', '--json');
858d307f52SEvan Bacon  } catch (e) {
86e1bb5bdfSKudo Chien    const error = e as ExecaError;
87e1bb5bdfSKudo Chien    expect(error.stderr).toMatch(/Invalid project root: \//);
888d307f52SEvan Bacon  }
898d307f52SEvan Bacon});
90