node tests: Find files in Python.

The code to run single files was added
in c15695e514,
and it's just kinda strange code.

We already do a lot of file logic in Python
to check for line-coverage, so it's easier
to just have all the logic in Python.

This adds a new feature--you can now specify
the actual file:

    ./tools/test-js-with-node frontend_tests/node_tests/people.js

(This is helpful if you just want to use
shell autocomplete.)

Another minor change is that if you specify
individual files, we won't sort them.  This is
important when you're trying to hunt down test
leaks.

Finally, we have a nicer message if we can't find
the file.
This commit is contained in:
Steve Howell 2020-09-02 19:58:08 +00:00 committed by Steve Howell
parent e9bbfbc624
commit dc1795a3da
3 changed files with 27 additions and 62 deletions

View File

@ -1,47 +0,0 @@
"use strict";
const fs = require("fs");
const path = require("path");
const _ = require("lodash");
exports.find_files_to_run = function () {
let oneFileFilter = [];
let testsDifference = [];
if (process.argv[2]) {
oneFileFilter = process.argv
.slice(2)
.filter((filename) => /[.]js$/.test(filename))
.map((filename) => filename.replace(/\.js$/i, ""));
}
// tests_dir is where we find our specific unit tests (as opposed
// to framework code)
const tests_dir = __dirname.replace(/zjsunit/, "node_tests");
let tests = fs
.readdirSync(tests_dir)
.filter((filename) => !/^\./i.test(filename))
.filter((filename) => /\.js$/i.test(filename))
.map((filename) => filename.replace(/\.js$/i, ""));
if (oneFileFilter.length > 0) {
tests = tests.filter((filename) => oneFileFilter.includes(filename));
testsDifference = _.difference(oneFileFilter, tests);
}
testsDifference.forEach((filename) => {
throw filename + ".js does not exist";
});
tests.sort();
const files = tests.map((fn) => {
const obj = {};
obj.name = fn;
obj.full_name = path.join(tests_dir, fn);
return obj;
});
return files;
};

View File

@ -7,7 +7,6 @@ const path = require("path");
const Handlebars = require("handlebars/runtime");
const _ = require("lodash");
const finder = require("./finder");
const handlebars = require("./handlebars");
const stub_i18n = require("./i18n");
const namespace = require("./namespace");
@ -34,7 +33,7 @@ function immediate(f) {
}
// Find the files we need to run.
const files = finder.find_files_to_run(); // may write to console
const files = process.argv.slice(2);
if (files.length === 0) {
throw "No tests found";
}
@ -100,9 +99,9 @@ global.markdown_assert = require("./markdown_assert");
let current_file_name;
function run_one_module(file) {
console.info("running tests for " + file.name);
current_file_name = file.name;
require(file.full_name);
console.info("running test " + path.basename(file, ".js"));
current_file_name = file;
require(file);
}
global.run_test = (label, f) => {

View File

@ -5,7 +5,7 @@ import os
import pwd
import subprocess
import sys
from typing import Any, Dict
from typing import Any, Dict, List
TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.dirname(TOOLS_DIR))
@ -203,24 +203,37 @@ def get_dev_host() -> str:
def print_error(msg: str) -> None:
print(BOLDRED + 'ERROR:' + ENDC + ' ' + msg)
def clean_file(orig_fn: str) -> str:
fn = orig_fn
if not fn.endswith(".js"):
fn += ".js"
if "frontend_tests/" not in fn:
fn = os.path.join(ROOT_DIR, "frontend_tests", "node_tests", fn)
fn = os.path.abspath(fn)
if not os.path.exists(fn):
print(f"Cannot find {orig_fn} ({fn})")
sys.exit(1)
return fn
def clean_files(fns: List[str]) -> List[str]:
cleaned_files = [clean_file(fn) for fn in fns]
return cleaned_files
def run_tests_via_node_js() -> int:
os.environ['TZ'] = 'UTC'
# Add ".js" to the end of all the file arguments, so index.js
# can actually verify if the file exists or not.
for index, arg in enumerate(options.args):
if not arg.endswith('.js') and not arg.endswith('.ts'):
# If it doesn't end with ".js" or ".ts", assume it is a JS file,
# since most files are currently JS files.
options.args[index] = arg + '.js'
# The index.js test runner is the real "driver" here, and we launch
# with either nyc or node, depending on whether we want coverage
# reports. Running under nyc is slower and creates funny
# tracebacks, so you generally want to get coverage reports only
# after making sure tests will pass.
node_tests_cmd = ['node', '--stack-trace-limit=100', INDEX_JS]
node_tests_cmd += individual_files
if individual_files:
files = individual_files
else:
files = sorted(glob.glob("frontend_tests/node_tests/*.js"))
node_tests_cmd += clean_files(files)
if options.coverage:
coverage_dir = os.path.join(ROOT_DIR, 'var/node-coverage')