Skip to content

Commit 3fbf2c0

Browse files
Alex Eaglealexeagle
authored andcommitted
feat: introduce generated_file_test
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
1 parent 3824ccf commit 3fbf2c0

26 files changed

Lines changed: 197 additions & 174 deletions

File tree

.github/BUILD.bazel

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("@build_bazel_rules_nodejs//internal/golden_file_test:golden_file_test.bzl", "golden_file_test")
1+
load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test")
22
load("@rules_codeowners//tools:codeowners.bzl", "generate_codeowners")
33

44
generate_codeowners(
@@ -14,8 +14,8 @@ generate_codeowners(
1414
],
1515
)
1616

17-
golden_file_test(
17+
generated_file_test(
1818
name = "codeowners",
19-
actual = "gen_codeowners",
20-
golden = "CODEOWNERS",
19+
src = "CODEOWNERS",
20+
generated = "gen_codeowners",
2121
)

BUILD.bazel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ bzl_library(
3838
visibility = ["//visibility:public"],
3939
deps = [
4040
"//internal/common:bzl",
41+
"//internal/generated_file_test:bzl",
4142
"//internal/linker:bzl",
4243
"//internal/pkg_npm:bzl",
4344
"//internal/pkg_web:bzl",
@@ -78,7 +79,7 @@ pkg_npm(
7879
"//internal/common:package_contents",
7980
"//internal/copy_repository:package_contents",
8081
"//internal/coverage:package_contents",
81-
"//internal/golden_file_test:package_contents",
82+
"//internal/generated_file_test:package_contents",
8283
"//internal/js_library:package_contents",
8384
"//internal/linker:package_contents",
8485
"//internal/node:package_contents",

index.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ load("//internal/common:check_bazel_version.bzl", _check_bazel_version = "check_
2222
load("//internal/common:check_version.bzl", "check_version")
2323
load("//internal/common:copy_to_bin.bzl", _copy_to_bin = "copy_to_bin")
2424
load("//internal/common:params_file.bzl", _params_file = "params_file")
25+
load("//internal/generated_file_test:generated_file_test.bzl", _generated_file_test = "generated_file_test")
2526
load(
2627
"//internal/node:node.bzl",
2728
_nodejs_binary = "nodejs_binary",
@@ -42,6 +43,7 @@ npm_package_bin = _npm_bin
4243
pkg_web = _pkg_web
4344
copy_to_bin = _copy_to_bin
4445
params_file = _params_file
46+
generated_file_test = _generated_file_test
4547
# ANY RULES ADDED HERE SHOULD BE DOCUMENTED, see index.for_docs.bzl
4648

4749
# Allows us to avoid a transitive dependency on bazel_skylib from leaking to users

index.for_docs.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ This differs from :index.bzl because we don't have wrapping macros that hide the
1919
load("//internal/common:check_bazel_version.bzl", _check_bazel_version = "check_bazel_version")
2020
load("//internal/common:copy_to_bin.bzl", _copy_to_bin = "copy_to_bin")
2121
load("//internal/common:params_file.bzl", _params_file = "params_file")
22+
load("//internal/generated_file_test:generated_file_test.bzl", _generated_file_test = "generated_file_test")
2223
load("//internal/node:node.bzl", _nodejs_binary = "nodejs_binary", _nodejs_test = "nodejs_test")
2324
load("//internal/node:node_repositories.bzl", _node_repositories = "node_repositories_rule")
2425
load("//internal/node:npm_package_bin.bzl", _npm_bin = "npm_package_bin")
@@ -37,4 +38,5 @@ npm_install = _npm_install
3738
yarn_install = _yarn_install
3839
npm_package_bin = _npm_bin
3940
pkg_web = _pkg_web
41+
generated_file_test = _generated_file_test
4042
# ANY RULES ADDED HERE SHOULD BE DOCUMENTED, run yarn stardoc to verify
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2+
3+
package(default_visibility = ["//visibility:public"])
4+
5+
bzl_library(
6+
name = "bzl",
7+
srcs = glob(["*.bzl"]),
8+
visibility = ["//visibility:public"],
9+
)
10+
11+
exports_files(["bin.js"])
12+
13+
filegroup(
14+
name = "package_contents",
15+
srcs = glob(["*"]),
16+
)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const runfiles = require(process.env['BAZEL_NODE_RUNFILES_HELPER']);
4+
5+
function main(args) {
6+
const [mode, golden_no_debug, golden_debug, actual] = args;
7+
const actualPath = runfiles.resolveWorkspaceRelative(actual);
8+
const debugBuild = /\/bazel-out\/[^/\s]*-dbg\//.test(actualPath);
9+
const golden = debugBuild ? golden_debug : golden_no_debug;
10+
const actualContents = fs.readFileSync(actualPath, 'utf-8').replace(/\r\n/g, '\n');
11+
const goldenContents =
12+
fs.readFileSync(runfiles.resolveWorkspaceRelative(golden), 'utf-8').replace(/\r\n/g, '\n');
13+
14+
if (actualContents === goldenContents) {
15+
return 0;
16+
}
17+
if (mode === '--out') {
18+
// Write to golden file
19+
fs.writeFileSync(runfiles.resolveWorkspaceRelative(golden), actualContents);
20+
console.error(`Replaced ${path.join(process.cwd(), golden)}`);
21+
return 0;
22+
}
23+
if (mode === '--verify') {
24+
const unidiff = require('unidiff');
25+
// Generated does not match golden
26+
const diff = unidiff.diffLines(goldenContents, actualContents);
27+
let prettyDiff =
28+
unidiff.formatLines(diff, {aname: `[workspace]/${golden}`, bname: `[bazel-out]/${actual}`});
29+
if (prettyDiff.length > 5000) {
30+
prettyDiff = prettyDiff.substr(0, 5000) + '/n...elided...';
31+
}
32+
console.error(`Generated output doesn't match:
33+
34+
${prettyDiff}
35+
36+
If the bazel-out content is correct, you can update the workspace file by running:
37+
38+
bazel run ${debugBuild ? '--compilation_mode=dbg ' : ''}${
39+
process.env['TEST_TARGET'].replace(/_bin$/, '')}.update
40+
`);
41+
return 1;
42+
}
43+
throw new Error('unknown mode', mode);
44+
}
45+
46+
if (require.main === module) {
47+
process.exitCode = main(process.argv.slice(2));
48+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"Convenience for testing that an output matches a file"
2+
3+
load("@build_bazel_rules_nodejs//internal/node:node.bzl", "nodejs_binary", "nodejs_test")
4+
5+
def generated_file_test(name, generated, src, src_dbg = None, **kwargs):
6+
"""Tests that a file generated by Bazel has identical content to a file in the workspace.
7+
8+
This is useful for testing, where a "snapshot" or "golden" file is checked in,
9+
so that you can code review changes to the generated output.
10+
11+
Args:
12+
name: Name of the rule.
13+
generated: a Label of the output file generated by another rule
14+
src: Label of the source file in the workspace
15+
src_dbg: if the build uses `--compilation_mode dbg` then some rules will produce different output.
16+
In this case you can specify what the dbg version of the output should look like
17+
**kwargs: extra arguments passed to the underlying nodejs_test or nodejs_binary
18+
"""
19+
data = [src, generated, "@npm//unidiff"]
20+
21+
if src_dbg:
22+
data.append(src_dbg)
23+
else:
24+
src_dbg = src
25+
26+
loc = "$(rootpath %s)"
27+
nodejs_test(
28+
name = name,
29+
entry_point = "@build_bazel_rules_nodejs//internal/generated_file_test:bin.js",
30+
templated_args = ["--verify", loc % src, loc % src_dbg, loc % generated],
31+
data = data,
32+
**kwargs
33+
)
34+
35+
nodejs_binary(
36+
name = name + ".update",
37+
testonly = True,
38+
entry_point = "@build_bazel_rules_nodejs//internal/generated_file_test:bin.js",
39+
templated_args = ["--out", loc % src, loc % src_dbg, loc % generated],
40+
data = data,
41+
**kwargs
42+
)

internal/golden_file_test/BUILD.bazel

Lines changed: 0 additions & 8 deletions
This file was deleted.

internal/golden_file_test/bin.js

Lines changed: 0 additions & 44 deletions
This file was deleted.

internal/golden_file_test/golden_file_test.bzl

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)