testeranto 0.38.3 → 0.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -10
- package/dist/common/Features.js +85 -0
- package/dist/common/IBaseConfig.js +2 -0
- package/dist/common/Node.js +75 -0
- package/dist/common/NodeWriter.js +51 -0
- package/dist/common/Project.js +630 -0
- package/dist/common/Puppeteer.js +44 -0
- package/dist/common/Web.js +64 -0
- package/dist/common/core.js +387 -0
- package/dist/common/electron.js +44 -0
- package/dist/common/package.json +3 -0
- package/dist/common/preload.js +10 -0
- package/dist/common/tsconfig.common.tsbuildinfo +1 -0
- package/dist/{Features.js → module/Features.js} +10 -7
- package/dist/module/Node.js +70 -0
- package/dist/module/NodeWriter.js +45 -0
- package/dist/module/Project.js +600 -0
- package/dist/module/Puppeteer.js +39 -0
- package/dist/module/Report.js +186 -0
- package/dist/module/Web.js +59 -0
- package/dist/module/core.js +378 -0
- package/dist/module/electron.js +39 -0
- package/dist/module/package.json +3 -0
- package/dist/module/preload.js +8 -0
- package/dist/module/tsconfig.module.tsbuildinfo +1 -0
- package/dist/{Features.d.ts → types/Features.d.ts} +12 -9
- package/dist/types/IBaseConfig.d.ts +13 -0
- package/dist/types/Node.d.ts +12 -0
- package/dist/types/NodeWriter.d.ts +2 -0
- package/dist/types/Project.d.ts +46 -0
- package/dist/types/Puppeteer.d.ts +1 -0
- package/dist/types/Web.d.ts +12 -0
- package/dist/types/core.d.ts +213 -0
- package/dist/types/electron.d.ts +1 -0
- package/dist/types/preload.d.ts +1 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -0
- package/index.d.ts +19 -0
- package/package.json +73 -19
- package/postBuild.sh +11 -0
- package/prebuild.sh +1 -0
- package/src/Features.ts +34 -28
- package/src/IBaseConfig.ts +6 -13
- package/src/Node.ts +166 -0
- package/src/NodeWriter.ts +66 -0
- package/src/Project.ts +704 -437
- package/src/Report.tsx +365 -249
- package/src/Web.ts +151 -0
- package/src/core.ts +1307 -0
- package/src/electron.ts +48 -0
- package/src/preload.ts +11 -0
- package/tsconfig.common.json +35 -0
- package/tsconfig.json +2 -2
- package/tsconfig.module.json +35 -0
- package/tsconfig.types.json +36 -0
- package/yarn-error.log +3144 -0
- package/bin/testerantoRun.sh +0 -3
- package/bin/testerantoWatch.sh +0 -3
- package/dist/IBaseConfig.d.ts +0 -16
- package/dist/Project.d.ts +0 -57
- package/dist/Project.js +0 -391
- package/dist/index.d.mts +0 -204
- package/dist/index.mjs +0 -468
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/Collate.tsx +0 -0
- package/src/index.mts +0 -1173
- package/testerantoDemo.gif +0 -0
- package/testerantoDemo.mov +0 -0
- package/truffle-config.js +0 -124
- /package/dist/{IBaseConfig.js → module/IBaseConfig.js} +0 -0
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# testeranto
|
|
2
2
|
|
|
3
|
-

|
|
4
|
-
|
|
5
3
|
home: [adamwong246.github.io/testeranto](https://adamwong246.github.io/testeranto/)
|
|
6
4
|
|
|
7
5
|
source: [github.com/adamwong246/testeranto](https://github.com/adamwong246/testeranto)
|
|
@@ -22,11 +20,9 @@ If so, then testeranto might be the testing tool you have been looking for!
|
|
|
22
20
|
|
|
23
21
|
## about
|
|
24
22
|
|
|
25
|
-
Testeranto.ts an Acceptance Test Driven Development ([ATDD](https://en.wikipedia.org/wiki/Acceptance_test-driven_development)) framework. It focuses on
|
|
26
|
-
|
|
27
|
-
## 3 distinguishing features of testeranto
|
|
23
|
+
Testeranto.ts an Acceptance Test Driven Development ([ATDD](https://en.wikipedia.org/wiki/Acceptance_test-driven_development)) framework. It focuses on strongly-typed tests, specified in a gherkin-like syntax. Testeranto includes a framework to help write your tests, a test runner to schedule the tests and a reporter to display the results.
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
## 2 distinguishing features of testeranto
|
|
30
26
|
|
|
31
27
|
1. Rather than testing your code directly, Testeranto requires you wrap your code with a semantic interface which is based on TS type signatures. These interfaces can be shared and your code is now tested through the gherkin-ish directives provided by that interface.
|
|
32
28
|
|
|
@@ -44,10 +40,6 @@ Testeranto includes a test runner which bundles and executes your tests, taking
|
|
|
44
40
|
|
|
45
41
|
Testeranto includes a test reporter which displays the state of your code in a web app. ([see example](https://chromapdx.github.io/kokomoBay/report.html)) This reporter can also be run locally for the developer's convenience.
|
|
46
42
|
|
|
47
|
-
Testeranto can very feasibly be used to test any code- a ruby HTTP server, for example. While testeranto itself and it's test implementations are typescript, the subject of the test can be any stateful software.
|
|
48
|
-
|
|
49
|
-
Testeranto allows you to test the same code in multiple ways. You can test your unbundled TS in a unit-test fashion, and also bundle that same code, then testing it through a interface like puppeteer, fetch, curl, etc.
|
|
50
|
-
|
|
51
43
|
Testeranto exposes an extended gherkin syntax. You can use the given-when-then lingua-franca, AND you can also use an imperative `Check` which is a bit more flexible.
|
|
52
44
|
|
|
53
45
|
Rather than the traditional method of specifying tests in plain text, Testeranto tests and features are just TS, editable and type-checkable from [github's online editor](https://github.dev/ChromaPDX/kokomoBay)!
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DirectedGraph = exports.TesterantoFeatures = exports.TesterantoGraphDirectedAcyclic = exports.TesterantoGraphDirected = exports.TesterantoGraphUndirected = exports.BaseFeature = void 0;
|
|
7
|
+
const graphology_1 = __importDefault(require("graphology"));
|
|
8
|
+
/* @ts-ignore:next-line */
|
|
9
|
+
const { DirectedGraph, UndirectedGraph } = graphology_1.default;
|
|
10
|
+
exports.DirectedGraph = DirectedGraph;
|
|
11
|
+
class TesterantoGraph {
|
|
12
|
+
constructor(name) {
|
|
13
|
+
this.name = name;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
class BaseFeature {
|
|
17
|
+
constructor(name) {
|
|
18
|
+
this.name = name;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.BaseFeature = BaseFeature;
|
|
22
|
+
class TesterantoGraphUndirected {
|
|
23
|
+
constructor(name) {
|
|
24
|
+
this.name = name;
|
|
25
|
+
this.graph = new UndirectedGraph();
|
|
26
|
+
}
|
|
27
|
+
connect(a, b, relation) {
|
|
28
|
+
this.graph.mergeEdge(a, b, { type: relation });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.TesterantoGraphUndirected = TesterantoGraphUndirected;
|
|
32
|
+
class TesterantoGraphDirected {
|
|
33
|
+
constructor(name) {
|
|
34
|
+
this.name = name;
|
|
35
|
+
this.graph = new DirectedGraph();
|
|
36
|
+
}
|
|
37
|
+
connect(to, from, relation) {
|
|
38
|
+
this.graph.mergeEdge(to, from, { type: relation });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.TesterantoGraphDirected = TesterantoGraphDirected;
|
|
42
|
+
class TesterantoGraphDirectedAcyclic {
|
|
43
|
+
constructor(name) {
|
|
44
|
+
this.name = name;
|
|
45
|
+
this.graph = new DirectedGraph();
|
|
46
|
+
}
|
|
47
|
+
connect(to, from, relation) {
|
|
48
|
+
this.graph.mergeEdge(to, from, { type: relation });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.TesterantoGraphDirectedAcyclic = TesterantoGraphDirectedAcyclic;
|
|
52
|
+
class TesterantoFeatures {
|
|
53
|
+
constructor(features, graphs) {
|
|
54
|
+
this.features = features;
|
|
55
|
+
this.graphs = graphs;
|
|
56
|
+
}
|
|
57
|
+
networks() {
|
|
58
|
+
return [
|
|
59
|
+
...this.graphs.undirected.values(),
|
|
60
|
+
...this.graphs.directed.values(),
|
|
61
|
+
...this.graphs.dags.values(),
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
toObj() {
|
|
65
|
+
return {
|
|
66
|
+
features: Object.entries(this.features).map(([name, feature]) => {
|
|
67
|
+
return Object.assign(Object.assign({}, feature), { inNetworks: this.networks()
|
|
68
|
+
.filter((network) => {
|
|
69
|
+
return network.graph.hasNode(feature.name);
|
|
70
|
+
})
|
|
71
|
+
.map((network) => {
|
|
72
|
+
return {
|
|
73
|
+
network: network.name,
|
|
74
|
+
neighbors: network.graph.neighbors(feature.name),
|
|
75
|
+
};
|
|
76
|
+
}) });
|
|
77
|
+
}),
|
|
78
|
+
networks: this.networks().map((network) => {
|
|
79
|
+
return Object.assign({}, network);
|
|
80
|
+
}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.TesterantoFeatures = TesterantoFeatures;
|
|
85
|
+
exports.default = {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const core_js_1 = require("./core.js");
|
|
7
|
+
const core_js_2 = __importDefault(require("./core.js"));
|
|
8
|
+
const NodeWriter_js_1 = require("./NodeWriter.js");
|
|
9
|
+
exports.default = async (input, testSpecification, testImplementation, testInterface, testResourceRequirement = core_js_1.defaultTestResourceRequirement) => {
|
|
10
|
+
const mrt = new core_js_2.default(input, testSpecification, testImplementation, testInterface, testResourceRequirement, testInterface.assertioner || (async (t) => t), testInterface.beforeEach || async function (subject, initialValues, testResource) {
|
|
11
|
+
return subject;
|
|
12
|
+
}, testInterface.afterEach || (async (s) => s), testInterface.afterAll || ((store) => undefined), testInterface.butThen || (async (a) => a), testInterface.andWhen, testInterface.actionHandler ||
|
|
13
|
+
function (b) {
|
|
14
|
+
return b;
|
|
15
|
+
}, NodeWriter_js_1.NodeWriter);
|
|
16
|
+
const t = mrt[0];
|
|
17
|
+
const testResourceArg = process.argv[2] || `{}`;
|
|
18
|
+
try {
|
|
19
|
+
const partialTestResource = JSON.parse(testResourceArg);
|
|
20
|
+
if (testResourceRequirement.ports == 0) {
|
|
21
|
+
const failed = await t.receiveTestResourceConfig(partialTestResource);
|
|
22
|
+
// process.exit(failed ? 1 : 0);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
console.log("test configuration is incomplete", partialTestResource);
|
|
26
|
+
if (process.send) {
|
|
27
|
+
console.log("requesting test resources via IPC ...", testResourceRequirement);
|
|
28
|
+
/* @ts-ignore:next-line */
|
|
29
|
+
process.send({
|
|
30
|
+
type: "testeranto:hola",
|
|
31
|
+
data: {
|
|
32
|
+
requirement: Object.assign(Object.assign({}, testResourceRequirement), { name: partialTestResource.name })
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
console.log("awaiting test resources via IPC...");
|
|
36
|
+
process.on("message", async function (packet) {
|
|
37
|
+
console.log("message: ", packet);
|
|
38
|
+
const resourcesFromPm2 = packet.data.testResourceConfiguration;
|
|
39
|
+
const secondTestResource = Object.assign(Object.assign({ fs: "." }, JSON.parse(JSON.stringify(partialTestResource))), JSON.parse(JSON.stringify(resourcesFromPm2)));
|
|
40
|
+
console.log("secondTestResource", secondTestResource);
|
|
41
|
+
const failed = await t.receiveTestResourceConfig(secondTestResource);
|
|
42
|
+
/* @ts-ignore:next-line */
|
|
43
|
+
process.send({
|
|
44
|
+
type: "testeranto:adios",
|
|
45
|
+
data: {
|
|
46
|
+
testResourceConfiguration: t.test.testResourceConfiguration,
|
|
47
|
+
results: t.toObj(),
|
|
48
|
+
},
|
|
49
|
+
}, (err) => {
|
|
50
|
+
if (!err) {
|
|
51
|
+
// process.exit(failed ? 1 : 0);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.error(err);
|
|
55
|
+
// process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.log("Pass run-time test resources by STDIN", process.stdin);
|
|
62
|
+
process.stdin.on("data", async (data) => {
|
|
63
|
+
console.log("data: ", data);
|
|
64
|
+
const resourcesFromStdin = JSON.parse(data.toString());
|
|
65
|
+
const secondTestResource = Object.assign(Object.assign({}, JSON.parse(JSON.stringify(resourcesFromStdin))), JSON.parse(JSON.stringify(partialTestResource)));
|
|
66
|
+
await t.receiveTestResourceConfig(secondTestResource);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
console.error(e);
|
|
73
|
+
process.exit(-1);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.NodeWriter = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fPaths = [];
|
|
10
|
+
exports.NodeWriter = {
|
|
11
|
+
createWriteStream: (filepath) => {
|
|
12
|
+
return fs_1.default.createWriteStream(filepath);
|
|
13
|
+
},
|
|
14
|
+
writeFileSync: (fp, contents) => {
|
|
15
|
+
fs_1.default.writeFileSync(fp, contents);
|
|
16
|
+
},
|
|
17
|
+
mkdirSync: async (fp) => {
|
|
18
|
+
await fs_1.default.mkdirSync(fp, { recursive: true });
|
|
19
|
+
},
|
|
20
|
+
testArtiFactoryfileWriter: (tLog) => (fPath, value) => {
|
|
21
|
+
tLog("testArtiFactory =>", fPath);
|
|
22
|
+
const cleanPath = path_1.default.resolve(fPath);
|
|
23
|
+
fPaths.push(cleanPath.replace(process.cwd(), ``));
|
|
24
|
+
const targetDir = cleanPath.split("/").slice(0, -1).join("/");
|
|
25
|
+
fs_1.default.mkdir(targetDir, { recursive: true }, async (error) => {
|
|
26
|
+
if (error) {
|
|
27
|
+
console.error(`❗️testArtiFactory failed`, targetDir, error);
|
|
28
|
+
}
|
|
29
|
+
fs_1.default.writeFileSync(path_1.default.resolve(targetDir.split("/").slice(0, -1).join("/"), "manifest"), fPaths.join(`\n`), {
|
|
30
|
+
encoding: "utf-8",
|
|
31
|
+
});
|
|
32
|
+
if (Buffer.isBuffer(value)) {
|
|
33
|
+
fs_1.default.writeFileSync(fPath, value, "binary");
|
|
34
|
+
}
|
|
35
|
+
else if (`string` === typeof value) {
|
|
36
|
+
fs_1.default.writeFileSync(fPath, value.toString(), {
|
|
37
|
+
encoding: "utf-8",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
/* @ts-ignore:next-line */
|
|
42
|
+
const pipeStream = value;
|
|
43
|
+
const myFile = fs_1.default.createWriteStream(fPath);
|
|
44
|
+
pipeStream.pipe(myFile);
|
|
45
|
+
pipeStream.on("close", () => {
|
|
46
|
+
myFile.close();
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
};
|