From d9e89531105b6ce989e5a860781536cbdc99235c Mon Sep 17 00:00:00 2001
From: Vincent LE GOFF <g_n_s@hotmail.fr>
Date: Tue, 26 Mar 2019 16:29:12 +0100
Subject: [PATCH] testing: turn off exitOnFail by default (#307)

---
 testing/README.md |  7 +++++--
 testing/mod.ts    | 35 ++++++++++++++++++++---------------
 2 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/testing/README.md b/testing/README.md
index 684d5d4bc3..b0c6bfc1af 100644
--- a/testing/README.md
+++ b/testing/README.md
@@ -13,7 +13,7 @@ object is passed, the `name` property is used to identify the test. If the asser
 
 Asserts are exposed in `testing/asserts.ts` module.
 
-- `equal` - Deep comparision function, where `actual` and `expected` are
+- `equal()` - Deep comparision function, where `actual` and `expected` are
   compared deeply, and if they vary, `equal` returns `false`.
 - `assert()` - Expects a boolean value, throws if the value is `false`.
 - `assertEquals()` - Uses the `equal` comparison and throws if the `actual` and
@@ -37,7 +37,10 @@ Asserts are exposed in `testing/asserts.ts` module.
 - `unimplemented()` - Use this to stub out methods that will throw when invoked
 - `unreachable()` - Used to assert unreachable code
 
-`runTests()` executes the declared tests.
+`runTests()` executes the declared tests. It accepts a `RunOptions` parameter:
+
+- parallel : Execute tests in a parallel way.
+- exitOnFail : if one test fails, test will throw an error and stop the tests. If not all tests will be processed.
 
 Basic usage:
 
diff --git a/testing/mod.ts b/testing/mod.ts
index 09e1837965..d0d755e78a 100644
--- a/testing/mod.ts
+++ b/testing/mod.ts
@@ -9,8 +9,6 @@ export interface TestDefinition {
   name: string;
 }
 
-export const exitOnFail = true;
-
 let filterRegExp: RegExp | null;
 const tests: TestDefinition[] = [];
 
@@ -93,7 +91,8 @@ function report(result: TestResult): void {
 function printResults(
   stats: TestStats,
   results: TestResults,
-  flush: boolean
+  flush: boolean,
+  exitOnFail: boolean
 ): void {
   if (flush) {
     for (const result of results.cases.values()) {
@@ -125,7 +124,8 @@ function previousPrinted(name: string, results: TestResults): boolean {
 async function createTestCase(
   stats: TestStats,
   results: TestResults,
-  { fn, name }: TestDefinition
+  { fn, name }: TestDefinition,
+  exitOnFail: boolean
 ): Promise<void> {
   const result: TestResult = results.cases.get(results.keys.get(name));
   try {
@@ -147,18 +147,20 @@ async function createTestCase(
 function initTestCases(
   stats: TestStats,
   results: TestResults,
-  tests: TestDefinition[]
+  tests: TestDefinition[],
+  exitOnFail: boolean
 ): Array<Promise<void>> {
-  return tests.map(createTestCase.bind(null, stats, results));
+  return tests.map(createTestCase.bind(null, stats, results, exitOnFail));
 }
 
 async function runTestsParallel(
   stats: TestStats,
   results: TestResults,
-  tests: TestDefinition[]
+  tests: TestDefinition[],
+  exitOnFail: boolean
 ): Promise<void> {
   try {
-    await Promise.all(initTestCases(stats, results, tests));
+    await Promise.all(initTestCases(stats, results, tests, exitOnFail));
   } catch (_) {
     // The error was thrown to stop awaiting all promises if exitOnFail === true
     // stats.failed has been incremented and the error stored in results
@@ -167,7 +169,8 @@ async function runTestsParallel(
 
 async function runTestsSerial(
   stats: TestStats,
-  tests: TestDefinition[]
+  tests: TestDefinition[],
+  exitOnFail: boolean
 ): Promise<void> {
   for (const { fn, name } of tests) {
     // See https://github.com/denoland/deno/pull/1452
@@ -193,15 +196,17 @@ async function runTestsSerial(
 /** Defines options for controlling execution details of a test suite. */
 export interface RunOptions {
   parallel?: boolean;
+  exitOnFail?: boolean;
 }
 
 /**
  * Runs specified test cases.
  * Parallel execution can be enabled via the boolean option; default: serial.
  */
-export async function runTests({ parallel = false }: RunOptions = {}): Promise<
-  void
-> {
+export async function runTests({
+  parallel = false,
+  exitOnFail = false
+}: RunOptions = {}): Promise<void> {
   const stats: TestStats = {
     measured: 0,
     ignored: 0,
@@ -212,11 +217,11 @@ export async function runTests({ parallel = false }: RunOptions = {}): Promise<
   const results: TestResults = createTestResults(tests);
   console.log(`running ${tests.length} tests`);
   if (parallel) {
-    await runTestsParallel(stats, results, tests);
+    await runTestsParallel(stats, results, tests, exitOnFail);
   } else {
-    await runTestsSerial(stats, tests);
+    await runTestsSerial(stats, tests, exitOnFail);
   }
-  printResults(stats, results, parallel);
+  printResults(stats, results, parallel, exitOnFail);
   if (stats.failed) {
     // Use setTimeout to avoid the error being ignored due to unhandled
     // promise rejections being swallowed.