๐Ÿ“ฆ facebook / react-native

๐Ÿ“„ run-ci-javascript-tests.js ยท 115 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @format
 * @flow strict-local
 */

'use strict';

/**
 * This script runs JavaScript tests.
 * Available arguments:
 * --maxWorkers [num] - how many workers, default 1
 * --jestBinary [path] - path to jest binary, defaults to local node modules
 * --yarnBinary [path] - path to yarn binary, defaults to yarn
 * --flowBinary [path] - path to flow binary, defaults to running `yarn run flow-check`
 */

const {execSync} = require('child_process');
const argv /*:$ReadOnly<{
  maxWorkers?: number,
  jestBinary?: string,
  flowBinary?: string,
  yarnBinary?: string,
}> */ =
  // $FlowFixMe[incompatible-type]
  // $FlowFixMe[incompatible-exact]
  // $FlowFixMe[incompatible-indexer]
  require('yargs').argv;

const numberOfMaxWorkers = argv.maxWorkers ?? 1;

const JEST_BINARY = argv.jestBinary ?? './node_modules/.bin/jest';
const FLOW_BINARY = argv.flowBinary;
const YARN_BINARY = argv.yarnBinary ?? 'yarn';

class ExecError extends Error {
  constructor(cause /*: Error */) {
    super(cause.message, {cause});
    this.name = 'ExecError';
  }
}

function describe(message /*: string */) {
  console.log(`\n\n>>>>> ${message}\n\n\n`);
}

try {
  console.log('Executing JavaScript tests');

  describe('Test: feature flags codegen');
  execAndLog(`${YARN_BINARY} run featureflags --verify-unchanged`);
  describe('Test: eslint');
  execAndLog(`${YARN_BINARY} run lint`);
  describe('Test: No JS build artifacts');
  execAndLog(`${YARN_BINARY} run build --validate`);

  describe('Test: Validate JS API snapshot');
  execAndLog(`${YARN_BINARY} run build-types --validate`);

  describe('Test: Flow check');
  const flowCommand =
    FLOW_BINARY == null
      ? `${YARN_BINARY} run flow-check`
      : `${FLOW_BINARY} full-check`;
  execAndLog(flowCommand);

  /*
   * Build @react-native/codegen and  @react-native/codegen-typescript-test
   *
   * The typescript-test project use TypeScript to write test cases
   * In order to make these tests discoverable to jest
   * *-test.ts must be compiled to *-test.js before running jest
   */

  describe('Test: Build @react-native/codegen');
  execAndLog(`${YARN_BINARY} --cwd ./packages/react-native-codegen run build`);
  describe('Test: Build @react-native/codegen-typescript-test');
  execAndLog(
    `${YARN_BINARY} --cwd ./private/react-native-codegen-typescript-test run build`,
  );

  describe('Test: Jest');
  execAndLog(
    `${JEST_BINARY} --maxWorkers=${numberOfMaxWorkers} --ci --reporters="default" --reporters="jest-junit"`,
  );

  describe('Test: TypeScript tests');
  execAndLog(`${YARN_BINARY} run test-typescript`);
} catch (e) {
  if (e instanceof ExecError) {
    console.error(e.message);
    process.exitCode = 1;
  } else {
    throw e;
  }
} finally {
  console.log('Finished.');
}

function execAndLog(command /*: string */) {
  console.log(`Executing: ${command}`);
  try {
    execSync(command, {
      stdio: ['ignore', 'inherit', 'inherit'],
      encoding: 'utf8',
    });
  } catch (e) {
    throw new ExecError(e);
  }
}