From 5497bc017d1aa1cefbae9b44874872074e487d85 Mon Sep 17 00:00:00 2001 From: Oriol Puig Date: Fri, 3 Nov 2023 17:20:03 +0100 Subject: [PATCH] feat(packages/sui-jest): Allow test server and browser environments with jest --- packages/sui-jest/bin/config.js | 4 - packages/sui-jest/bin/sui-jest-browser.js | 29 +++ packages/sui-jest/bin/sui-jest-server.js | 29 +++ packages/sui-jest/bin/sui-jest.js | 17 +- .../src/config/jest.browser.config.js | 15 ++ packages/sui-jest/src/config/jest.config.js | 197 ++++++++++++++++++ .../sui-jest/src/config/jest.server.config.js | 15 ++ packages/sui-jest/src/runner.js | 38 ++++ .../{bin/utils.js => src/utils/index.js} | 0 9 files changed, 333 insertions(+), 11 deletions(-) delete mode 100644 packages/sui-jest/bin/config.js create mode 100755 packages/sui-jest/bin/sui-jest-browser.js create mode 100755 packages/sui-jest/bin/sui-jest-server.js create mode 100644 packages/sui-jest/src/config/jest.browser.config.js create mode 100644 packages/sui-jest/src/config/jest.config.js create mode 100644 packages/sui-jest/src/config/jest.server.config.js create mode 100644 packages/sui-jest/src/runner.js rename packages/sui-jest/{bin/utils.js => src/utils/index.js} (100%) diff --git a/packages/sui-jest/bin/config.js b/packages/sui-jest/bin/config.js deleted file mode 100644 index da7374f58..000000000 --- a/packages/sui-jest/bin/config.js +++ /dev/null @@ -1,4 +0,0 @@ -// TODO: add sui jest common config -const jestConfig = {} - -module.exports = jestConfig diff --git a/packages/sui-jest/bin/sui-jest-browser.js b/packages/sui-jest/bin/sui-jest-browser.js new file mode 100755 index 000000000..a1f953413 --- /dev/null +++ b/packages/sui-jest/bin/sui-jest-browser.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node +/* eslint-disable no-console */ +const program = require('commander') +const runner = require('../src/runner.js') + +// Setup default env vars +process.env.BABEL_ENV = 'test' +process.env.NODE_ENV = 'test' + +program + .option('-W, --watch', 'Run in watch mode') + .option('--ci', 'Run a Firefox headless for CI testing') + .option('-P, --pattern ', 'Path pattern to include', false) + .option('-c, --coverage', 'Run the coverage preprocessor', false) + .on('--help', () => { + console.log(' Description:') + console.log('') + console.log(' Run tests in browser with Jest') + console.log('') + console.log(' Examples:') + console.log('') + console.log(' $ sui-jest browser') + console.log('') + }) + .parse(process.argv) + +const {ci, coverage, pattern, watch} = program.opts() + +runner({ci, coverage, environment: 'jsdom', pattern, watch}) diff --git a/packages/sui-jest/bin/sui-jest-server.js b/packages/sui-jest/bin/sui-jest-server.js new file mode 100755 index 000000000..8456e62ac --- /dev/null +++ b/packages/sui-jest/bin/sui-jest-server.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node +/* eslint-disable no-console */ +const program = require('commander') +const runner = require('../src/runner.js') + +// Setup default env vars +process.env.BABEL_ENV = 'test' +process.env.NODE_ENV = 'test' + +program + .option('-W, --watch', 'Run in watch mode') + .option('--ci', 'Run a Firefox headless for CI testing') + .option('-P, --pattern ', 'Path pattern to include', false) + .option('-c, --coverage', 'Run the coverage preprocessor', false) + .on('--help', () => { + console.log(' Description:') + console.log('') + console.log(' Run tests in server with Jest') + console.log('') + console.log(' Examples:') + console.log('') + console.log(' $ sui-jest server') + console.log('') + }) + .parse(process.argv) + +const {ci, coverage, pattern, watch} = program.opts() + +runner({ci, coverage, environment: 'node', pattern, watch}) diff --git a/packages/sui-jest/bin/sui-jest.js b/packages/sui-jest/bin/sui-jest.js index b5a45fd54..e927a0e86 100755 --- a/packages/sui-jest/bin/sui-jest.js +++ b/packages/sui-jest/bin/sui-jest.js @@ -1,14 +1,17 @@ #!/usr/bin/env node -const {hasFile} = require('./utils.js') +const program = require('commander') +// Setup default env vars process.env.BABEL_ENV = 'test' process.env.NODE_ENV = 'test' -const args = process.argv.slice(2) +const pkg = require('../package.json') +const version = pkg.version -const config = - !args.includes('--config') && !hasFile('jest.config.js') - ? ['--config', JSON.stringify(require('./config.js'))] - : [] +program.version(version, ' --version') -require('jest').run([...config, ...args]) +program.command('browser', 'Run tests in the browser').alias('b') + +program.command('server', 'Run tests in node').alias('s') + +program.parse(process.argv) diff --git a/packages/sui-jest/src/config/jest.browser.config.js b/packages/sui-jest/src/config/jest.browser.config.js new file mode 100644 index 000000000..09162c940 --- /dev/null +++ b/packages/sui-jest/src/config/jest.browser.config.js @@ -0,0 +1,15 @@ +/** + * For a detailed explanation regarding each configuration property, visit: + * https://jestjs.io/docs/configuration + */ + +// TODO: add sui jest common config +const jestConfig = { + testMatch: [ + '**/__tests__/**/suite/**/?(*.)+(test).+(ts|tsx|js|jsx)', + '**/__tests__/**/*.(client|browser)+.*.(ts|tsx|js|jsx)', + '!**/__tests__/**/*server*' + ] +} + +module.exports = jestConfig diff --git a/packages/sui-jest/src/config/jest.config.js b/packages/sui-jest/src/config/jest.config.js new file mode 100644 index 000000000..b01996ea5 --- /dev/null +++ b/packages/sui-jest/src/config/jest.config.js @@ -0,0 +1,197 @@ +/** + * For a detailed explanation regarding each configuration property, visit: + * https://jestjs.io/docs/configuration + */ + +// TODO: Decide which is the default common config +const jestConfig = { + // All imported modules in your tests should be mocked automatically + // automock: false, + + // Stop running tests after `n` failures + // bail: 0, + + // The directory where Jest should store its cached dependency information + // cacheDirectory: "/private/var/folders/r5/sfgw__110f9dggbdy8v_l_kc0000gq/T/jest_dz", + + // Automatically clear mock calls, instances, contexts and results before every test + clearMocks: true, + + // Indicates whether the coverage information should be collected while executing the test + collectCoverage: false, + + // An array of glob patterns indicating a set of files for which coverage information should be collected + // collectCoverageFrom: undefined, + + // The directory where Jest should output its coverage files + coverageDirectory: 'coverage', + + // An array of regexp pattern strings used to skip coverage collection + // coveragePathIgnorePatterns: [ + // "/node_modules/" + // ], + + // Indicates which provider should be used to instrument code for coverage + coverageProvider: 'v8', + + // A list of reporter names that Jest uses when writing coverage reports + // coverageReporters: [ + // "json", + // "text", + // "lcov", + // "clover" + // ], + + // An object that configures minimum threshold enforcement for coverage results + // coverageThreshold: undefined, + + // A path to a custom dependency extractor + // dependencyExtractor: undefined, + + // Make calling deprecated APIs throw helpful error messages + // errorOnDeprecated: false, + + // The default configuration for fake timers + // fakeTimers: { + // "enableGlobally": false + // }, + + // Force coverage collection from ignored files using an array of glob patterns + // forceCoverageMatch: [], + + // A path to a module which exports an async function that is triggered once before all test suites + // globalSetup: undefined, + + // A path to a module which exports an async function that is triggered once after all test suites + // globalTeardown: undefined, + + // A set of global variables that need to be available in all test environments + // globals: {}, + + // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. + // maxWorkers: "50%", + + // An array of directory names to be searched recursively up from the requiring module's location + // moduleDirectories: [ + // "node_modules" + // ], + + // An array of file extensions your modules use + // moduleFileExtensions: [ + // "js", + // "mjs", + // "cjs", + // "jsx", + // "ts", + // "tsx", + // "json", + // "node" + // ], + + // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module + // moduleNameMapper: {}, + + // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader + // modulePathIgnorePatterns: [], + + // Activates notifications for test results + // notify: false, + + // An enum that specifies notification mode. Requires { notify: true } + // notifyMode: "failure-change", + + // A preset that is used as a base for Jest's configuration + // preset: undefined, + + // Run tests from one or more projects + // projects: undefined, + + // Use this configuration option to add custom reporters to Jest + // reporters: undefined, + + // Automatically reset mock state before every test + // resetMocks: false, + + // Reset the module registry before running each individual test + // resetModules: false, + + // A path to a custom resolver + // resolver: undefined, + + // Automatically restore mock state and implementation before every test + // restoreMocks: false, + + // The root directory that Jest should scan for tests and modules within + // rootDir: undefined, + + // A list of paths to directories that Jest should use to search for files in + // roots: [ + // "" + // ], + + // Allows you to use a custom runner instead of Jest's default test runner + // runner: "jest-runner", + + // The paths to modules that run some code to configure or set up the testing environment before each test + // setupFiles: [], + + // A list of paths to modules that run some code to configure or set up the testing framework before each test + // setupFilesAfterEnv: [], + + // The number of seconds after which a test is considered as slow and reported as such in the results. + // slowTestThreshold: 5, + + // A list of paths to snapshot serializer modules Jest should use for snapshot testing + // snapshotSerializers: [], + + // The test environment that will be used for testing + // testEnvironment: "jest-environment-node", + + // Options that will be passed to the testEnvironment + // testEnvironmentOptions: {}, + + // Adds a location field to test results + // testLocationInResults: false, + + // The glob patterns Jest uses to detect test files + // testMatch: ['!**/__tests__/**/*.[jt]s?(x)', '**/?(*.)+(spec|test).[tj]s?(x)'], + testMatch: ['**/__tests__/**/?(*.)+(spec|test).[tj]s?(x)'], + // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped + // testPathIgnorePatterns: [ + // "/node_modules/" + // ], + + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], + + // This option allows the use of a custom results processor + // testResultsProcessor: undefined, + + // This option allows use of a custom test runner + // testRunner: "jest-circus/runner", + + // A map from regular expressions to paths to transformers + transform: { + '^.+\\.(t|j)sx?$': '@swc/jest' + } + + // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation + // transformIgnorePatterns: [ + // "/node_modules/", + // "\\.pnp\\.[^\\/]+$" + // ], + + // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them + // unmockedModulePathPatterns: undefined, + + // Indicates whether each individual test should be reported during the run + // verbose: undefined, + + // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode + // watchPathIgnorePatterns: [], + + // Whether to use watchman for file crawling + // watchman: true, +} + +module.exports = jestConfig diff --git a/packages/sui-jest/src/config/jest.server.config.js b/packages/sui-jest/src/config/jest.server.config.js new file mode 100644 index 000000000..f98a0ba6d --- /dev/null +++ b/packages/sui-jest/src/config/jest.server.config.js @@ -0,0 +1,15 @@ +/** + * For a detailed explanation regarding each configuration property, visit: + * https://jestjs.io/docs/configuration + */ + +// TODO: add sui jest common config +const jestConfig = { + testMatch: [ + '**/__tests__/**/suite/**/?(*.)+(test).+(ts|tsx|js|jsx)', + '**/__tests__/**/*.(server)+.*.(ts|tsx|js|jsx)', + '!**/__tests__/**/*{client|browser}*' + ] +} + +module.exports = jestConfig diff --git a/packages/sui-jest/src/runner.js b/packages/sui-jest/src/runner.js new file mode 100644 index 000000000..b1992b2a2 --- /dev/null +++ b/packages/sui-jest/src/runner.js @@ -0,0 +1,38 @@ +const defaultConfig = require('./config/jest.config.js') +const defaultServerConfig = require('./config/jest.server.config.js') +const defaultBrowserConfig = require('./config/jest.browser.config.js') +const {hasFile, fromRoot} = require('./utils/index.js') + +const JEST_CONFIG_FILE_NAME = 'jest.config.js' + +module.exports = async ({ci, coverage, environment, watch, pattern}) => { + const args = [] + let config = defaultConfig + + if (ci) args.push('--ci') + if (coverage) args.push('--coverage') + if (environment) args.push(...['--env', environment]) + if (pattern) defaultConfig.testMatch = [pattern] + if (watch) args.push('--watch') + + // Add server support + if (environment === 'node') { + config = {...config, ...defaultServerConfig} + } + + // Add browser support + if (environment === 'jsdom') { + config = {...config, ...defaultBrowserConfig} + } + + // If project has a jest.config.js file, we merge it with the default one + if (hasFile(JEST_CONFIG_FILE_NAME)) { + const projectJestConfigPath = fromRoot(JEST_CONFIG_FILE_NAME) + const projectJestConfig = require(projectJestConfigPath) + config = {...config, ...projectJestConfig} + } + + args.push(...['--config', JSON.stringify(config)]) + + require('jest').run([...args]) +} diff --git a/packages/sui-jest/bin/utils.js b/packages/sui-jest/src/utils/index.js similarity index 100% rename from packages/sui-jest/bin/utils.js rename to packages/sui-jest/src/utils/index.js