Skip to content
This repository has been archived by the owner on Apr 18, 2022. It is now read-only.

Commit

Permalink
Merge pull request #30 from udibo/dev
Browse files Browse the repository at this point in the history
Make external TestSuite with symbol only
  • Loading branch information
KyleJune authored Mar 7, 2022
2 parents 67e8e62 + f4445a5 commit 810a912
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 147 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Test Suite

[![version](https://img.shields.io/badge/release-0.11.0-success)](https://deno.land/x/test_suite@0.11.0)
[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/test_suite@0.11.0/mod.ts)
[![version](https://img.shields.io/badge/release-0.12.0-success)](https://deno.land/x/test_suite@0.12.0)
[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/test_suite@0.12.0/mod.ts)
[![CI](https://github.com/udibo/test_suite/workflows/CI/badge.svg)](https://github.com/udibo/test_suite/actions?query=workflow%3ACI)
[![codecov](https://codecov.io/gh/udibo/test_suite/branch/main/graph/badge.svg?token=EFKGY72AAV)](https://codecov.io/gh/udibo/test_suite)
[![license](https://img.shields.io/github/license/udibo/test_suite)](https://github.com/udibo/test_suite/blob/master/LICENSE)
Expand All @@ -26,12 +26,12 @@ also be imported directly from GitHub using raw content URLs.

```ts
// Import from Deno's third party module registry
import { describe, it } from "https://deno.land/x/test_suite@0.11.0/mod.ts";
import { describe, it } from "https://deno.land/x/test_suite@0.12.0/mod.ts";
// Import from GitHub
import {
describe,
it,
} from "https://raw.githubusercontent.com/udibo/test_suite/0.11.0/mod.ts";
} from "https://raw.githubusercontent.com/udibo/test_suite/0.12.0/mod.ts";
```

## Usage
Expand All @@ -52,7 +52,7 @@ except they are called before and after each individual test.
Below are some examples of how to use `describe` and `it` in tests.

See
[deno docs](https://doc.deno.land/https/deno.land/x/test_suite@0.11.0/mod.ts)
[deno docs](https://doc.deno.land/https/deno.land/x/test_suite@0.12.0/mod.ts)
for more information.

### Nested test grouping
Expand All @@ -65,13 +65,13 @@ import {
beforeEach,
describe,
it,
} from "https://deno.land/x/test_suite@0.11.0/mod.ts";
} from "https://deno.land/x/test_suite@0.12.0/mod.ts";
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
import {
getUser,
resetUsers,
User,
} from "https://deno.land/x/test_suite@0.11.0/examples/user.ts";
} from "https://deno.land/x/test_suite@0.12.0/examples/user.ts";

describe("user describe", () => {
let user: User;
Expand Down Expand Up @@ -129,13 +129,13 @@ test result: ok. 1 passed (5 steps); 0 failed; 0 ignored; 0 measured; 0 filtered
The example below can be found [here](examples/user_flat_test.ts).

```ts
import { describe, it } from "https://deno.land/x/test_suite@0.11.0/mod.ts";
import { describe, it } from "https://deno.land/x/test_suite@0.12.0/mod.ts";
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
import {
getUser,
resetUsers,
User,
} from "https://deno.land/x/test_suite@0.11.0/examples/user.ts";
} from "https://deno.land/x/test_suite@0.12.0/examples/user.ts";

interface UserContext {
user: User;
Expand Down
94 changes: 54 additions & 40 deletions describe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import {
HookNames,
ItDefinition,
TestSuite,
TestSuiteInternal,
} from "./test_suite.ts";
export type { DescribeDefinition, ItDefinition };
export type { DescribeDefinition, ItDefinition, TestSuite };

/** The arguments for an ItFunction. */
type ItArgs<T> =
Expand Down Expand Up @@ -32,32 +33,32 @@ type ItArgs<T> =
fn: (context: T) => void | Promise<void>,
]
| [
suite: symbol,
suite: TestSuite<T>,
name: string,
options: Omit<ItDefinition<T>, "name" | "suite">,
]
| [
suite: symbol,
suite: TestSuite<T>,
name: string,
fn: (context: T) => void | Promise<void>,
]
| [
suite: symbol,
suite: TestSuite<T>,
fn: (context: T) => void | Promise<void>,
]
| [
suite: symbol,
suite: TestSuite<T>,
name: string,
options: Omit<ItDefinition<T>, "fn" | "name" | "suite">,
fn: (context: T) => void | Promise<void>,
]
| [
suite: symbol,
suite: TestSuite<T>,
options: Omit<ItDefinition<T>, "fn" | "suite">,
fn: (context: T) => void | Promise<void>,
]
| [
suite: symbol,
suite: TestSuite<T>,
options: Omit<ItDefinition<T>, "fn" | "name" | "suite">,
fn: (context: T) => void | Promise<void>,
];
Expand All @@ -70,15 +71,18 @@ function itDefinition<T>(...args: ItArgs<T>): ItDefinition<T> {
optionsOrFn,
fn,
] = args;
let suite: symbol | undefined = undefined;
let suite: TestSuite<T> | undefined = undefined;
let name: string;
let options:
| ItDefinition<T>
| Omit<ItDefinition<T>, "fn">
| Omit<ItDefinition<T>, "name">
| Omit<ItDefinition<T>, "fn" | "name">;
if (typeof suiteOptionsOrNameOrFn === "symbol") {
suite = suiteOptionsOrNameOrFn;
if (
typeof suiteOptionsOrNameOrFn === "object" &&
typeof (suiteOptionsOrNameOrFn as TestSuite<T>).symbol === "symbol"
) {
suite = suiteOptionsOrNameOrFn as TestSuite<T>;
} else {
fn = optionsOrFn as typeof fn;
optionsOrFn = optionsOrNameOrFn as typeof optionsOrFn;
Expand Down Expand Up @@ -128,18 +132,20 @@ export interface it {

/** Registers an individual test case. */
export function it<T>(...args: ItArgs<T>): void {
if (TestSuite.running) {
if (TestSuiteInternal.running) {
throw new Error(
"cannot register new test cases after already registered test cases start running",
);
}
const options = itDefinition(...args);
const { suite } = options;
const testSuite = suite ? TestSuite.suites.get(suite) : TestSuite.current;
const testSuite = suite
? TestSuiteInternal.suites.get(suite.symbol)
: TestSuiteInternal.current;

if (!TestSuite.started) TestSuite.started = true;
if (!TestSuiteInternal.started) TestSuiteInternal.started = true;
if (testSuite) {
TestSuite.addStep(testSuite, options);
TestSuiteInternal.addStep(testSuite, options);
} else {
const {
name,
Expand All @@ -151,7 +157,7 @@ export function it<T>(...args: ItArgs<T>): void {
sanitizeOps,
sanitizeResources,
} = options;
TestSuite.registerTest({
TestSuiteInternal.registerTest({
name,
ignore,
only,
Expand All @@ -160,7 +166,7 @@ export function it<T>(...args: ItArgs<T>): void {
sanitizeOps,
sanitizeResources,
fn: async () => {
if (!TestSuite.running) TestSuite.running = true;
if (!TestSuiteInternal.running) TestSuiteInternal.running = true;
await fn!({} as T);
},
});
Expand All @@ -187,18 +193,18 @@ function addHook<T>(
name: HookNames,
fn: (context: T) => void | Promise<void>,
): void {
if (!TestSuite.current) {
if (TestSuite.started) {
if (!TestSuiteInternal.current) {
if (TestSuiteInternal.started) {
throw new Error(
"cannot add global hooks after a global test is registered",
);
}
TestSuite.current = new TestSuite({
TestSuiteInternal.current = new TestSuiteInternal({
name: "global",
[name]: fn,
});
} else {
TestSuite.setHook(TestSuite.current!, name, fn);
TestSuiteInternal.setHook(TestSuiteInternal.current!, name, fn);
}
}

Expand Down Expand Up @@ -254,36 +260,36 @@ type DescribeArgs<T> =
fn: () => void,
]
| [
suite: symbol,
suite: TestSuite<T>,
name: string,
]
| [
suite: symbol,
suite: TestSuite<T>,
name: string,
options: Omit<DescribeDefinition<T>, "name" | "suite">,
]
| [
suite: symbol,
suite: TestSuite<T>,
name: string,
fn: () => void,
]
| [
suite: symbol,
suite: TestSuite<T>,
fn: () => void,
]
| [
suite: symbol,
suite: TestSuite<T>,
name: string,
options: Omit<DescribeDefinition<T>, "fn" | "name" | "suite">,
fn: () => void,
]
| [
suite: symbol,
suite: TestSuite<T>,
options: Omit<DescribeDefinition<T>, "fn" | "suite">,
fn: () => void,
]
| [
suite: symbol,
suite: TestSuite<T>,
options: Omit<DescribeDefinition<T>, "fn" | "name" | "suite">,
fn: () => void,
];
Expand All @@ -298,15 +304,18 @@ function describeDefinition<T>(
optionsOrFn,
fn,
] = args;
let suite: symbol | undefined = undefined;
let suite: TestSuite<T> | undefined = undefined;
let name: string;
let options:
| DescribeDefinition<T>
| Omit<DescribeDefinition<T>, "fn">
| Omit<DescribeDefinition<T>, "name">
| Omit<DescribeDefinition<T>, "fn" | "name">;
if (typeof suiteOptionsOrNameOrFn === "symbol") {
suite = suiteOptionsOrNameOrFn;
if (
typeof suiteOptionsOrNameOrFn === "object" &&
typeof (suiteOptionsOrNameOrFn as TestSuite<T>).symbol === "symbol"
) {
suite = suiteOptionsOrNameOrFn as TestSuite<T>;
} else {
fn = optionsOrFn as typeof fn;
optionsOrFn = optionsOrNameOrFn as typeof optionsOrFn;
Expand Down Expand Up @@ -336,7 +345,11 @@ function describeDefinition<T>(
}

if (!suite) {
suite = options.suite ?? TestSuite.current?.symbol;
suite = options.suite;
}
if (!suite && TestSuiteInternal.current) {
const { symbol } = TestSuiteInternal.current;
suite = { symbol };
}

return {
Expand All @@ -349,32 +362,33 @@ function describeDefinition<T>(

/** Registers a test suite. */
export interface describe {
<T>(...args: DescribeArgs<T>): symbol;
<T>(...args: DescribeArgs<T>): TestSuite<T>;

/** Registers a test suite with only set to true. */
only<T>(...args: DescribeArgs<T>): symbol;
only<T>(...args: DescribeArgs<T>): TestSuite<T>;

/** Registers a test suite with ignore set to true. */
ignore<T>(...args: DescribeArgs<T>): symbol;
ignore<T>(...args: DescribeArgs<T>): TestSuite<T>;
}

/** Registers a test suite. */
export function describe<T>(
...args: DescribeArgs<T>
): symbol {
if (TestSuite.running) {
): TestSuite<T> {
if (TestSuiteInternal.running) {
throw new Error(
"cannot register new test suites after already registered test cases start running",
);
}
const options = describeDefinition(...args);
if (!TestSuite.started) TestSuite.started = true;
return (new TestSuite(options)).symbol;
if (!TestSuiteInternal.started) TestSuiteInternal.started = true;
const { symbol } = new TestSuiteInternal(options);
return { symbol };
}

describe.only = function describeOnly<T>(
...args: DescribeArgs<T>
): symbol {
): TestSuite<T> {
const options = describeDefinition(...args);
return describe({
...options,
Expand All @@ -384,7 +398,7 @@ describe.only = function describeOnly<T>(

describe.ignore = function describeIgnore<T>(
...args: DescribeArgs<T>
): symbol {
): TestSuite<T> {
const options = describeDefinition(...args);
return describe({
...options,
Expand Down
Loading

0 comments on commit 810a912

Please sign in to comment.