Skip to content

Commit

Permalink
Merge pull request #105 from lucacasonato/fix-104
Browse files Browse the repository at this point in the history
fix: afterAll runs after last suite/case
  • Loading branch information
ebebbington authored Dec 31, 2020
2 parents 363560d + 3115408 commit 85bab1a
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 84 deletions.
135 changes: 74 additions & 61 deletions src/test_case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,77 +30,90 @@ export class TestCase {
let executedBeforeAllSuiteHook = false;
let executedAfterAllSuiteHook = false;

Object.keys(this.plan.suites).forEach((suiteName) => {
Object.keys(this.plan.suites).forEach((suiteName, suiteIndex) => {
// Track the execution of hooks
let executedBeforeEachSuiteHook = false;
let executedAfterEachSuiteHook = false;
let executedBeforeAllCaseHook = false;
let executedAfterAllCaseHook = false;

// Run cases
this.plan!.suites[suiteName].cases!.forEach(async (c: ITestCase) => {
// Run the case - required to run like this because the
// hooks need to be ran inside the Deno.test call. Deno.test seems to queue
// the tests, meaning all hooks are ran, and **then** the tests are ran
const hookAttachedTestFn = async () => {
if (this.plan.before_all_suite_hook && !executedBeforeAllSuiteHook) {
await this.plan.before_all_suite_hook();
executedBeforeAllSuiteHook = true;
}
if (
this.plan.before_each_suite_hook && !executedBeforeEachSuiteHook
) {
await this.plan.before_each_suite_hook();
executedBeforeEachSuiteHook = true;
}
if (
this.plan.suites[suiteName].before_all_case_hook &&
!executedBeforeAllCaseHook
) {
await this.plan.suites[suiteName].before_all_case_hook!();
executedBeforeAllCaseHook = true;
}
if (this.plan.suites[suiteName].before_each_case_hook) {
await this.plan.suites[suiteName].before_each_case_hook!();
}
this.plan!.suites[suiteName].cases!.forEach(
async (c: ITestCase, caseIndex) => {
// Run the case - required to run like this because the
// hooks need to be ran inside the Deno.test call. Deno.test seems to queue
// the tests, meaning all hooks are ran, and **then** the tests are ran
const hookAttachedTestFn = async () => {
if (
this.plan.before_all_suite_hook && !executedBeforeAllSuiteHook
) {
await this.plan.before_all_suite_hook();
executedBeforeAllSuiteHook = true;
}
if (
this.plan.before_each_suite_hook && !executedBeforeEachSuiteHook
) {
await this.plan.before_each_suite_hook();
executedBeforeEachSuiteHook = true;
}
if (
this.plan.suites[suiteName].before_all_case_hook &&
!executedBeforeAllCaseHook
) {
await this.plan.suites[suiteName].before_all_case_hook!();
executedBeforeAllCaseHook = true;
}
if (this.plan.suites[suiteName].before_each_case_hook) {
await this.plan.suites[suiteName].before_each_case_hook!();
}

await c.testFn();
await c.testFn();

if (this.plan.suites[suiteName].after_each_case_hook) {
await this.plan.suites[suiteName].after_each_case_hook!();
}
if (
this.plan.suites[suiteName].after_all_case_hook &&
!executedAfterAllCaseHook
) {
await this.plan.suites[suiteName].after_all_case_hook!();
executedAfterAllCaseHook = true;
}
if (this.plan.after_each_suite_hook && !executedAfterEachSuiteHook) {
await this.plan.after_each_suite_hook();
executedAfterEachSuiteHook = true;
}
if (this.plan.after_all_suite_hook && !executedAfterAllSuiteHook) {
await this.plan.after_all_suite_hook();
executedAfterAllSuiteHook = true;
if (this.plan.suites[suiteName].after_each_case_hook) {
await this.plan.suites[suiteName].after_each_case_hook!();
}
const isLastCase =
(this.plan!.suites[suiteName].cases!.length - 1) == caseIndex;
if (
this.plan.suites[suiteName].after_all_case_hook &&
!executedAfterAllCaseHook && isLastCase
) {
await this.plan.suites[suiteName].after_all_case_hook!();
executedAfterAllCaseHook = true;
}
if (
this.plan.after_each_suite_hook && !executedAfterEachSuiteHook
) {
await this.plan.after_each_suite_hook();
executedAfterEachSuiteHook = true;
}
const isLastSuite =
(Object.keys(this.plan!.suites).length - 1) == suiteIndex;
if (
this.plan.after_all_suite_hook && !executedAfterAllSuiteHook &&
isLastSuite
) {
await this.plan.after_all_suite_hook();
executedAfterAllSuiteHook = true;
}
};
// (ebebbington) To stop the output of test running being horrible
// in the CI, we will only display the new name which should be
// "plan | suite " case", as opposed to the "super saiyan"
// version. This name is generated differently inside `formatTestCaseName`
// based on if the tests are being ran inside a CI job
if (Deno.env.get("CI") === "true") {
await Deno.test(c.new_name, async () => {
await hookAttachedTestFn();
});
} else {
await Deno.test(c.name, async () => {
Deno.stdout.writeSync(encoder.encode(c.new_name));
await hookAttachedTestFn();
});
}
};
// (ebebbington) To stop the output of test running being horrible
// in the CI, we will only display the new name which should be
// "plan | suite " case", as opposed to the "super saiyan"
// version. This name is generated differently inside `formatTestCaseName`
// based on if the tests are being ran inside a CI job
if (Deno.env.get("CI") === "true") {
await Deno.test(c.new_name, async () => {
await hookAttachedTestFn();
});
} else {
await Deno.test(c.name, async () => {
Deno.stdout.writeSync(encoder.encode(c.new_name));
await hookAttachedTestFn();
});
}
});
},
);
});
}
}
54 changes: 31 additions & 23 deletions tests/integration/hooks/after_all_test.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,69 @@
/**
* Purpose of this test is to ensure a test using before_each succeeds
* Purpose of this test is to ensure a test using before_all succeeds
*/

import { Rhum } from "../../../mod.ts";

let suite_val = "Ed";
let case_val = 22;
let async_case_val = 5;
let suite_val = 0;
let case_val = 0;
let async_case_val = 0;
Rhum.testPlan("after_all_test.ts", () => {
Rhum.afterAll(() => {
suite_val = "Eric";
Rhum.asserts.assertEquals(suite_val, 3);
});
// Run the first test suite
Rhum.testSuite("test suite 1", () => {
Rhum.afterAll(() => {
case_val = 2;
Rhum.asserts.assertEquals(case_val, 2);
case_val = 3;
});
Rhum.testCase("hooks properly set suite_val and case_val", () => {
// Asserting that the suite val should not have been changed by the hook (yet)
Rhum.asserts.assertEquals(suite_val, "Ed");
// Revert it back for the next test that uses it
suite_val = "Ed";
// Assert the value is kept the same (hook hasn't ran yet)
Rhum.asserts.assertEquals(case_val, 22);
// Asserting that the suite val should not have been changed by the hook
Rhum.asserts.assertEquals(suite_val, 0);
suite_val = 1;
// Asserting that the case val should not have been changed by the hook
Rhum.asserts.assertEquals(case_val, 0);
case_val = 1;
});
Rhum.testCase("hooks properly set case_val", () => {
// Assert the value has changes as the hook should have ran
Rhum.asserts.assertEquals(case_val, 2);
// Asserting that the suite val should not have been changed by the hook
Rhum.asserts.assertEquals(suite_val, 1);
suite_val = 2;
// Asserting that the case val should not have been changed by the hook
Rhum.asserts.assertEquals(case_val, 1);
case_val = 2;
});
});

// Run the second test suite
Rhum.testSuite("test suite 2", () => {
Rhum.afterAll(() => {
case_val = 0;
Rhum.asserts.assertEquals(case_val, 4);
});
Rhum.testCase("hooks properly set suite_val and case_val", async () => {
// Asserting the hook should have replaced the name
Rhum.asserts.assertEquals(suite_val, "Eric");
suite_val = "Ed";
// Should be kept the same as the after each hook should have updated the value
Rhum.asserts.assertEquals(case_val, 2);
// Asserting that the suite val should not have been changed by the hook
Rhum.asserts.assertEquals(suite_val, 2);
suite_val = 3;
// Asserting that the case val has been changed by the hook
Rhum.asserts.assertEquals(case_val, 3);
case_val = 4;
});
});
Rhum.testSuite("test suite 3", () => {
Rhum.afterAll(async () => {
Rhum.asserts.assertEquals(async_case_val, 1);
await new Promise((resolve) => {
setTimeout(() => resolve((async_case_val = 15)), 1000);
setTimeout(() => resolve((async_case_val = 2)), 1000);
});
});
Rhum.testCase("Async afterAll hook has no effect before case", () => {
Rhum.asserts.assertEquals(async_case_val, 5);
Rhum.asserts.assertEquals(async_case_val, 0);
async_case_val = 1;
});
});
Rhum.testSuite("test suite 4", () => {
Rhum.testCase("Async afterAll hook has effect after case", () => {
Rhum.asserts.assertEquals(async_case_val, 15);
Rhum.asserts.assertEquals(async_case_val, 2);
});
});
});
Expand Down

0 comments on commit 85bab1a

Please sign in to comment.