Skip to content

Commit

Permalink
feat(examples): add Jest example (#1274)
Browse files Browse the repository at this point in the history
* feat(examples): add Jest example

This PR adds an example of how you might create a Jest rule

Unfortunately Jest does not handle symlinks very well so we have to add some patches so that it behaves correctly(See: jasongwartz/bazel_rules_nodejs_contrib#4 (comment))

Ultimately we should be able to move these patches into bazel_require_script which globally patches symlink operations for all node programs run by Bazel.
  • Loading branch information
purkhusid authored and alexeagle committed Oct 23, 2019
1 parent b916d61 commit f864462
Show file tree
Hide file tree
Showing 27 changed files with 5,366 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import %workspace%/common.bazelrc
# This lets us glob() up all the files inside the examples to make them inputs to tests
# To update these lines, just run `yarn bazel:update-deleted-packages`
# (Note, we cannot use common --deleted_packages because the bazel version command doesn't support it)
build --deleted_packages=examples/angular,examples/angular/e2e,examples/angular/src/app/hello-world,examples/angular/src/app/todos/reducers,examples/angular/src/app/todos,examples/angular/src/app/home,examples/angular/src/app,examples/angular/src/shared/material,examples/angular/src/assets,examples/angular/src/example,examples/angular/src,examples/angular/src/lib/shorten,examples/angular/tools,examples/angular_view_engine,examples/angular_view_engine/e2e,examples/angular_view_engine/src/app/hello-world,examples/angular_view_engine/src/app/todos/reducers,examples/angular_view_engine/src/app/todos,examples/angular_view_engine/src/app/home,examples/angular_view_engine/src/app,examples/angular_view_engine/src/shared/material,examples/angular_view_engine/src/assets,examples/angular_view_engine/src/example,examples/angular_view_engine/src,examples/angular_view_engine/src/lib/shorten,examples/angular_view_engine/tools,examples/app,examples/app/styles,examples/app/test,examples/closure,examples/kotlin,examples/nestjs,examples/nestjs/src,examples/parcel,examples/protocol_buffers,examples/user_managed_deps,examples/vendored_node_and_yarn,examples/vendored_node,examples/webapp,examples/web_testing,examples/worker,e2e/bazel_managed_deps,e2e/fine_grained_symlinks,e2e/jasmine,e2e/karma,e2e/karma_stack_trace,e2e/karma_stack_trace/test_folder,e2e/karma_typescript,e2e/node_loader_no_preserve_symlinks,e2e/node_loader_preserve_symlinks,e2e/packages,e2e/symlinked_node_modules_npm,e2e/symlinked_node_modules_yarn,e2e/ts_auto_deps,e2e/ts_devserver,e2e/ts_devserver/genrule,e2e/ts_devserver/subpackage,e2e/typescript,e2e/webapp,e2e/webpack
query --deleted_packages=examples/angular,examples/angular/e2e,examples/angular/src/app/hello-world,examples/angular/src/app/todos/reducers,examples/angular/src/app/todos,examples/angular/src/app/home,examples/angular/src/app,examples/angular/src/shared/material,examples/angular/src/assets,examples/angular/src/example,examples/angular/src,examples/angular/src/lib/shorten,examples/angular/tools,examples/angular_view_engine,examples/angular_view_engine/e2e,examples/angular_view_engine/src/app/hello-world,examples/angular_view_engine/src/app/todos/reducers,examples/angular_view_engine/src/app/todos,examples/angular_view_engine/src/app/home,examples/angular_view_engine/src/app,examples/angular_view_engine/src/shared/material,examples/angular_view_engine/src/assets,examples/angular_view_engine/src/example,examples/angular_view_engine/src,examples/angular_view_engine/src/lib/shorten,examples/angular_view_engine/tools,examples/app,examples/app/styles,examples/app/test,examples/closure,examples/kotlin,examples/nestjs,examples/nestjs/src,examples/parcel,examples/protocol_buffers,examples/user_managed_deps,examples/vendored_node_and_yarn,examples/vendored_node,examples/webapp,examples/web_testing,examples/worker,e2e/bazel_managed_deps,e2e/fine_grained_symlinks,e2e/jasmine,e2e/karma,e2e/karma_stack_trace,e2e/karma_stack_trace/test_folder,e2e/karma_typescript,e2e/node_loader_no_preserve_symlinks,e2e/node_loader_preserve_symlinks,e2e/packages,e2e/symlinked_node_modules_npm,e2e/symlinked_node_modules_yarn,e2e/ts_auto_deps,e2e/ts_devserver,e2e/ts_devserver/genrule,e2e/ts_devserver/subpackage,e2e/typescript,e2e/webapp,e2e/webpack
build --deleted_packages=examples/angular,examples/angular/e2e,examples/angular/src/app/hello-world,examples/angular/src/app/todos/reducers,examples/angular/src/app/todos,examples/angular/src/app/home,examples/angular/src/app,examples/angular/src/shared/material,examples/angular/src/assets,examples/angular/src/example,examples/angular/src,examples/angular/src/lib/shorten,examples/angular/tools,examples/angular_view_engine,examples/angular_view_engine/e2e,examples/angular_view_engine/src/app/hello-world,examples/angular_view_engine/src/app/todos/reducers,examples/angular_view_engine/src/app/todos,examples/angular_view_engine/src/app/home,examples/angular_view_engine/src/app,examples/angular_view_engine/src/shared/material,examples/angular_view_engine/src/assets,examples/angular_view_engine/src/example,examples/angular_view_engine/src,examples/angular_view_engine/src/lib/shorten,examples/angular_view_engine/tools,examples/app,examples/app/styles,examples/app/test,examples/closure,examples/jest,examples/jest/tools,examples/kotlin,examples/nestjs,examples/nestjs/src,examples/parcel,examples/protocol_buffers,examples/user_managed_deps,examples/vendored_node_and_yarn,examples/vendored_node,examples/webapp,examples/web_testing,examples/worker,e2e/bazel_managed_deps,e2e/fine_grained_symlinks,e2e/jasmine,e2e/node_loader_no_preserve_symlinks,e2e/node_loader_preserve_symlinks,e2e/packages,e2e/symlinked_node_modules_npm,e2e/symlinked_node_modules_yarn,e2e/ts_auto_deps,e2e/ts_devserver,e2e/ts_devserver/genrule,e2e/ts_devserver/subpackage,e2e/typescript,e2e/webapp,e2e/webpack
query --deleted_packages=examples/angular,examples/angular/e2e,examples/angular/src/app/hello-world,examples/angular/src/app/todos/reducers,examples/angular/src/app/todos,examples/angular/src/app/home,examples/angular/src/app,examples/angular/src/shared/material,examples/angular/src/assets,examples/angular/src/example,examples/angular/src,examples/angular/src/lib/shorten,examples/angular/tools,examples/angular_view_engine,examples/angular_view_engine/e2e,examples/angular_view_engine/src/app/hello-world,examples/angular_view_engine/src/app/todos/reducers,examples/angular_view_engine/src/app/todos,examples/angular_view_engine/src/app/home,examples/angular_view_engine/src/app,examples/angular_view_engine/src/shared/material,examples/angular_view_engine/src/assets,examples/angular_view_engine/src/example,examples/angular_view_engine/src,examples/angular_view_engine/src/lib/shorten,examples/angular_view_engine/tools,examples/app,examples/app/styles,examples/app/test,examples/closure,examples/jest,examples/jest/tools,examples/kotlin,examples/nestjs,examples/nestjs/src,examples/parcel,examples/protocol_buffers,examples/user_managed_deps,examples/vendored_node_and_yarn,examples/vendored_node,examples/webapp,examples/web_testing,examples/worker,e2e/bazel_managed_deps,e2e/fine_grained_symlinks,e2e/jasmine,e2e/node_loader_no_preserve_symlinks,e2e/node_loader_preserve_symlinks,e2e/packages,e2e/symlinked_node_modules_npm,e2e/symlinked_node_modules_yarn,e2e/ts_auto_deps,e2e/ts_devserver,e2e/ts_devserver/genrule,e2e/ts_devserver/subpackage,e2e/typescript,e2e/webapp,e2e/webpack

# Mock versioning command to test the --stamp behavior
build --workspace_status_command="echo BUILD_SCM_VERSION 1.2.3"
Expand Down
4 changes: 4 additions & 0 deletions examples/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ example_integration_test(
},
)

example_integration_test(
name = "examples_jest",
)

example_integration_test(
name = "examples_kotlin",
npm_packages = {
Expand Down
1 change: 1 addition & 0 deletions examples/jest/.bazelignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
1 change: 1 addition & 0 deletions examples/jest/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import %workspace%/../../common.bazelrc
31 changes: 31 additions & 0 deletions examples/jest/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
load(":jest.bzl", "jest_test")

jest_test(
name = "test",
srcs = [
"index.test.js",
"index2.test.js",
],
jest_config = ":jest.config.js",
tags = [
# Need to set the pwd to avoid jest needing a runfiles helper
# Windows users with permissions can use --enable_runfiles
# to make this test work
"no-bazelci-windows",
],
deps = [
"babel.config.js",
"extra.js",
"index.js",
"@npm//@babel/core",
"@npm//@babel/preset-env",
"@npm//@jest/transform",
"@npm//babel-jest",
],
)

# Just a dummy test so that we have a test target for //... on certain bazelci platforms with bazel_integration_test
sh_test(
name = "dummy_test",
srcs = ["dummy_test.sh"],
)
3 changes: 3 additions & 0 deletions examples/jest/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Jest example

This example shows how you might use the Jest testing framework
48 changes: 48 additions & 0 deletions examples/jest/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2019 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

workspace(
name = "examples_jest",
managed_directories = {"@npm": ["node_modules"]},
)

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "ad4be2c6f40f5af70c7edf294955f9d9a0222c8e2756109731b25f79ea2ccea0",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/0.38.3/rules_nodejs-0.38.3.tar.gz"],
)

load("@build_bazel_rules_nodejs//:index.bzl", "yarn_install")

yarn_install(
name = "npm",
data = [
"//:tools/patches/@jest+core+24.7.1.patch",
"//:tools/patches/@jest+transform+24.7.1.patch",
"//:tools/patches/jest-cli+24.7.1.patch",
"//:tools/patches/jest-config+24.7.1.patch",
"//:tools/patches/jest-haste-map+24.7.1.patch",
"//:tools/patches/jest-resolve+24.7.1.patch",
"//:tools/patches/jest-runtime+24.7.1.patch",
],
package_json = "//:package.json",
quiet = False,
yarn_lock = "//:yarn.lock",
)

load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")

install_bazel_dependencies()
12 changes: 12 additions & 0 deletions examples/jest/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};
2 changes: 2 additions & 0 deletions examples/jest/dummy_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
echo "Just a dummy test so that we have a test target for //... on certain bazelci platforms with bazel_integration_test"
exit 0
1 change: 1 addition & 0 deletions examples/jest/extra.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'test';
3 changes: 3 additions & 0 deletions examples/jest/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import extra from './extra';

export default extra;
5 changes: 5 additions & 0 deletions examples/jest/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import indexfile from './index.js';

test('it should work', () => {
expect(indexfile).toBe('test');
});
5 changes: 5 additions & 0 deletions examples/jest/index2.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import indexfile from './index.js';

test('it should work', () => {
expect(indexfile).toBe('test');
});
21 changes: 21 additions & 0 deletions examples/jest/jest.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"Shows how you might create a macro for the autogeneratd Jest rule"

load("@npm//jest-cli:index.bzl", _jest_test = "jest_test")

def jest_test(name, srcs, deps, jest_config, **kwargs):
"A macro around the autogenerated jest_test rule"
args = [
"--no-cache",
"--no-watchman",
"--ci",
]
args.extend(["--config", "$(location %s)" % jest_config])
for src in srcs:
args.extend(["--runTestsByPath", "$(location %s)" % src])

_jest_test(
name = name,
data = [jest_config] + srcs + deps,
args = args,
**kwargs
)
6 changes: 6 additions & 0 deletions examples/jest/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
testEnvironment: 'node',

transform: {'^.+\\.jsx?$': 'babel-jest'},
testMatch: ['**/*.test.js']
};
23 changes: 23 additions & 0 deletions examples/jest/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "jest_example",
"private": true,
"devDependencies": {
"@babel/cli": "^7.6.0",
"@babel/core": "^7.6.0",
"@babel/preset-env": "^7.6.0",
"@jest/transform": "24.7.1",
"@jest/core": "24.7.1",
"babel-jest": "24.7.1",
"jest-cli": "24.7.1",
"jest-config": "24.7.1",
"jest-haste-map": "24.7.1",
"jest-resolve": "24.7.1",
"jest-runtime": "24.7.1",
"patch-package": "6.1.2",
"babel-plugin-istanbul": "5.1.2"
},
"scripts": {
"test": "bazel test ...",
"postinstall": "patch-package --patch-dir=./tools/patches"
}
}
4 changes: 4 additions & 0 deletions examples/jest/tools/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Marker that this directory is a Bazel package

# These patch files from Globegitter:
# https://gist.github.com/Globegitter/690dd1b97828a3927b436bc11211f139
13 changes: 13 additions & 0 deletions examples/jest/tools/patches/@jest+core+24.7.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/node_modules/@jest/core/build/runJest.js b/node_modules/@jest/core/build/runJest.js
index 5afb90a..9a2c15b 100644
--- a/node_modules/@jest/core/build/runJest.js
+++ b/node_modules/@jest/core/build/runJest.js
@@ -244,7 +244,7 @@ const processResults = (runResults, options) => {

if (isJSON) {
if (outputFile) {
- const cwd = (0, _realpathNative().sync)(process.cwd());
+ const cwd = process.cwd();

const filePath = _path().default.resolve(cwd, outputFile);

13 changes: 13 additions & 0 deletions examples/jest/tools/patches/@jest+transform+24.7.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/node_modules/@jest/transform/build/ScriptTransformer.js b/node_modules/@jest/transform/build/ScriptTransformer.js
index 81397c7..7589de2 100644
--- a/node_modules/@jest/transform/build/ScriptTransformer.js
+++ b/node_modules/@jest/transform/build/ScriptTransformer.js
@@ -328,7 +328,7 @@ class ScriptTransformer {
}

transformSource(filepath, content, instrument) {
- const filename = this._getRealPath(filepath);
+ const filename = filepath;

const transform = this._getTransformer(filename);

31 changes: 31 additions & 0 deletions examples/jest/tools/patches/babel-plugin-istanbul+5.1.2.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
diff --git a/node_modules/babel-plugin-istanbul/lib/index.js b/node_modules/babel-plugin-istanbul/lib/index.js
index 259adb4..102a54f 100644
--- a/node_modules/babel-plugin-istanbul/lib/index.js
+++ b/node_modules/babel-plugin-istanbul/lib/index.js
@@ -27,7 +27,7 @@ function makeShouldSkip() {
var exclude;
return function shouldSkip(file, opts) {
if (!exclude || exclude.cwd !== opts.cwd) {
- var cwd = getRealpath(process.env.NYC_CWD || process.cwd());
+ var cwd = process.env.NYC_CWD || process.cwd();
var nycConfig = process.env.NYC_CONFIG ? JSON.parse(process.env.NYC_CONFIG) : {};
var config = {};

@@ -68,7 +68,7 @@ function makeVisitor(_ref) {
Program: {
enter: function enter(path) {
this.__dv__ = null;
- var realPath = getRealpath(this.file.opts.filename);
+ var realPath = this.file.opts.filename;

if (shouldSkip(realPath, this.opts)) {
return;
@@ -101,7 +101,7 @@ function makeVisitor(_ref) {
var result = this.__dv__.exit(path);

if (this.opts.onCover) {
- this.opts.onCover(getRealpath(this.file.opts.filename), result.fileCoverage);
+ this.opts.onCover(this.file.opts.filename, result.fileCoverage);
}
}
}
34 changes: 34 additions & 0 deletions examples/jest/tools/patches/istanbul-api+2.1.5.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
diff --git a/node_modules/istanbul-api/lib/file-matcher.js b/node_modules/istanbul-api/lib/file-matcher.js
index d926363..587d5d4 100644
--- a/node_modules/istanbul-api/lib/file-matcher.js
+++ b/node_modules/istanbul-api/lib/file-matcher.js
@@ -18,8 +18,8 @@ function filesFor(options, callback) {
let root = options.root;
let includes = options.includes;
let excludes = options.excludes;
- const realpath = options.realpath;
- const relative = options.relative;
+ const realpath = false;
+ const relative = true;

root = root || process.cwd();
includes = includes && Array.isArray(includes) ? includes : ['**/*.js'];
@@ -35,6 +35,7 @@ function filesFor(options, callback) {
return callback(err);
}
if (relative) {
+ console.log("istanbul", files)
return callback(err, files);
}

@@ -62,8 +63,8 @@ function matcherFor(options, callback) {
options = null;
}
options = options || {};
- options.relative = false; //force absolute paths
- options.realpath = true; //force real paths (to match Node.js module paths)
+ options.relative = true; //force absolute paths
+ options.realpath = false; //force real paths (to match Node.js module paths)

filesFor(options, (err, files) => {
const fileMap = Object.create(null);
26 changes: 26 additions & 0 deletions examples/jest/tools/patches/jest-cli+24.7.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
diff --git a/node_modules/jest-cli/build/cli/index.js b/node_modules/jest-cli/build/cli/index.js
index 831a476..46f7570 100644
--- a/node_modules/jest-cli/build/cli/index.js
+++ b/node_modules/jest-cli/build/cli/index.js
@@ -271,7 +271,7 @@ const getProjectListFromCLIArgs = (argv, project) => {

if (!projects.length && process.platform === 'win32') {
try {
- projects.push((0, _realpathNative().sync)(process.cwd()));
+ projects.push(process.cwd());
} catch (err) {
// do nothing, just catch error
// process.binding('fs').realpath can throw, e.g. on mapped drives
diff --git a/node_modules/jest-cli/build/init/index.js b/node_modules/jest-cli/build/init/index.js
index cae2fc2..7f38281 100644
--- a/node_modules/jest-cli/build/init/index.js
+++ b/node_modules/jest-cli/build/init/index.js
@@ -134,7 +134,7 @@ var _default =
/*#__PURE__*/
(function() {
var _ref = _asyncToGenerator(function*(
- rootDir = (0, _realpathNative().sync)(process.cwd())
+ rootDir = process.cwd()
) {
// prerequisite checks
const projectPackageJsonPath = _path().default.join(
35 changes: 35 additions & 0 deletions examples/jest/tools/patches/jest-config+24.7.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
diff --git a/node_modules/jest-config/build/getCacheDirectory.js b/node_modules/jest-config/build/getCacheDirectory.js
index 7e64ba6..6ea2cfd 100644
--- a/node_modules/jest-config/build/getCacheDirectory.js
+++ b/node_modules/jest-config/build/getCacheDirectory.js
@@ -50,7 +50,7 @@ const getCacheDirectory = () => {
getuid = _process.getuid;

const tmpdir = _path().default.join(
- (0, _realpathNative().sync)(_os().default.tmpdir()),
+ _os().default.tmpdir(),
'jest'
);

diff --git a/node_modules/jest-config/build/normalize.js b/node_modules/jest-config/build/normalize.js
index ce37c38..c34497a 100644
--- a/node_modules/jest-config/build/normalize.js
+++ b/node_modules/jest-config/build/normalize.js
@@ -428,7 +428,7 @@ const normalizeRootDir = options => {

try {
// try to resolve windows short paths, ignoring errors (permission errors, mostly)
- options.rootDir = (0, _realpathNative().sync)(options.rootDir);
+ options.rootDir = options.rootDir;
} catch (e) {
// ignored
}
@@ -1004,7 +1004,7 @@ function normalize(options, argv, configPath, projectIndex = Infinity) {

try {
// try to resolve windows short paths, ignoring errors (permission errors, mostly)
- newOptions.cwd = (0, _realpathNative().sync)(process.cwd());
+ newOptions.cwd = process.cwd();
} catch (e) {
// ignored
}
26 changes: 26 additions & 0 deletions examples/jest/tools/patches/jest-haste-map+24.7.1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
diff --git a/node_modules/jest-haste-map/build/crawlers/node.js b/node_modules/jest-haste-map/build/crawlers/node.js
index a179225..06106b9 100644
--- a/node_modules/jest-haste-map/build/crawlers/node.js
+++ b/node_modules/jest-haste-map/build/crawlers/node.js
@@ -165,7 +165,7 @@ function find(roots, extensions, ignore, callback) {
}

function findNative(roots, extensions, ignore, callback) {
- const args = Array.from(roots);
+ const args = Array.from(['-L'].concat(roots));
args.push('-type', 'f');

if (extensions.length) {
diff --git a/node_modules/jest-haste-map/build/index.js b/node_modules/jest-haste-map/build/index.js
index eb8d84f..97ec2c1 100644
--- a/node_modules/jest-haste-map/build/index.js
+++ b/node_modules/jest-haste-map/build/index.js
@@ -403,7 +403,7 @@ class HasteMap extends _events().default {
roots: Array.from(new Set(options.roots)),
skipPackageJson: !!options.skipPackageJson,
throwOnModuleCollision: !!options.throwOnModuleCollision,
- useWatchman: options.useWatchman == null ? true : options.useWatchman,
+ useWatchman: false,
watch: !!options.watch
};
this._console = options.console || global.console;
Loading

0 comments on commit f864462

Please sign in to comment.