Skip to content

Commit

Permalink
feat: introduce generated_file_test
Browse files Browse the repository at this point in the history
This is a new public API for checking in golden or snapshot files.
If you used the private golden_file_test previously, you need to rename actual to generated, golden to src, and golden_debug to src_dbg

Fixes #1893
  • Loading branch information
Alex Eagle authored and alexeagle committed Jun 8, 2020
1 parent 3824ccf commit 3fbf2c0
Show file tree
Hide file tree
Showing 26 changed files with 197 additions and 174 deletions.
8 changes: 4 additions & 4 deletions .github/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@build_bazel_rules_nodejs//internal/golden_file_test:golden_file_test.bzl", "golden_file_test")
load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test")
load("@rules_codeowners//tools:codeowners.bzl", "generate_codeowners")

generate_codeowners(
Expand All @@ -14,8 +14,8 @@ generate_codeowners(
],
)

golden_file_test(
generated_file_test(
name = "codeowners",
actual = "gen_codeowners",
golden = "CODEOWNERS",
src = "CODEOWNERS",
generated = "gen_codeowners",
)
3 changes: 2 additions & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ bzl_library(
visibility = ["//visibility:public"],
deps = [
"//internal/common:bzl",
"//internal/generated_file_test:bzl",
"//internal/linker:bzl",
"//internal/pkg_npm:bzl",
"//internal/pkg_web:bzl",
Expand Down Expand Up @@ -78,7 +79,7 @@ pkg_npm(
"//internal/common:package_contents",
"//internal/copy_repository:package_contents",
"//internal/coverage:package_contents",
"//internal/golden_file_test:package_contents",
"//internal/generated_file_test:package_contents",
"//internal/js_library:package_contents",
"//internal/linker:package_contents",
"//internal/node:package_contents",
Expand Down
2 changes: 2 additions & 0 deletions index.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ load("//internal/common:check_bazel_version.bzl", _check_bazel_version = "check_
load("//internal/common:check_version.bzl", "check_version")
load("//internal/common:copy_to_bin.bzl", _copy_to_bin = "copy_to_bin")
load("//internal/common:params_file.bzl", _params_file = "params_file")
load("//internal/generated_file_test:generated_file_test.bzl", _generated_file_test = "generated_file_test")
load(
"//internal/node:node.bzl",
_nodejs_binary = "nodejs_binary",
Expand All @@ -42,6 +43,7 @@ npm_package_bin = _npm_bin
pkg_web = _pkg_web
copy_to_bin = _copy_to_bin
params_file = _params_file
generated_file_test = _generated_file_test
# ANY RULES ADDED HERE SHOULD BE DOCUMENTED, see index.for_docs.bzl

# Allows us to avoid a transitive dependency on bazel_skylib from leaking to users
Expand Down
2 changes: 2 additions & 0 deletions index.for_docs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This differs from :index.bzl because we don't have wrapping macros that hide the
load("//internal/common:check_bazel_version.bzl", _check_bazel_version = "check_bazel_version")
load("//internal/common:copy_to_bin.bzl", _copy_to_bin = "copy_to_bin")
load("//internal/common:params_file.bzl", _params_file = "params_file")
load("//internal/generated_file_test:generated_file_test.bzl", _generated_file_test = "generated_file_test")
load("//internal/node:node.bzl", _nodejs_binary = "nodejs_binary", _nodejs_test = "nodejs_test")
load("//internal/node:node_repositories.bzl", _node_repositories = "node_repositories_rule")
load("//internal/node:npm_package_bin.bzl", _npm_bin = "npm_package_bin")
Expand All @@ -37,4 +38,5 @@ npm_install = _npm_install
yarn_install = _yarn_install
npm_package_bin = _npm_bin
pkg_web = _pkg_web
generated_file_test = _generated_file_test
# ANY RULES ADDED HERE SHOULD BE DOCUMENTED, run yarn stardoc to verify
16 changes: 16 additions & 0 deletions internal/generated_file_test/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")

package(default_visibility = ["//visibility:public"])

bzl_library(
name = "bzl",
srcs = glob(["*.bzl"]),
visibility = ["//visibility:public"],
)

exports_files(["bin.js"])

filegroup(
name = "package_contents",
srcs = glob(["*"]),
)
48 changes: 48 additions & 0 deletions internal/generated_file_test/bin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const fs = require('fs');
const path = require('path');
const runfiles = require(process.env['BAZEL_NODE_RUNFILES_HELPER']);

function main(args) {
const [mode, golden_no_debug, golden_debug, actual] = args;
const actualPath = runfiles.resolveWorkspaceRelative(actual);
const debugBuild = /\/bazel-out\/[^/\s]*-dbg\//.test(actualPath);
const golden = debugBuild ? golden_debug : golden_no_debug;
const actualContents = fs.readFileSync(actualPath, 'utf-8').replace(/\r\n/g, '\n');
const goldenContents =
fs.readFileSync(runfiles.resolveWorkspaceRelative(golden), 'utf-8').replace(/\r\n/g, '\n');

if (actualContents === goldenContents) {
return 0;
}
if (mode === '--out') {
// Write to golden file
fs.writeFileSync(runfiles.resolveWorkspaceRelative(golden), actualContents);
console.error(`Replaced ${path.join(process.cwd(), golden)}`);
return 0;
}
if (mode === '--verify') {
const unidiff = require('unidiff');
// Generated does not match golden
const diff = unidiff.diffLines(goldenContents, actualContents);
let prettyDiff =
unidiff.formatLines(diff, {aname: `[workspace]/${golden}`, bname: `[bazel-out]/${actual}`});
if (prettyDiff.length > 5000) {
prettyDiff = prettyDiff.substr(0, 5000) + '/n...elided...';
}
console.error(`Generated output doesn't match:
${prettyDiff}
If the bazel-out content is correct, you can update the workspace file by running:
bazel run ${debugBuild ? '--compilation_mode=dbg ' : ''}${
process.env['TEST_TARGET'].replace(/_bin$/, '')}.update
`);
return 1;
}
throw new Error('unknown mode', mode);
}

if (require.main === module) {
process.exitCode = main(process.argv.slice(2));
}
42 changes: 42 additions & 0 deletions internal/generated_file_test/generated_file_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"Convenience for testing that an output matches a file"

load("@build_bazel_rules_nodejs//internal/node:node.bzl", "nodejs_binary", "nodejs_test")

def generated_file_test(name, generated, src, src_dbg = None, **kwargs):
"""Tests that a file generated by Bazel has identical content to a file in the workspace.
This is useful for testing, where a "snapshot" or "golden" file is checked in,
so that you can code review changes to the generated output.
Args:
name: Name of the rule.
generated: a Label of the output file generated by another rule
src: Label of the source file in the workspace
src_dbg: if the build uses `--compilation_mode dbg` then some rules will produce different output.
In this case you can specify what the dbg version of the output should look like
**kwargs: extra arguments passed to the underlying nodejs_test or nodejs_binary
"""
data = [src, generated, "@npm//unidiff"]

if src_dbg:
data.append(src_dbg)
else:
src_dbg = src

loc = "$(rootpath %s)"
nodejs_test(
name = name,
entry_point = "@build_bazel_rules_nodejs//internal/generated_file_test:bin.js",
templated_args = ["--verify", loc % src, loc % src_dbg, loc % generated],
data = data,
**kwargs
)

nodejs_binary(
name = name + ".update",
testonly = True,
entry_point = "@build_bazel_rules_nodejs//internal/generated_file_test:bin.js",
templated_args = ["--out", loc % src, loc % src_dbg, loc % generated],
data = data,
**kwargs
)
8 changes: 0 additions & 8 deletions internal/golden_file_test/BUILD.bazel

This file was deleted.

44 changes: 0 additions & 44 deletions internal/golden_file_test/bin.js

This file was deleted.

34 changes: 0 additions & 34 deletions internal/golden_file_test/golden_file_test.bzl

This file was deleted.

2 changes: 1 addition & 1 deletion internal/linker/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ load("//packages/typescript:checked_in_ts_project.bzl", "checked_in_ts_project")
# because the implementation of ts_library depends on the linker so that would be a cycle.
# So we compile it to JS and check in the result as index.js.
# To update index.js run:
# bazel run //internal/linker:linker_lib_check_compiled.accept
# bazel run //internal/linker:linker_lib_check_compiled.update
checked_in_ts_project(
name = "linker_lib",
src = "link_node_modules.ts",
Expand Down
20 changes: 10 additions & 10 deletions internal/linker/test/integration/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@build_bazel_rules_nodejs//internal/golden_file_test:golden_file_test.bzl", "golden_file_test")
load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test")
load(":rule.bzl", "linked")

# Use the node binary supplied by the bazel toolchain
Expand Down Expand Up @@ -130,23 +130,23 @@ linked(
],
)

golden_file_test(
generated_file_test(
# default rule in this package
name = "integration",
actual = "actual",
golden = "golden.txt",
src = "golden.txt",
generated = "actual",
)

golden_file_test(
generated_file_test(
# default rule in this package
name = "integration_conflicts",
actual = "actual_with_conflicts",
golden = "golden.txt",
src = "golden.txt",
generated = "actual_with_conflicts",
)

golden_file_test(
generated_file_test(
# default rule in this package
name = "integration_conflicts_alt",
actual = "actual_with_conflicts_alt",
golden = "golden.txt",
src = "golden.txt",
generated = "actual_with_conflicts_alt",
)
10 changes: 5 additions & 5 deletions internal/node/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("//internal/golden_file_test:golden_file_test.bzl", "golden_file_test")
load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test")

package(default_visibility = ["//visibility:public"])

Expand Down Expand Up @@ -47,9 +47,9 @@ filegroup(
)

# To update node_patches.js run:
# bazel run //internal/node:checked_in_node_patches.accept
golden_file_test(
# bazel run //internal/node:checked_in_node_patches.update
generated_file_test(
name = "checked_in_node_patches",
actual = "//packages/node-patches:bundle",
golden = "node_patches.js",
src = "node_patches.js",
generated = "//packages/node-patches:bundle",
)
9 changes: 4 additions & 5 deletions internal/node/test/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary", "nodejs_test", "npm_package_bin")
load("@build_bazel_rules_nodejs//internal/golden_file_test:golden_file_test.bzl", "golden_file_test")
load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test", "nodejs_binary", "nodejs_test", "npm_package_bin")
load("@npm//typescript:index.bzl", "tsc")
load("//internal/js_library:js_library.bzl", "js_library")
load("//internal/node:node_repositories.bzl", "BUILT_IN_NODE_PLATFORMS")
Expand Down Expand Up @@ -358,10 +357,10 @@ npm_package_bin(
tool = ":test_runfiles_helper",
)

golden_file_test(
generated_file_test(
name = "test_runfiles_helper_test",
actual = ":test_runfiles_helper.out",
golden = "test_runfiles_helper.golden",
src = "test_runfiles_helper.golden",
generated = ":test_runfiles_helper.out",
)

nodejs_test(
Expand Down
2 changes: 1 addition & 1 deletion internal/npm_install/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jasmine_node_test(
)

nodejs_binary(
name = "test.accept",
name = "test.update",
data = [
":check.js",
":goldens",
Expand Down
2 changes: 1 addition & 1 deletion internal/npm_install/test/check.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ ${prettyDiff}
Update the golden file:
bazel run ${process.env['TEST_TARGET']}.accept`);
bazel run ${process.env['TEST_TARGET']}.update`);
}
}
}
Expand Down
Loading

0 comments on commit 3fbf2c0

Please sign in to comment.