Last active
April 19, 2021 05:59
-
-
Save lukasholzer/46a1c620710b2db5ebe5c6686e0146d9 to your computer and use it in GitHub Desktop.
bazel jest testing rule
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/node_modules/jest-haste-map/build/crawlers/node.js b/node_modules/jest-haste-map/build/crawlers/node.js | |
index 1e7372c..ab36178 100644 | |
--- a/node_modules/jest-haste-map/build/crawlers/node.js | |
+++ b/node_modules/jest-haste-map/build/crawlers/node.js | |
@@ -168,10 +168,6 @@ function find(roots, extensions, ignore, callback) { | |
} | |
if (typeof entry !== 'string') { | |
- if (entry.isSymbolicLink()) { | |
- return; | |
- } | |
- | |
if (entry.isDirectory()) { | |
search(file); | |
return; | |
@@ -183,7 +179,7 @@ function find(roots, extensions, ignore, callback) { | |
activeCalls--; // This logic is unnecessary for node > v10.10, but leaving it in | |
// since we need it for backwards-compatibility still. | |
- if (!err && stat && !stat.isSymbolicLink()) { | |
+ if (!err && stat) { | |
if (stat.isDirectory()) { | |
search(file); | |
} else { | |
@@ -217,8 +213,13 @@ function find(roots, extensions, ignore, callback) { | |
function findNative(roots, extensions, ignore, callback) { | |
const args = Array.from(roots); | |
+ args.push('('); | |
args.push('-type', 'f'); | |
+ args.push('-o'); | |
+ args.push('-type', 'l'); | |
+ args.push(')'); | |
+ | |
if (extensions.length) { | |
args.push('('); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
/* eslint-disable no-console */ | |
/** Custom bazel reporter that tells how to update snapshots */ | |
class BazelReporter { | |
/** | |
* lifecycle hook that is triggered after the run is completed | |
* @param contexts | |
* @param results The Test results | |
*/ | |
onRunComplete(contexts, results) { | |
if (results.numFailedTests && results.snapshot.failure) { | |
console.log(`================================================================================ | |
Snapshot failed, you can update the snapshot by running | |
$ bazel run ${process.env['TEST_TARGET'].replace(/_bin$/, '')}.update | |
`); | |
} | |
} | |
} | |
module.exports = BazelReporter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
/* eslint-disable @typescript-eslint/no-var-requires,@typescript-eslint/typedef */ | |
const runfilesHelper = require(process.env['BAZEL_NODE_RUNFILES_HELPER']); | |
const { sep } = require('path'); | |
/** | |
* | |
* @param {string} request | |
* @param {*} options | |
*/ | |
module.exports = (request, options) => { | |
// resolve a request like `dynatrace/developer-portal/src/App` | |
// this originates through bazel if no module name is present | |
// it will prefixes the path with the bazel workspace and omit the file | |
// ending | |
if (request.startsWith(process.env['BAZEL_WORKSPACE'])) { | |
const resolved = resolveModule(request, ['.js', `${sep}index.js`, '']); | |
if (resolved?.length) { | |
return resolved; | |
} | |
} | |
// Call the defaultResolver, so we leverage its cache, error handling, etc. | |
return options.defaultResolver(request, options); | |
}; | |
/** | |
* Try to resolve a bazel module id (amd module name of a umd bundle) | |
* @param {string} id the module id that should be resolved | |
* @param {string[]} extensions a list of extensions to try to resolve | |
* @returns {string|undefined} The resolved module id | |
*/ | |
function resolveModule(id, extensions) { | |
if (extensions.length) { | |
try { | |
const [extension] = extensions.splice(0, 1); | |
return runfilesHelper.resolve(`${id}${extension}`); | |
} catch { | |
return resolveModule(id, extensions); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
/* eslint-disable @typescript-eslint/no-var-requires */ | |
const { relative, join, parse, sep } = require('path'); | |
/** @type {import('jest-snapshot').SnapshotResolver} */ | |
module.exports = { | |
// resolves from test to snapshot path | |
resolveSnapshotPath: (testPath, snapshotExtension) => { | |
const updatedPath = process.env.BUILD_WORKING_DIRECTORY | |
? join( | |
process.env.BUILD_WORKING_DIRECTORY, | |
relative(process.cwd(), testPath), | |
) | |
: testPath; | |
const { dir, base } = parse(updatedPath); | |
return `${join(dir, '__snapshots__', base)}${snapshotExtension}`; | |
}, | |
// resolves from snapshot to test path | |
resolveTestPath: (snapshotFilePath, snapshotExtension) => { | |
const clean = process.env.BUILD_WORKING_DIRECTORY | |
? snapshotFilePath | |
.replace(process.env.BUILD_WORKING_DIRECTORY, '') | |
.replace(/^[\\/]/, '') | |
: snapshotFilePath; | |
return clean | |
.replace(`__snapshots__${sep}`, '') | |
.slice(0, -snapshotExtension.length); | |
}, | |
// Example test path, used for preflight consistency check of the implementation above | |
testPathForConsistencyCheck: `some${sep}example.test.js`, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"Jest testing macro that can compile typescript files for testing as well" | |
load("@npm//@bazel/typescript:index.bzl", "ts_library") | |
load("@npm//jest-cli:index.bzl", "jest", _jest_test = "jest_test") | |
load("@bazel_skylib//rules:write_file.bzl", "write_file") | |
def jest_test( | |
srcs, | |
tsconfig, | |
config = None, | |
# jest does not understand only commonjs the default would be umd | |
devmode_module = "commonjs", | |
name = "test", | |
size = "medium", | |
flaky = False, | |
deps = [], | |
data = [], | |
**kwargs): | |
"""Jest testing rule that compiles the typescript sources and run jest tests | |
Args: | |
srcs: The sources passed | |
tsconfig: The typescript config for compiling typescript files | |
config: The jest configuration file | |
devmode_module: The jest compile devmode module | |
name: The name of the test rule | |
size: test size | |
flaky: Whether this test is flaky | |
deps: The dependencies that are needed for the test | |
data: Additional data for the test_run (like snapshots) | |
**kwargs: Keyword arguments | |
""" | |
# compile the spec files first | |
ts_library( | |
name = "%s_compile" % name, | |
srcs = srcs, | |
tsconfig = tsconfig, | |
devmode_module = devmode_module, | |
deps = [ | |
"@npm//tslib", | |
"@npm//@types/jest", | |
"@npm//@testing-library/jest-dom", | |
"@npm//jest-junit", | |
] + deps, | |
) | |
test_data = [ | |
"%s_compile" % name, | |
"@npm//@testing-library/jest-dom", | |
# c8 is used for bazel collecting coverage | |
"@npm//c8", | |
"@npm//jest-junit", | |
# prettier is used to format inline snapshots | |
"@npm//prettier", | |
"//:jest.preset.js", | |
"//tools/bazel_rules/jest:test-setup.js", | |
"//tools/bazel_rules/jest:jest-reporter.js", | |
"//tools/bazel_rules/jest:jest-resolver.js", | |
"//tools/bazel_rules/jest:jest-snapshot-resolver.js", | |
] + deps + data | |
test_args = [ | |
"--no-cache", | |
"--no-watchman", | |
"--ci", | |
"--colors", | |
] | |
# if we have a config file than add it | |
if config: | |
test_data.append(config) | |
test_args.append("--config $(rootpath %s)" % config) | |
else: | |
write_file( | |
name = "%s_config" % name, | |
out = "jest.config.js", | |
content = [""" | |
const { relative, join } = require('path'); | |
module.exports = { | |
preset: relative(__dirname, join(process.cwd(), 'jest.preset.js')) | |
}"""], | |
) | |
test_data.append("%s_config" % name) | |
test_args.append("--config %s/jest.config.js" % native.package_name()) | |
_jest_test( | |
name = name, | |
args = test_args, | |
data = test_data, | |
size = size, | |
flaky = flaky, | |
**kwargs | |
) | |
# This target is used to update the snapshot | |
# e.g bazel run //packages/react-intl:unit.update | |
jest( | |
name = "%s.update" % name, | |
data = test_data, | |
templated_args = test_args + ["-u"], | |
**kwargs | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
/* eslint-disable @typescript-eslint/no-var-requires */ | |
const { join, dirname } = require('path'); | |
/** @type {import('./tools/utils/src/runfiles-helper').RunfilesHelper} */ | |
const runfilesHelper = require(process.env['BAZEL_NODE_RUNFILES_HELPER']); | |
const [_, target] = process.env.BAZEL_TARGET.split(':'); | |
/** @type {import('@jest/types').Config.InitialOptions['reporters']} */ | |
const reporters = [ | |
'default', | |
join(process.cwd(), 'tools/bazel_rules/jest/jest-reporter.js'), | |
]; | |
// The xml output file is only set on `bazel test` and not on `bazel run` | |
if (process.env.XML_OUTPUT_FILE) { | |
reporters.push([ | |
runfilesHelper.resolve('npm/node_modules/jest-junit/index.js'), | |
{ | |
outputDirectory: dirname(process.env.XML_OUTPUT_FILE), | |
outputName: `${target}.xml`, | |
suiteName: process.env.BAZEL_TARGET, | |
// Not setting class and title templates leads to weird default formatting | |
classNameTemplate: `{classname} (${process.env.BAZEL_TARGET})`, | |
titleTemplate: '{title}', | |
ancestorSeparator: ' › ', | |
usePathForSuiteName: 'true', | |
}, | |
]); | |
} | |
/** @type {import('@jest/types').Config.InitialOptions} */ | |
module.exports = { | |
setupFilesAfterEnv: [ | |
join(process.cwd(), 'tools/bazel_rules/jest/test-setup.js'), | |
], | |
moduleNameMapper: { | |
'\\.(css)$': 'identity-obj-proxy', | |
}, | |
resolver: join(process.cwd(), 'tools/bazel_rules/jest/jest-resolver.js'), | |
snapshotResolver: join( | |
process.cwd(), | |
'tools/bazel_rules/jest/jest-snapshot-resolver.js', | |
), | |
testMatch: ['**/*.test.js'], | |
// make sure jest prints out console.logs | |
verbose: false, | |
watchman: false, | |
prettierPath: runfilesHelper.resolve('npm/node_modules/prettier/index.js'), | |
logHeapUsage: true, | |
collectCoverage: Boolean(process.env.IBAZEL), | |
collectCoverageFrom: process.env.IBAZEL | |
? undefined | |
: [ | |
'**/*.{js,jsx,ts,tsx}', | |
'!**/*.d.ts', | |
'!**/coverage/**/*', | |
'!**/jest.config.js', | |
'!**/*_loader.js', | |
'!**/*_require_patch.js', | |
'!**/fixtures/**/*', | |
], | |
reporters, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment