From b0b2648c0ed649dc2175eaafc90190923e862691 Mon Sep 17 00:00:00 2001 From: Alex Eagle Date: Sun, 4 Aug 2019 13:12:07 -0700 Subject: [PATCH] feat(jasmine): introduce config_file attribute --- packages/jasmine/src/jasmine_node_test.bzl | 25 ++++++++++++++--- packages/jasmine/src/jasmine_runner.js | 30 +++++++++++++-------- packages/jasmine/test/BUILD.bazel | 13 +++++++++ packages/jasmine/test/test_config_file.js | 6 +++++ packages/jasmine/test/test_config_file.json | 6 +++++ 5 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 packages/jasmine/test/test_config_file.js create mode 100644 packages/jasmine/test/test_config_file.json diff --git a/packages/jasmine/src/jasmine_node_test.bzl b/packages/jasmine/src/jasmine_node_test.bzl index e6802be6bb..58be096696 100644 --- a/packages/jasmine/src/jasmine_node_test.bzl +++ b/packages/jasmine/src/jasmine_node_test.bzl @@ -28,6 +28,7 @@ def jasmine_node_test( deps = [], expected_exit_code = 0, tags = [], + config_file = None, coverage = False, jasmine = "@npm//@bazel/jasmine", jasmine_entry_point = "@npm//:node_modules/@bazel/jasmine/jasmine_runner.js", @@ -43,6 +44,15 @@ def jasmine_node_test( deps: Other targets which produce JavaScript, such as ts_library expected_exit_code: The expected exit code for the test. tags: Bazel tags applied to test + config_file: (experimental) label of a file containing Jasmine JSON config. + + Note that not all configuration options are honored, and + we expect some strange feature interations. + For example, if you list spec_files, they will be tested + but not instrumented for code coverage. + + See https://jasmine.github.io/setup/nodejs.html#configuration + coverage: Enables code coverage collection and reporting. jasmine: A label providing the `@bazel/jasmine` npm dependency. jasmine_entry_point: A label providing the `@bazel/jasmine` entry point. @@ -61,12 +71,21 @@ def jasmine_node_test( all_data += [Label("@bazel_tools//tools/bash/runfiles")] # If the target specified templated_args, pass it through. - templated_args = kwargs.pop("templated_args", []) + ["$(location :%s_devmode_srcs.MF)" % name] + templated_args = kwargs.pop("templated_args", []) + templated_args.append("$(location :%s_devmode_srcs.MF)" % name) if coverage: - templated_args = templated_args + ["--coverage"] + templated_args.append("--coverage") + else: + templated_args.append("--nocoverage") + + if config_file: + # Calculate a label relative to the user's BUILD file + pkg = Label("%s//%s:__pkg__" % (native.repository_name(), native.package_name())) + all_data.append(pkg.relative(config_file)) + templated_args.append("$(location %s)" % config_file) else: - templated_args = templated_args + ["--nocoverage"] + templated_args.append("--noconfig") nodejs_test( name = name, diff --git a/packages/jasmine/src/jasmine_runner.js b/packages/jasmine/src/jasmine_runner.js index ccb87c3cf6..49c40b454e 100644 --- a/packages/jasmine/src/jasmine_runner.js +++ b/packages/jasmine/src/jasmine_runner.js @@ -51,26 +51,34 @@ Error.stackTraceLimit = Infinity; const IS_TEST_FILE = /[^a-zA-Z0-9](spec|test)\.js$/i; const IS_NODE_MODULE = /\/node_modules\// +// We process arguments by splicing them out of the process.argv +// Users could set their own templated_args on their test, then +// the tested code might process the argv +// So it shouldn't see these Bazel-specific ones +function readArg() { + return process.argv.splice(2, 1)[0]; +} + function main(args) { - if (!args.length) { - throw new Error('Spec file manifest expected argument missing'); + if (args.length < 3) { + throw new Error('expected argument missing'); } + + // first args is always the path to the manifest - const manifest = require.resolve(args[0]); + const manifest = require.resolve(readArg()); // second is always a flag to enable coverage or not - const coverageArg = args[1]; + const coverageArg = readArg(); const enableCoverage = coverageArg === '--coverage'; - - // Remove the manifest, some tested code may process the argv. - // Also remove the --coverage flag - process.argv.splice(2, 2)[0]; + // config file is the next arg + const configFile = readArg(); // the relative directory the coverage reporter uses to find anf filter the files - const cwd = process.cwd() + const cwd = process.cwd(); const jrunner = new JasmineRunner({jasmineCore: jasmineCore}); - if (args.length == 3) { - jrunner.loadConfigFile(args[2]); + if (configFile !== '--noconfig') { + jrunner.loadConfigFile(require.resolve(configFile)); } const allFiles = fs.readFileSync(manifest, UTF8) .split('\n') diff --git a/packages/jasmine/test/BUILD.bazel b/packages/jasmine/test/BUILD.bazel index e6a03b8086..82f5e78aa5 100644 --- a/packages/jasmine/test/BUILD.bazel +++ b/packages/jasmine/test/BUILD.bazel @@ -63,3 +63,16 @@ jasmine_node_test( "--node_options=--experimental-modules", ], ) + +# We have no srcs[] here because we set specs in the config file +jasmine_node_test( + name = "config_file_test", + config_file = "test_config_file.json", + # The file isn't named following our usual conventions + # but since it's configured in the json config file + # Jasmine will still load it + data = ["test_config_file.js"], + # TODO(alexeagle): on Windows CI we get no specs found + # Maybe Jasmine doesn't normalize the slashes in the config + tags = ["fix-windows"], +) diff --git a/packages/jasmine/test/test_config_file.js b/packages/jasmine/test/test_config_file.js new file mode 100644 index 0000000000..7402b2266b --- /dev/null +++ b/packages/jasmine/test/test_config_file.js @@ -0,0 +1,6 @@ +describe('configuring Jasmine', () => { + it('should accept a config file', () => { + // the config_file.json has random: false + expect(jasmine.getEnv().configuration().random).toBeFalsy(); + }); +}); \ No newline at end of file diff --git a/packages/jasmine/test/test_config_file.json b/packages/jasmine/test/test_config_file.json new file mode 100644 index 0000000000..f52aa3ef7e --- /dev/null +++ b/packages/jasmine/test/test_config_file.json @@ -0,0 +1,6 @@ +{ + "random": false, + "spec_files": [ + "**/test_config_*.js" + ] +} \ No newline at end of file