testeranto 0.16.31 → 0.21.0

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "testeranto",
3
3
  "description": "teeny tiny tightly-typed typescript tests",
4
- "version": "0.16.31",
4
+ "version": "0.21.0",
5
5
  "type": "module",
6
6
  "types": "./src/index.d.mts",
7
7
  "main": "./src/index.mjs",
@@ -21,6 +21,7 @@
21
21
  },
22
22
  "scripts": {
23
23
  "build": "tsc",
24
+ "dev": "tsc --watch",
24
25
  "bundle:reporter": "esbuild ./src/Report.tsx --bundle --outfile=./dist/reporter.js",
25
26
  "simpleserver": "cd dist && python -m SimpleHTTPServer 8080",
26
27
  "clean:dist": "rm -rf ./dist/results && rm -rf ./dist/tests && rm -f ./dist/reporter.css && rm -f ./dist/reporter.js && rm -f ./dist/*.jpg ",
package/src/index.d.mts CHANGED
@@ -1,12 +1,17 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import { PassThrough } from 'stream';
2
4
  declare const DirectedGraph: any, UndirectedGraph: any;
3
- export declare class BaseFeature {
5
+ declare type ITTestResource = {
6
+ "ports": number[];
7
+ };
8
+ declare abstract class TesterantoGraph {
4
9
  name: string;
10
+ abstract graph: any;
5
11
  constructor(name: string);
6
12
  }
7
- declare abstract class TesterantoGraph {
13
+ export declare class BaseFeature {
8
14
  name: string;
9
- abstract graph: any;
10
15
  constructor(name: string);
11
16
  }
12
17
  export declare class TesterantoGraphUndirected implements TesterantoGraph {
@@ -63,9 +68,6 @@ export declare class TesterantoFeatures {
63
68
  export declare type ITTestResourceRequirement = {
64
69
  "ports": number;
65
70
  };
66
- declare type ITTestResource = {
67
- "ports": number[];
68
- };
69
71
  export declare type IT_FeatureNetwork = {
70
72
  name: string;
71
73
  };
@@ -79,7 +81,7 @@ export declare type IT = {
79
81
  export declare type ITestJob = {
80
82
  toObj(): object;
81
83
  test: IT;
82
- runner: (testResource: any) => Promise<boolean>;
84
+ runner: (testResource: any, artificer: ITestArtificer) => Promise<boolean>;
83
85
  testResource: ITTestResourceRequirement;
84
86
  };
85
87
  export declare type ITestResults = Promise<{
@@ -125,10 +127,6 @@ export declare type ITestImplementation<IState, ISelection, IWhenShape, IThenSha
125
127
  [K in keyof ITestShape["checks"]]: (...Ic: ITestShape["checks"][K]) => IState;
126
128
  };
127
129
  };
128
- declare class TestArtifact {
129
- binary: Buffer | string;
130
- constructor(binary: any);
131
- }
132
130
  export declare abstract class BaseSuite<IInput, ISubject, IStore, ISelection, IThenShape, ITestShape extends ITTestShape, IFeatureShape> {
133
131
  name: string;
134
132
  givens: BaseGiven<ISubject, IStore, ISelection, IThenShape, IFeatureShape>[];
@@ -138,7 +136,6 @@ export declare abstract class BaseSuite<IInput, ISubject, IStore, ISelection, IT
138
136
  fails: BaseGiven<ISubject, IStore, ISelection, IThenShape, IFeatureShape>[];
139
137
  testResourceConfiguration: ITTestResource;
140
138
  constructor(name: string, givens?: BaseGiven<ISubject, IStore, ISelection, IThenShape, IFeatureShape>[], checks?: BaseCheck<ISubject, IStore, ISelection, IThenShape, ITestShape, IFeatureShape>[]);
141
- aborter(): Promise<void>;
142
139
  toObj(): {
143
140
  name: string;
144
141
  givens: {
@@ -153,13 +150,12 @@ export declare abstract class BaseSuite<IInput, ISubject, IStore, ISelection, IT
153
150
  }[];
154
151
  errors: Error;
155
152
  features: (keyof IFeatureShape)[];
156
- testArtifacts: Record<string, any[]>;
157
153
  }[];
158
154
  fails: BaseGiven<ISubject, IStore, ISelection, IThenShape, IFeatureShape>[];
159
155
  };
160
- setup(s: IInput): Promise<ISubject>;
156
+ setup(s: IInput, artifactory: ITestArtificer): Promise<ISubject>;
161
157
  test(t: IThenShape): unknown;
162
- run(input: any, testResourceConfiguration: ITTestResource): Promise<boolean>;
158
+ run(input: any, testResourceConfiguration: ITTestResource, artifactory: IHyperTestArtificer): Promise<boolean>;
163
159
  }
164
160
  export declare abstract class BaseGiven<ISubject, IStore, ISelection, IThenShape, IFeatureShape> {
165
161
  name: string;
@@ -169,8 +165,9 @@ export declare abstract class BaseGiven<ISubject, IStore, ISelection, IThenShape
169
165
  error: Error;
170
166
  abort: boolean;
171
167
  store: IStore;
172
- testArtifacts: Record<string, any[]>;
168
+ recommendedFsPath: string;
173
169
  constructor(name: string, features: (keyof IFeatureShape)[], whens: BaseWhen<IStore, ISelection, IThenShape>[], thens: BaseThen<ISelection, IStore, IThenShape>[]);
170
+ afterAll(store: IStore, artifactory: ITestArtificer): void;
174
171
  toObj(): {
175
172
  name: string;
176
173
  whens: {
@@ -183,16 +180,11 @@ export declare abstract class BaseGiven<ISubject, IStore, ISelection, IThenShape
183
180
  }[];
184
181
  errors: Error;
185
182
  features: (keyof IFeatureShape)[];
186
- testArtifacts: Record<string, any[]>;
187
- };
188
- abstract givenThat(subject: ISubject, testResourceConfiguration?: any): Promise<IStore>;
189
- saveTestArtifact(k: string, testArtifact: TestArtifact): void;
190
- artifactSaver: {
191
- png: (testArtifact: any) => void;
192
183
  };
193
- aborter(ndx: number): Promise<unknown>;
194
- afterEach(store: IStore, ndx: number, cb: any): Promise<unknown>;
195
- give(subject: ISubject, index: number, testResourceConfiguration: any, tester: any): Promise<IStore>;
184
+ abstract givenThat(subject: ISubject, testResourceConfiguration: any, artifactory: ITestArtificer): Promise<IStore>;
185
+ aborter(ndx: number, artifactory: ITestArtificer): Promise<unknown>;
186
+ afterEach(store: IStore, ndx: number, artifactory: ITestArtificer): Promise<unknown>;
187
+ give(subject: ISubject, index: number, testResourceConfiguration: any, tester: any, artifactory: ITestArtificer): Promise<IStore>;
196
188
  }
197
189
  export declare abstract class BaseWhen<IStore, ISelection, IThenShape> {
198
190
  name: string;
@@ -233,9 +225,9 @@ export declare abstract class BaseCheck<ISubject, IStore, ISelection, IThenShape
233
225
  [K in keyof ITestShape["thens"]]: (p: any, tc: any) => BaseThen<ISelection, IStore, IThenShape>;
234
226
  };
235
227
  constructor(name: string, features: (keyof IFeatureShape)[], checkCB: (whens: any, thens: any) => any, whens: any, thens: any);
236
- abstract checkThat(subject: ISubject, testResourceConfiguration?: any): Promise<IStore>;
228
+ abstract checkThat(subject: ISubject, testResourceConfiguration: any, artifactory: ITestArtificer): Promise<IStore>;
237
229
  afterEach(store: IStore, ndx: number, cb?: any): Promise<unknown>;
238
- check(subject: ISubject, ndx: number, testResourceConfiguration: any, tester: any): Promise<void>;
230
+ check(subject: ISubject, ndx: number, testResourceConfiguration: any, tester: any, artifactory: ITestArtificer): Promise<void>;
239
231
  }
240
232
  export declare abstract class TesterantoLevelZero<IInput, ISubject, IStore, ISelection, SuiteExtensions, GivenExtensions, WhenExtensions, ThenExtensions, CheckExtensions, IThenShape, IFeatureShape> {
241
233
  readonly cc: IStore;
@@ -265,13 +257,16 @@ export declare abstract class TesterantoLevelOne<ITestShape extends ITTestShape,
265
257
  [K in keyof ITestShape["checks"]]: (name: string, features: (keyof IFeatureShape)[], cbz: (...any: any[]) => Promise<void>) => any;
266
258
  }) => BaseSuite<IInput, ISubject, IStore, ISelection, IThenShape, ITestShape, IFeatureShape>[], input: IInput, suiteKlasser: (name: string, givens: BaseGiven<ISubject, IStore, ISelection, IThenShape, IFeatureShape>[], checks: BaseCheck<ISubject, IStore, ISelection, IThenShape, ITestShape, IFeatureShape>[]) => BaseSuite<IInput, ISubject, IStore, ISelection, IThenShape, ITestShape, IFeatureShape>, givenKlasser: (n: any, f: any, w: any, t: any, z?: any) => BaseGiven<ISubject, IStore, ISelection, IThenShape, IFeatureShape>, whenKlasser: (s: any, o: any) => BaseWhen<IStore, ISelection, IThenShape>, thenKlasser: (s: any, o: any) => BaseThen<IStore, ISelection, IThenShape>, checkKlasser: (n: any, f: any, cb: any, w: any, t: any) => BaseCheck<ISubject, IStore, ISelection, IThenShape, ITestShape, IFeatureShape>, testResource: any);
267
259
  }
260
+ declare type ITestArtificer = (key: string, data: string | Buffer | PassThrough) => void;
261
+ declare type IHyperTestArtificer = (name: string) => ITestArtificer;
268
262
  export declare const Testeranto: <TestShape extends ITTestShape, Input, Subject, Store, Selection_1, WhenShape, ThenShape, InitialStateShape, IFeatureShape>(input: Input, testSpecification: ITestSpecification<TestShape, IFeatureShape>, testImplementation: any, testResource: ITTestResourceRequirement, testInterface: {
269
263
  actionHandler?: ((b: (...any: any[]) => any) => any) | undefined;
270
- afterEach?: ((store: Store, ndx: number, cb: any) => unknown) | undefined;
271
264
  andWhen: (store: Store, actioner: any, testResource: ITTestResource) => Promise<Selection_1>;
272
- assertioner?: ((t: ThenShape) => any) | undefined;
273
- beforeAll?: ((input: Input) => Promise<Subject>) | undefined;
274
- beforeEach?: ((subject: Subject, initialValues: any, testResource: ITTestResource) => Promise<Store>) | undefined;
275
265
  butThen?: ((store: Store, callback: any, testResource: ITTestResource) => Promise<Selection_1>) | undefined;
266
+ assertioner?: ((t: ThenShape) => any) | undefined;
267
+ afterAll?: ((store: Store, artificer: ITestArtificer) => any) | undefined;
268
+ afterEach?: ((store: Store, ndx: number, artificer: ITestArtificer) => Promise<unknown>) | undefined;
269
+ beforeAll?: ((input: Input, artificer: ITestArtificer) => Promise<Subject>) | undefined;
270
+ beforeEach?: ((subject: Subject, initialValues: any, testResource: ITTestResource, artificer: ITestArtificer) => Promise<Store>) | undefined;
276
271
  }) => Promise<void>;
277
272
  export {};
package/src/index.mjs CHANGED
@@ -1,16 +1,20 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
1
3
  import pkg from 'graphology';
2
4
  /* @ts-ignore:next-line */
3
5
  const { DirectedGraph, UndirectedGraph } = pkg;
4
- export class BaseFeature {
6
+ class TesterantoGraph {
5
7
  constructor(name) {
6
8
  this.name = name;
7
9
  }
8
10
  }
9
- class TesterantoGraph {
11
+ ;
12
+ export class BaseFeature {
10
13
  constructor(name) {
11
14
  this.name = name;
12
15
  }
13
16
  }
17
+ ;
14
18
  export class TesterantoGraphUndirected {
15
19
  constructor(name) {
16
20
  this.name = name;
@@ -68,12 +72,7 @@ export class TesterantoFeatures {
68
72
  };
69
73
  }
70
74
  }
71
- const testOutPath = "./dist/results/";
72
- class TestArtifact {
73
- constructor(binary) {
74
- this.binary = binary;
75
- }
76
- }
75
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////
77
76
  export class BaseSuite {
78
77
  constructor(name, givens = [], checks = []) {
79
78
  this.name = name;
@@ -81,10 +80,6 @@ export class BaseSuite {
81
80
  this.checks = checks;
82
81
  this.fails = [];
83
82
  }
84
- async aborter() {
85
- this.aborted = true;
86
- await Promise.all((this.givens || []).map((g, ndx) => g.aborter(ndx)));
87
- }
88
83
  toObj() {
89
84
  return {
90
85
  name: this.name,
@@ -92,20 +87,23 @@ export class BaseSuite {
92
87
  fails: this.fails
93
88
  };
94
89
  }
95
- setup(s) {
90
+ setup(s, artifactory) {
96
91
  return new Promise((res) => res(s));
97
92
  }
98
93
  test(t) {
99
94
  return t;
100
95
  }
101
- async run(input, testResourceConfiguration) {
102
- this.testResourceConfiguration = Object.keys(testResourceConfiguration).length ? testResourceConfiguration : { ports: [] };
103
- const subject = await this.setup(input);
96
+ async run(input, testResourceConfiguration, artifactory) {
97
+ this.testResourceConfiguration =
98
+ Object.keys(testResourceConfiguration).length ?
99
+ testResourceConfiguration :
100
+ { ports: [] };
101
+ const subject = await this.setup(input, artifactory('-1'));
104
102
  console.log("\nSuite:", this.name, testResourceConfiguration);
105
103
  for (const [ndx, giver] of this.givens.entries()) {
106
104
  try {
107
105
  if (!this.aborted) {
108
- this.store = await giver.give(subject, ndx, testResourceConfiguration, this.test);
106
+ this.store = await giver.give(subject, ndx, testResourceConfiguration, this.test, artifactory(ndx.toString()));
109
107
  }
110
108
  }
111
109
  catch (e) {
@@ -115,22 +113,28 @@ export class BaseSuite {
115
113
  }
116
114
  }
117
115
  for (const [ndx, thater] of this.checks.entries()) {
118
- await thater.check(subject, ndx, testResourceConfiguration, this.test);
116
+ await thater.check(subject, ndx, testResourceConfiguration, this.test, artifactory('`checkidk'));
117
+ }
118
+ // @TODO fix me
119
+ for (const [ndx, giver] of this.givens.entries()) {
120
+ giver.afterAll(this.store, artifactory);
119
121
  }
122
+ ////////////////
120
123
  return true;
121
124
  }
122
125
  }
126
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////
123
127
  export class BaseGiven {
124
128
  constructor(name, features, whens, thens) {
125
- this.artifactSaver = {
126
- png: (testArtifact) => this.saveTestArtifact('afterEach', new TestArtifact(testArtifact))
127
- };
128
129
  this.name = name;
129
130
  this.features = features;
130
131
  this.whens = whens;
131
132
  this.thens = thens;
132
- this.testArtifacts = {};
133
133
  }
134
+ afterAll(store, artifactory) {
135
+ return;
136
+ }
137
+ ;
134
138
  toObj() {
135
139
  return {
136
140
  name: this.name,
@@ -138,33 +142,26 @@ export class BaseGiven {
138
142
  thens: this.thens.map((t) => t.toObj()),
139
143
  errors: this.error,
140
144
  features: this.features,
141
- testArtifacts: this.testArtifacts,
142
145
  };
143
146
  }
144
- saveTestArtifact(k, testArtifact) {
145
- if (!this.testArtifacts[k]) {
146
- this.testArtifacts[k] = [];
147
- }
148
- this.testArtifacts[k].push(testArtifact);
149
- }
150
- async aborter(ndx) {
147
+ async aborter(ndx, artifactory) {
151
148
  this.abort = true;
152
149
  return Promise.all([
153
150
  ...this.whens.map((w, ndx) => new Promise((res) => res(w.aborter()))),
154
151
  ...this.thens.map((t, ndx) => new Promise((res) => res(t.aborter()))),
155
152
  ])
156
153
  .then(async () => {
157
- return await this.afterEach(this.store, ndx, this.artifactSaver);
154
+ return await this.afterEach(this.store, ndx, artifactory);
158
155
  });
159
156
  }
160
- async afterEach(store, ndx, cb) {
157
+ async afterEach(store, ndx, artifactory) {
161
158
  return;
162
159
  }
163
- async give(subject, index, testResourceConfiguration, tester) {
160
+ async give(subject, index, testResourceConfiguration, tester, artifactory) {
164
161
  console.log(`\n Given: ${this.name}`);
165
162
  try {
166
163
  if (!this.abort) {
167
- this.store = await this.givenThat(subject, testResourceConfiguration);
164
+ this.store = await this.givenThat(subject, testResourceConfiguration, artifactory);
168
165
  }
169
166
  for (const whenStep of this.whens) {
170
167
  await whenStep.test(this.store, testResourceConfiguration);
@@ -181,7 +178,8 @@ export class BaseGiven {
181
178
  }
182
179
  finally {
183
180
  try {
184
- await this.afterEach(this.store, index, this.artifactSaver);
181
+ /* @ts-ignore:next-line */
182
+ this.testArtifacts = await this.afterEach(this.store, index, artifactory);
185
183
  }
186
184
  catch (_a) {
187
185
  console.error("afterEach failed! no error will be recorded!");
@@ -257,9 +255,9 @@ export class BaseCheck {
257
255
  async afterEach(store, ndx, cb) {
258
256
  return;
259
257
  }
260
- async check(subject, ndx, testResourceConfiguration, tester) {
258
+ async check(subject, ndx, testResourceConfiguration, tester, artifactory) {
261
259
  console.log(`\n Check: ${this.name}`);
262
- const store = await this.checkThat(subject, testResourceConfiguration);
260
+ const store = await this.checkThat(subject, testResourceConfiguration, artifactory);
263
261
  await this.checkCB((Object.entries(this.whens)
264
262
  .reduce((a, [key, when]) => {
265
263
  a[key] = async (payload) => {
@@ -278,6 +276,7 @@ export class BaseCheck {
278
276
  return;
279
277
  }
280
278
  }
279
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////
281
280
  export class TesterantoLevelZero {
282
281
  constructor(cc, suitesOverrides, givenOverides, whenOverides, thenOverides, checkOverides) {
283
282
  this.cc = cc;
@@ -354,14 +353,36 @@ export class TesterantoLevelOne {
354
353
  toObj: () => {
355
354
  return suite.toObj();
356
355
  },
357
- runner: async (allocatedPorts) => {
358
- return suite.run(input, { ports: allocatedPorts });
356
+ runner: async (allocatedPorts, artifactory) => {
357
+ return suite.run(input, { ports: allocatedPorts }, artifactory);
359
358
  },
360
359
  };
361
360
  });
362
361
  return toReturn;
363
362
  }
364
363
  }
364
+ const testArtiFactoryfileWriter = (fsPath) => (gindex) => (key, value) => {
365
+ const fPath = `${fsPath}/${gindex}/${key}`;
366
+ const cleanPath = path.resolve(fPath);
367
+ const targetDir = cleanPath.split('/').slice(0, -1).join('/');
368
+ fs.mkdir(targetDir, { recursive: true }, async (error) => {
369
+ if (error) {
370
+ console.error(`❗️testArtiFactory failed`, targetDir, error);
371
+ }
372
+ if (Buffer.isBuffer(value) || (`string` === (typeof value))) {
373
+ fs.writeFile(fPath, value.toString(), (error) => {
374
+ if (error) {
375
+ console.error(`❗️testArtiFactory failed`, fPath, error);
376
+ }
377
+ });
378
+ }
379
+ else {
380
+ const pipeStream = value;
381
+ var myFile = fs.createWriteStream(fPath);
382
+ pipeStream.pipe(myFile);
383
+ }
384
+ });
385
+ };
365
386
  export const Testeranto = async (input, testSpecification, testImplementation,
366
387
  // testImplementation: ITestImplementation<
367
388
  // InitialStateShape,
@@ -382,13 +403,14 @@ testResource, testInterface) => {
382
403
  return subject;
383
404
  };
384
405
  const afterEach = testInterface.afterEach || (async (s) => s);
406
+ const afterAll = testInterface.afterAll || ((store) => undefined);
385
407
  class MrT extends TesterantoLevelOne {
386
408
  constructor() {
387
409
  super(testImplementation,
388
410
  /* @ts-ignore:next-line */
389
411
  testSpecification, input, (class extends BaseSuite {
390
- async setup(s) {
391
- return beforeAll(s);
412
+ async setup(s, artifactory) {
413
+ return beforeAll(s, artifactory);
392
414
  }
393
415
  test(t) {
394
416
  return assertioner(t);
@@ -398,11 +420,14 @@ testResource, testInterface) => {
398
420
  super(name, features, whens, thens);
399
421
  this.initialValues = initialValues;
400
422
  }
401
- async givenThat(subject, testResource) {
402
- return beforeEach(subject, this.initialValues, testResource);
423
+ async givenThat(subject, testResource, artifactory) {
424
+ return beforeEach(subject, this.initialValues, testResource, artifactory);
425
+ }
426
+ afterEach(store, ndx, artifactory) {
427
+ return new Promise((res) => res(afterEach(store, ndx, artifactory)));
403
428
  }
404
- afterEach(store, ndx, cb) {
405
- return new Promise((res) => res(afterEach(store, ndx, cb)));
429
+ afterAll(store, artifactory) {
430
+ return afterAll(store, artifactory);
406
431
  }
407
432
  }, class When extends BaseWhen {
408
433
  constructor(name, actioner, payload) {
@@ -426,11 +451,11 @@ testResource, testInterface) => {
426
451
  super(name, features, checkCallback, whens, thens);
427
452
  this.initialValues = initialValues;
428
453
  }
429
- async checkThat(subject, testResource) {
430
- return beforeEach(subject, this.initialValues, testResource);
454
+ async checkThat(subject, testResource, artifactory) {
455
+ return beforeEach(subject, this.initialValues, testResource, artifactory);
431
456
  }
432
- afterEach(store, ndx, cb) {
433
- return new Promise((res) => res(afterEach(store, ndx, cb)));
457
+ afterEach(store, ndx, artifactory) {
458
+ return new Promise((res) => res(afterEach(store, ndx, artifactory)));
434
459
  }
435
460
  }, testResource);
436
461
  }
@@ -446,7 +471,7 @@ testResource, testInterface) => {
446
471
  });
447
472
  console.log("awaiting test resources from mothership...");
448
473
  process.on('message', async function (packet) {
449
- await mrt[0].runner(packet.data.goWithTestResources);
474
+ await mrt[0].runner(packet.data.goWithTestResources, testArtiFactoryfileWriter(packet.data.recommendedFsPath));
450
475
  /* @ts-ignore:next-line */
451
476
  process.send({
452
477
  type: 'testeranto:adios',
@@ -461,7 +486,7 @@ testResource, testInterface) => {
461
486
  else {
462
487
  console.error(`❗️`, err);
463
488
  }
464
- process.exit(0); // :-)
489
+ // process.exit(0); // :-)
465
490
  });
466
491
  });
467
492
  process.on('SIGINT', function () {