1/* eslint-env jest */
2import JsonFile from '@expo/json-file';
3import execa from 'execa';
4import fs from 'fs-extra';
5import klawSync from 'klaw-sync';
6import path from 'path';
7
8import { execute, projectRoot, getLoadedModulesAsync, setupTestProjectAsync, bin } from './utils';
9
10const originalForceColor = process.env.FORCE_COLOR;
11const originalCI = process.env.CI;
12
13beforeAll(async () => {
14  await fs.mkdir(projectRoot, { recursive: true });
15  process.env.FORCE_COLOR = '0';
16  process.env.CI = '1';
17  process.env.EXPO_USE_PATH_ALIASES = '1';
18});
19
20afterAll(() => {
21  process.env.FORCE_COLOR = originalForceColor;
22  process.env.CI = originalCI;
23  delete process.env.EXPO_USE_PATH_ALIASES;
24});
25
26it('loads expected modules by default', async () => {
27  const modules = await getLoadedModulesAsync(
28    `require('../../build/src/export/embed').expoExportEmbed`
29  );
30  expect(modules).toStrictEqual([
31    '../node_modules/arg/index.js',
32    '../node_modules/chalk/node_modules/ansi-styles/index.js',
33    '../node_modules/chalk/source/index.js',
34    '../node_modules/chalk/source/util.js',
35    '../node_modules/has-flag/index.js',
36    '../node_modules/supports-color/index.js',
37    '@expo/cli/build/src/export/embed/index.js',
38    '@expo/cli/build/src/log.js',
39    '@expo/cli/build/src/utils/args.js',
40  ]);
41});
42
43it('runs `npx expo export:embed --help`', async () => {
44  const results = await execute('export:embed', '--help');
45  expect(results.stdout).toMatchInlineSnapshot(`
46    "
47      Info
48        (Internal) Export the JavaScript bundle during a native build script for embedding in a native binary
49
50      Usage
51        $ npx expo export:embed <dir>
52
53      Options
54        <dir>                                  Directory of the Expo project. Default: Current working directory
55        --entry-file <path>                    Path to the root JS file, either absolute or relative to JS root
56        --platform <string>                    Either "ios" or "android" (default: "ios")
57        --transformer <string>                 Specify a custom transformer to be used
58        --dev [boolean]                        If false, warnings are disabled and the bundle is minified (default: true)
59        --minify [boolean]                     Allows overriding whether bundle is minified. This defaults to false if dev is true, and true if dev is false. Disabling minification can be useful for speeding up production builds for testing purposes.
60        --bundle-output <string>               File name where to store the resulting bundle, ex. /tmp/groups.bundle
61        --bundle-encoding <string>             Encoding the bundle should be written in (https://nodejs.org/api/buffer.html#buffer_buffer). (default: "utf8")
62        --max-workers <number>                 Specifies the maximum number of workers the worker-pool will spawn for transforming files. This defaults to the number of the cores available on your machine.
63        --sourcemap-output <string>            File name where to store the sourcemap file for resulting bundle, ex. /tmp/groups.map
64        --sourcemap-sources-root <string>      Path to make sourcemap's sources entries relative to, ex. /root/dir
65        --sourcemap-use-absolute-path          Report SourceMapURL using its full path
66        --assets-dest <string>                 Directory name where to store assets referenced in the bundle
67        --asset-catalog-dest <string>          Directory to create an iOS Asset Catalog for images
68        --unstable-transform-profile <string>  Experimental, transform JS for a specific JS engine. Currently supported: hermes, hermes-canary, default
69        --reset-cache                          Removes cached files
70        -v, --verbose                          Enables debug logging
71        --config <string>                      Path to the CLI configuration file
72        --generate-static-view-configs         Generate static view configs for Fabric components. If there are no Fabric components in the bundle or Fabric is disabled, this is just no-op.
73        --read-global-cache                    Try to fetch transformed JS code from the global cache, if configured.
74        -h, --help                             Usage info
75    "
76  `);
77});
78
79it(
80  'runs `npx expo export:embed`',
81  async () => {
82    const projectRoot = await setupTestProjectAsync('ios-export-embed', 'with-assets');
83    fs.ensureDir(path.join(projectRoot, 'dist'));
84    await execa(
85      'node',
86      [
87        bin,
88        'export:embed',
89        '--entry-file',
90        './App.js',
91        '--bundle-output',
92        './dist/output.js',
93        '--assets-dest',
94        'dist',
95        '--platform',
96        'ios',
97      ],
98      {
99        cwd: projectRoot,
100      }
101    );
102
103    const outputDir = path.join(projectRoot, 'dist');
104    // List output files with sizes for snapshotting.
105    // This is to make sure that any changes to the output are intentional.
106    // Posix path formatting is used to make paths the same across OSes.
107    const files = klawSync(outputDir)
108      .map((entry) => {
109        if (entry.path.includes('node_modules') || !entry.stats.isFile()) {
110          return null;
111        }
112        return path.posix.relative(outputDir, entry.path);
113      })
114      .filter(Boolean);
115
116    // If this changes then everything else probably changed as well.
117    expect(files).toEqual([
118      'assets/assets/font.ttf',
119      'assets/assets/icon.png',
120      'assets/assets/icon@2x.png',
121      'output.js',
122    ]);
123  },
124  // Could take 45s depending on how fast npm installs
125  120 * 1000
126);
127