Skip to content

Commit

Permalink
testing: Refactor to resemble prettier
Browse files Browse the repository at this point in the history
Should help later when extracting common functionality to expandGlob(),
like exclusion. Makes findTestModules() an async generator.
  • Loading branch information
nayeemrmn committed Sep 28, 2019
1 parent ff97903 commit 4729107
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 43 deletions.
74 changes: 37 additions & 37 deletions testing/runner.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
#!/usr/bin/env -S deno -A
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { parse } from "../flags/mod.ts";
import {
WalkInfo,
expandGlobSync,
glob,
ExpandGlobOptions
} from "../fs/mod.ts";
import { WalkInfo, expandGlob, glob, ExpandGlobOptions } from "../fs/mod.ts";
import { isWindows } from "../fs/path/constants.ts";
import { isAbsolute, join } from "../fs/path/mod.ts";
import { RunTestsOptions, runTests } from "./mod.ts";
Expand Down Expand Up @@ -64,26 +59,20 @@ function filePathToUrl(path: string): string {
return `file:https://${isWindows ? "/" : ""}${path.replace(/\\/g, "/")}`;
}

function expandDirectory(dir: string, options: ExpandGlobOptions): WalkInfo[] {
return DIR_GLOBS.flatMap((s: string): WalkInfo[] => [
...expandGlobSync(s, { ...options, root: dir })
]);
}

/**
* Given a list of globs or URLs to include and exclude and a root directory
* from which to expand relative globs, return a list of URLs
* from which to expand relative globs, yield a list of URLs
* (file: or remote) that should be imported for the test runner.
*/
export async function findTestModules(
export async function* findTestModules(
includeModules: string[],
excludeModules: string[],
root: string = cwd()
): Promise<string[]> {
): AsyncIterableIterator<string> {
const [includePaths, includeUrls] = partition(includeModules, isRemoteUrl);
const [excludePaths, excludeUrls] = partition(excludeModules, isRemoteUrl);

const expandGlobOpts = {
const expandGlobOpts: ExpandGlobOptions = {
root,
extended: true,
globstar: true,
Expand All @@ -99,25 +88,36 @@ export async function findTestModules(
const excludeUrlPatterns = excludeUrls.map(
(url: string): RegExp => RegExp(url)
);
const notExcludedPath = ({ filename }: WalkInfo): boolean =>
const shouldIncludePath = ({ filename }: WalkInfo): boolean =>
!excludePathPatterns.some((p: RegExp): boolean => !!filename.match(p));
const notExcludedUrl = (url: string): boolean =>
const shouldIncludeUrl = (url: string): boolean =>
!excludeUrlPatterns.some((p: RegExp): boolean => !!url.match(p));

const matchedPaths = includePaths
.flatMap((s: string): WalkInfo[] => [...expandGlobSync(s, expandGlobOpts)])
.filter(notExcludedPath)
.flatMap(({ filename, info }): string[] =>
info.isDirectory()
? expandDirectory(filename, { ...expandGlobOpts, includeDirs: false })
.filter(notExcludedPath)
.map(({ filename }): string => filename)
: [filename]
);
async function* expandDirectory(d: string): AsyncIterableIterator<string> {
for (const dirGlob of DIR_GLOBS) {
for await (const walkInfo of expandGlob(dirGlob, {
...expandGlobOpts,
root: d,
includeDirs: false
})) {
if (shouldIncludePath(walkInfo)) {
yield filePathToUrl(walkInfo.filename);
}
}
}
}

const matchedUrls = includeUrls.filter(notExcludedUrl);
for (const globString of includePaths) {
for await (const walkInfo of expandGlob(globString, expandGlobOpts)) {
if (walkInfo.info.isDirectory()) {
yield* expandDirectory(walkInfo.filename);
} else if (shouldIncludePath(walkInfo)) {
yield filePathToUrl(walkInfo.filename);
}
}
}

return [...matchedPaths.map(filePathToUrl), ...matchedUrls];
yield* includeUrls.filter(shouldIncludeUrl);
}

export interface RunTestModulesOptions extends RunTestsOptions {
Expand Down Expand Up @@ -162,9 +162,13 @@ export async function runTestModules({
skip = /^\s*$/,
disableLog = false
}: RunTestModulesOptions = {}): Promise<void> {
const testModuleUrls = await findTestModules(include, exclude);
let moduleCount = 0;
for await (const testModule of findTestModules(include, exclude)) {
await import(testModule);
moduleCount++;
}

if (testModuleUrls.length == 0) {
if (moduleCount == 0) {
const noneFoundMessage = "No matching test modules found.";
if (!allowNone) {
throw new DenoError(ErrorKind.NotFound, noneFoundMessage);
Expand All @@ -175,11 +179,7 @@ export async function runTestModules({
}

if (!disableLog) {
console.log(`Found ${testModuleUrls.length} matching test modules.`);
}

for (const url of testModuleUrls) {
await import(url);
console.log(`Found ${moduleCount} matching test modules.`);
}

await runTests({
Expand Down
29 changes: 23 additions & 6 deletions testing/runner_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,30 @@ import { test } from "./mod.ts";
import { findTestModules } from "./runner.ts";
import { isWindows } from "../fs/path/constants.ts";
import { assertEquals } from "../testing/asserts.ts";
const { cwd } = Deno;

function urlToFilePath(url: URL): string {
// Since `new URL('file:https:///C:/a').pathname` is `/C:/a`, remove leading slash.
return url.pathname.slice(url.protocol == "file:" && isWindows ? 1 : 0);
}

async function findTestModulesArray(
include: string[],
exclude: string[],
root: string = cwd()
): Promise<string[]> {
const result = [];
for await (const testModule of findTestModules(include, exclude, root)) {
result.push(testModule);
}
return result;
}

const TEST_DATA_URL = new URL("testdata", import.meta.url);
const TEST_DATA_PATH = urlToFilePath(TEST_DATA_URL);

test(async function findTestModulesDir1(): Promise<void> {
const urls = await findTestModules(["."], [], TEST_DATA_PATH);
const urls = await findTestModulesArray(["."], [], TEST_DATA_PATH);
assertEquals(urls.sort(), [
`${TEST_DATA_URL}/bar_test.js`,
`${TEST_DATA_URL}/foo_test.ts`,
Expand All @@ -27,7 +40,7 @@ test(async function findTestModulesDir1(): Promise<void> {
});

test(async function findTestModulesDir2(): Promise<void> {
const urls = await findTestModules(["subdir"], [], TEST_DATA_PATH);
const urls = await findTestModulesArray(["subdir"], [], TEST_DATA_PATH);
assertEquals(urls.sort(), [
`${TEST_DATA_URL}/subdir/bar_test.js`,
`${TEST_DATA_URL}/subdir/foo_test.ts`,
Expand All @@ -37,7 +50,11 @@ test(async function findTestModulesDir2(): Promise<void> {
});

test(async function findTestModulesGlob(): Promise<void> {
const urls = await findTestModules(["**/*_test.{js,ts}"], [], TEST_DATA_PATH);
const urls = await findTestModulesArray(
["**/*_test.{js,ts}"],
[],
TEST_DATA_PATH
);
assertEquals(urls.sort(), [
`${TEST_DATA_URL}/bar_test.js`,
`${TEST_DATA_URL}/foo_test.ts`,
Expand All @@ -47,7 +64,7 @@ test(async function findTestModulesGlob(): Promise<void> {
});

test(async function findTestModulesExcludeDir(): Promise<void> {
const urls = await findTestModules(["."], ["subdir"], TEST_DATA_PATH);
const urls = await findTestModulesArray(["."], ["subdir"], TEST_DATA_PATH);
assertEquals(urls.sort(), [
`${TEST_DATA_URL}/bar_test.js`,
`${TEST_DATA_URL}/foo_test.ts`,
Expand All @@ -57,7 +74,7 @@ test(async function findTestModulesExcludeDir(): Promise<void> {
});

test(async function findTestModulesExcludeGlob(): Promise<void> {
const urls = await findTestModules(["."], ["**/foo*"], TEST_DATA_PATH);
const urls = await findTestModulesArray(["."], ["**/foo*"], TEST_DATA_PATH);
assertEquals(urls.sort(), [
`${TEST_DATA_URL}/bar_test.js`,
`${TEST_DATA_URL}/subdir/bar_test.js`,
Expand All @@ -73,6 +90,6 @@ test(async function findTestModulesRemote(): Promise<void> {
"https://example.com/colors_test.ts",
"http:https://example.com/printf_test.ts"
];
const matches = await findTestModules(urls, []);
const matches = await findTestModulesArray(urls, []);
assertEquals(matches, urls);
});

0 comments on commit 4729107

Please sign in to comment.