Skip to content

Commit f67e24b

Browse files
committed
Add new cli testing suite information to READMEs
1 parent 17cb559 commit f67e24b

7 files changed

Lines changed: 64 additions & 53 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@ new UnitTest("Throws error for division by zero")
2727

2828
**🔩   [Unit](./packages/@unit/README.md)**   `unit`
2929

30-
> Test arbitrary units of code based on deep expectation comparisons.
30+
> Test arbitrary units of code based on deep expected value comparisons.
3131
3232
**🔩   [HTTP](./packages/@http/README.md)**   `http`
3333

3434
> Test HTTP(S) endpoints based on expectation filtered responses.
3535
36+
**🔩   [CLI](./packages/@cli/README.md)**   `cli`
37+
38+
> Test command line interfaces based on expected stdout or stderr.
39+
3640
##
3741

3842
<sub>© Thassilo Martin Schiepanski</sub>

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@cli/README.md

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# [rJS Testing](https://github.com/rapidjs-org/testing) CLITest `cli`
22

3-
rJS Testing CLI testing suite (`CLITest`): Test command line interfaces based on stdout and -err.
3+
rJS Testing CLI testing suite (`CLITest`): Test command line interfaces based on expected stdout or stderr.
44

55
``` cli
66
npm i -D @rapidjs.org/testing-cli
@@ -30,40 +30,45 @@ HTTPTest.configure(configuration: RequestOptions & {
3030

3131
``` ts
3232
.actual(binary: string, arg?: string[])
33-
.actual(args: string[]) // imply binary if defined a common
33+
.actual(args: string[]) // Imply binary if defined a common
3434
```
3535

3636
#### Expected
3737

3838
``` ts
39-
.expected(binary: string, arg?: string[])
40-
.expected(args: string[]) // imply binary if defined a common
39+
.expected(feedback: {
40+
stdout?: string|string[]; // Either text as is, or array of lines
41+
stderr?: string|string[];
42+
})
43+
.expected(stdout: string|string[]) // Only check stdout
4144
```
4245

46+
> The execution output to be compared is whitespace normalised, i.e. any non-break whitespace character is condensed to a single space.
47+
4348
### Value-based Assertion
4449

4550
``` ts
46-
new CLITest("List files")
47-
.actual(<expression>)
48-
.expected(<expression>);
51+
new CLITest("Print working directory")
52+
.actual("pwd")
53+
.expected("/Users/rjs/app");
4954
```
5055

5156
## Comparison Strategy
5257

53-
...
58+
Before a comparison of a binary execution output, it is whitespace normalised. This is, any non-break whitespace character is condensed to a single space.
5459

5560
**&thinsp; SUCCESS**
5661

5762
``` js
58-
.actual(<expression>)
59-
.expected(<expression>)
63+
.actual("ls", [ "-L" ])
64+
.expected("img1.png img2.png")
6065
```
6166

6267
**&thinsp; FAILURE**
6368

6469
``` js
65-
.actual(<expression>)
66-
.expected(<expression>)
70+
.actual("ls", [ "-L" ])
71+
.expected("img1.png img2.png")
6772
```
6873

6974
##

packages/@cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@
3434
"dependencies": {
3535
"@rapidjs.org/testing": "0.x"
3636
}
37-
}
37+
}

packages/@cli/src/CLITest.ts

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,71 +28,72 @@ export class CLITest extends Test<IOutput> {
2828

2929
private normalizeOutput(output: Partial<IOutput>): IOutput {
3030
const normalizeStdValue = (value: string) => {
31-
return (value ?? "")
32-
.replace(/(\n|\r)+/g, "\n")
33-
.replace(/(\t| )+/g, " ")
34-
.trim()
35-
?? null;
36-
}
31+
return (
32+
(value ?? "")
33+
.replace(/(\n|\r)+/g, "\n")
34+
.replace(/(\t| )+/g, " ")
35+
.trim() ?? null
36+
);
37+
};
3738
return {
3839
stdout: normalizeStdValue(output.stdout),
3940
stderr: normalizeStdValue(output.stderr)
4041
};
4142
}
42-
43+
4344
protected evalActualExpression(args: string[]): Promise<IOutput>;
4445
protected evalActualExpression(binary: string, args?: string[]): Promise<IOutput>;
45-
protected evalActualExpression(binaryOrArgs: string|string[], args: string[] = []): Promise<IOutput> {
46-
// TODO: Pipe chain abstraction (?)
47-
const effectiveBinary: string = (!binaryOrArgs || Array.isArray(binaryOrArgs))
48-
? CLITest.configuration.commonBinary
49-
: binaryOrArgs;
50-
if(!effectiveBinary) throw new SyntaxError("Missing binary to execute");
46+
protected evalActualExpression(binaryOrArgs: string | string[], args: string[] = []): Promise<IOutput> {
47+
// TODO: Unix pipes abstraction (?)
48+
// TODO: Possibility top check underlying effect (and chain with other test suite) (?)
49+
50+
const effectiveBinary: string =
51+
!binaryOrArgs || Array.isArray(binaryOrArgs) ? CLITest.configuration.commonBinary : binaryOrArgs;
52+
if (!effectiveBinary) throw new SyntaxError("Missing binary to execute");
5153

52-
const effectiveArgs: string[] = (args ?? [ binaryOrArgs ].flat()) ?? [];
54+
const effectiveArgs: string[] = args ?? [binaryOrArgs].flat() ?? [];
5355

5456
return new Promise((resolve, reject) => {
55-
exec([ effectiveBinary, effectiveArgs ].flat().join(" "), (err: Error, stdout: string, stderr: string) => {
56-
if(err && !stderr) {
57+
exec([effectiveBinary, effectiveArgs].flat().join(" "), (err: Error, stdout: string, stderr: string) => {
58+
if (err && !stderr) {
5759
reject(err);
5860

5961
return;
6062
}
61-
62-
resolve(this.normalizeOutput({
63-
stdout, stderr
64-
}));
63+
64+
resolve(
65+
this.normalizeOutput({
66+
stdout,
67+
stderr
68+
})
69+
);
6570
});
6671
});
6772
}
6873

69-
protected evalExpectedExpression(expectedOutput: Partial<IOutput>|string): IOutput {
74+
protected evalExpectedExpression(expectedOutput: Partial<IOutput> | string): IOutput {
7075
return this.normalizeOutput(
71-
(typeof(expectedOutput) === "string")
72-
? {
73-
stdout: expectedOutput
74-
}
75-
: {
76-
stdout: [ expectedOutput.stdout ].flat().join("\n"),
77-
stderr: [ expectedOutput.stderr ].flat().join("\n")
78-
}
76+
typeof expectedOutput === "string"
77+
? {
78+
stdout: expectedOutput
79+
}
80+
: {
81+
stdout: [expectedOutput.stdout].flat().join("\n"),
82+
stderr: [expectedOutput.stderr].flat().join("\n")
83+
}
7984
);
8085
}
8186

8287
protected getDifference(actual: IOutput, expected: IOutput) {
8388
const filterObj = (sourceObj: IOutput, targetObj: IOutput) => {
8489
return {
85-
...(sourceObj.stdout !== targetObj.stdout)
86-
? { stdout: sourceObj.stdout }
87-
: {},
88-
...(sourceObj.stderr !== targetObj.stderr)
89-
? { stderr: sourceObj.stderr }
90-
: {},
91-
}
90+
...(sourceObj.stdout !== targetObj.stdout ? { stdout: sourceObj.stdout } : {}),
91+
...(sourceObj.stderr !== targetObj.stderr ? { stderr: sourceObj.stderr } : {})
92+
};
9293
};
9394
return {
9495
actual: filterObj(actual, expected),
9596
expected: filterObj(expected, actual)
96-
}
97+
};
9798
}
9899
}

packages/testing/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ new UnitTest("Throws error for division by zero")
3131
| :- | :- | :- |
3232
| `unit` &thinsp; `@rapidjs.org/testing-unit` | `UnitTest` | Unit testing ([Read Documentation](../@unit/README.md)) |
3333
| `http` &thinsp; `@rapidjs.org/testing-http` | `HTTPTest` | HTTP(S) testing ([Read Documentation](../@http/README.md)) |
34+
| `cli` &thinsp; `@rapidjs.org/testing-cli` | `CLITest` | CLI testing ([Read Documentation](../@cli/README.md)) |
3435

3536
## Test Cases
3637

packages/testing/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rapidjs.org/testing",
3-
"version": "0.1.1",
3+
"version": "0.1.2",
44
"description": "Context-sensitive, (a)sync-uniform testing framework for JavaScript and TypeScript.",
55
"author": "Thassilo Martin Schiepanski",
66
"homepage": "https://github.com/rapidjs-org/testing#readme",

0 commit comments

Comments
 (0)