testeranto 0.90.0 → 0.100.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.
Files changed (133) hide show
  1. package/bundle.js +4 -7
  2. package/dist/common/src/Node.js +5 -3
  3. package/dist/common/src/PM/main.js +254 -126
  4. package/dist/common/src/PM/node.js +20 -5
  5. package/dist/common/src/PM/web.js +19 -4
  6. package/dist/common/src/SubPackages/puppeteer.js +1 -1
  7. package/dist/common/src/SubPackages/react/jsx/index.js +14 -6
  8. package/dist/common/src/SubPackages/react/jsx/node.js +2 -2
  9. package/dist/common/src/SubPackages/react-dom/component/web.js +13 -39
  10. package/dist/common/src/SubPackages/react-test-renderer/component/interface.js +2 -10
  11. package/dist/common/src/Web.js +25 -21
  12. package/dist/common/src/cli.js +439 -0
  13. package/dist/common/src/cli2.js +144 -0
  14. package/dist/common/src/esbuildConfigs/inputFilesPlugin.js +18 -8
  15. package/dist/common/src/esbuildConfigs/node.js +1 -4
  16. package/dist/common/src/esbuildConfigs/web.js +1 -1
  17. package/dist/common/src/lib/abstractBase.js +31 -263
  18. package/dist/common/src/lib/basebuilder.js +1 -11
  19. package/dist/common/src/lib/classBuilder.js +1 -1
  20. package/dist/common/src/lib/core.js +8 -28
  21. package/dist/common/src/lib/types.js +1 -0
  22. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  23. package/dist/module/src/Node.js +5 -3
  24. package/dist/module/src/PM/main.js +254 -126
  25. package/dist/module/src/PM/node.js +20 -5
  26. package/dist/module/src/PM/web.js +19 -4
  27. package/dist/module/src/SubPackages/puppeteer.js +1 -1
  28. package/dist/module/src/SubPackages/react/jsx/index.js +14 -6
  29. package/dist/module/src/SubPackages/react/jsx/node.js +2 -2
  30. package/dist/module/src/SubPackages/react-dom/component/web.js +13 -39
  31. package/dist/module/src/SubPackages/react-test-renderer/component/interface.js +2 -10
  32. package/dist/module/src/Web.js +25 -21
  33. package/dist/module/src/cli.js +411 -0
  34. package/dist/module/src/cli2.js +116 -0
  35. package/dist/module/src/esbuildConfigs/inputFilesPlugin.js +18 -8
  36. package/dist/module/src/esbuildConfigs/node.js +1 -4
  37. package/dist/module/src/esbuildConfigs/web.js +1 -1
  38. package/dist/module/src/lib/abstractBase.js +31 -263
  39. package/dist/module/src/lib/basebuilder.js +1 -11
  40. package/dist/module/src/lib/classBuilder.js +1 -1
  41. package/dist/module/src/lib/core.js +8 -28
  42. package/dist/module/src/lib/types.js +1 -0
  43. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  44. package/dist/prebuild/cli.mjs +1491 -0
  45. package/dist/prebuild/{run-tests.mjs → cli2.mjs} +223 -212
  46. package/dist/types/src/Node.d.ts +6 -3
  47. package/dist/types/src/PM/index.d.ts +10 -2
  48. package/dist/types/src/PM/main.d.ts +14 -7
  49. package/dist/types/src/PM/node.d.ts +9 -2
  50. package/dist/types/src/PM/web.d.ts +9 -3
  51. package/dist/types/src/SubPackages/puppeteer.d.ts +1 -1
  52. package/dist/types/src/SubPackages/react/component/node.d.ts +1 -1
  53. package/dist/types/src/SubPackages/react/component/web.d.ts +1 -1
  54. package/dist/types/src/SubPackages/react/jsx/node.d.ts +3 -3
  55. package/dist/types/src/SubPackages/react/jsx/web.d.ts +2 -2
  56. package/dist/types/src/SubPackages/react-dom/component/node.d.ts +2 -2
  57. package/dist/types/src/SubPackages/react-dom/component/web.d.ts +1 -1
  58. package/dist/types/src/SubPackages/react-dom/jsx/node.d.ts +1 -1
  59. package/dist/types/src/SubPackages/react-dom/jsx/web.d.ts +2 -2
  60. package/dist/types/src/SubPackages/react-test-renderer/MemoExoticComponent/node.d.ts +2 -2
  61. package/dist/types/src/SubPackages/react-test-renderer/component/interface.d.ts +1 -1
  62. package/dist/types/src/SubPackages/react-test-renderer/component/node.d.ts +2 -2
  63. package/dist/types/src/SubPackages/react-test-renderer/component/web.d.ts +2 -2
  64. package/dist/types/src/SubPackages/react-test-renderer/fc/node.d.ts +2 -2
  65. package/dist/types/src/SubPackages/react-test-renderer/fc/web.d.ts +2 -2
  66. package/dist/types/src/SubPackages/react-test-renderer/jsx/node.d.ts +3 -2
  67. package/dist/types/src/SubPackages/react-test-renderer/jsx/web.d.ts +2 -2
  68. package/dist/types/src/SubPackages/react-test-renderer/jsx-promised/node.d.ts +2 -2
  69. package/dist/types/src/SubPackages/react-test-renderer/jsx-promised/web.d.ts +2 -2
  70. package/dist/types/src/Types.d.ts +60 -21
  71. package/dist/types/src/Web.d.ts +3 -3
  72. package/dist/types/src/lib/abstractBase.d.ts +6 -2
  73. package/dist/types/src/lib/core.d.ts +3 -3
  74. package/dist/types/src/lib/index.d.ts +1 -1
  75. package/dist/types/src/lib/types.d.ts +6 -30
  76. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  77. package/package.json +23 -20
  78. package/src/Node.ts +6 -3
  79. package/src/PM/index.ts +12 -8
  80. package/src/PM/main.ts +331 -165
  81. package/src/PM/node.ts +42 -7
  82. package/src/PM/web.ts +33 -5
  83. package/src/SubPackages/puppeteer.ts +1 -1
  84. package/src/SubPackages/react/jsx/index.ts +15 -7
  85. package/src/SubPackages/react/jsx/node.ts +18 -6
  86. package/src/SubPackages/react-dom/component/web.ts +28 -51
  87. package/src/SubPackages/react-test-renderer/component/interface.ts +4 -11
  88. package/src/SubPackages/react-test-renderer/jsx/node.ts +16 -1
  89. package/src/Types.ts +362 -114
  90. package/src/Web.ts +45 -23
  91. package/src/cli.ts +535 -0
  92. package/src/cli2.ts +157 -0
  93. package/src/esbuildConfigs/inputFilesPlugin.ts +27 -9
  94. package/src/esbuildConfigs/node.ts +4 -7
  95. package/src/esbuildConfigs/web.ts +4 -3
  96. package/src/lib/abstractBase.ts +84 -291
  97. package/src/lib/basebuilder.ts +1 -12
  98. package/src/lib/classBuilder.ts +2 -1
  99. package/src/lib/core.ts +17 -29
  100. package/src/lib/types.ts +5 -177
  101. package/dist/common/src/Aider.js +0 -143
  102. package/dist/common/src/Project.js +0 -225
  103. package/dist/common/src/Puppeteer.js +0 -113
  104. package/dist/common/src/build-tests.js +0 -39
  105. package/dist/common/src/esbuildConfigs/features.js +0 -14
  106. package/dist/common/src/esbuildConfigs/report.js +0 -14
  107. package/dist/common/src/esbuildConfigs/tests.js +0 -13
  108. package/dist/common/src/run-tests.js +0 -39
  109. package/dist/module/src/Aider.js +0 -136
  110. package/dist/module/src/Project.js +0 -218
  111. package/dist/module/src/Puppeteer.js +0 -108
  112. package/dist/module/src/build-tests.js +0 -11
  113. package/dist/module/src/esbuildConfigs/features.js +0 -12
  114. package/dist/module/src/esbuildConfigs/report.js +0 -14
  115. package/dist/module/src/esbuildConfigs/tests.js +0 -11
  116. package/dist/module/src/run-tests.js +0 -11
  117. package/dist/prebuild/build-tests.mjs +0 -552
  118. package/dist/types/src/Aider.d.ts +0 -1
  119. package/dist/types/src/Project.d.ts +0 -12
  120. package/dist/types/src/Puppeteer.d.ts +0 -2
  121. package/dist/types/src/esbuildConfigs/features.d.ts +0 -4
  122. package/dist/types/src/esbuildConfigs/report.d.ts +0 -0
  123. package/dist/types/src/esbuildConfigs/tests.d.ts +0 -4
  124. package/src/Aider.ts +0 -168
  125. package/src/Project.ts +0 -291
  126. package/src/Puppeteer.ts +0 -145
  127. package/src/build-tests.ts +0 -12
  128. package/src/esbuildConfigs/features.ts +0 -17
  129. package/src/esbuildConfigs/report.ts +0 -15
  130. package/src/esbuildConfigs/tests.ts +0 -14
  131. package/src/run-tests.ts +0 -12
  132. /package/dist/types/src/{build-tests.d.ts → cli.d.ts} +0 -0
  133. /package/dist/types/src/{run-tests.d.ts → cli2.d.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import Testeranto from "../Node.js";
3
3
  export default (testInput, testSpecifications, testImplementations, testInterface) => {
4
- return Testeranto(testInput, testSpecifications, testImplementations, Object.assign({ beforeAll(x) {
4
+ return Testeranto(testInput, testSpecifications, testImplementations, Object.assign({ beforeAll: (x) => {
5
5
  // process.parentPort.postMessage(
6
6
  // `/docs/web/src/ClassicalComponent/test.html`
7
7
  // );
@@ -6,14 +6,22 @@ export const testInterface = {
6
6
  // // resolve(x());
7
7
  // // });
8
8
  // },
9
- beforeEach: async (subject, initializer, artificer) => {
9
+ // beforeEach: async (subject, initializer, artificer): Promise<IStore> => {
10
+ // return new Promise((resolve, rej) => {
11
+ // resolve(React.createElement(subject));
12
+ // });
13
+ // },
14
+ andWhen: async (s, whenCB) => {
15
+ await whenCB(s());
10
16
  return new Promise((resolve, rej) => {
11
- const x = React.createElement(subject);
12
- console.log("react-element", x);
13
- resolve(x);
17
+ resolve(React.createElement(s));
14
18
  });
19
+ // return whenCB(s);
15
20
  },
16
- andWhen: function (s, whenCB) {
17
- return whenCB(s);
21
+ butThen: async (subject, thenCB) => {
22
+ await thenCB(subject());
23
+ return new Promise((resolve, rej) => {
24
+ resolve(React.createElement(subject));
25
+ });
18
26
  },
19
27
  };
@@ -1,5 +1,5 @@
1
1
  import Testeranto from "../../../Node.js";
2
2
  import { testInterface as baseInterface, } from "./index.js";
3
- export default (testImplementations, testSpecifications, testInput, testInterface) => {
4
- return Testeranto(testInput, testSpecifications, testImplementations, Object.assign(Object.assign({}, baseInterface), testInterface));
3
+ export default (testImplementations, testSpecifications, testInput, testInterface = baseInterface) => {
4
+ return Testeranto(testInput, testSpecifications, testImplementations, testInterface);
5
5
  };
@@ -13,52 +13,26 @@ export default (testInput, testSpecifications, testImplementations, testInterfac
13
13
  }
14
14
  }
15
15
  const t = Testeranto(testInput, testSpecifications, testImplementations, {
16
- beforeAll: async (initialProps, artificer) => {
16
+ beforeAll: async (subject, artificer) => {
17
17
  return await new Promise((resolve, rej) => {
18
18
  const htmlElement = document.getElementById("root");
19
19
  if (htmlElement) {
20
20
  const domRoot = ReactDom.createRoot(htmlElement);
21
- // Ignore these type errors
22
- domRoot.render(createElement(TesterantoComponent, Object.assign(Object.assign({}, initialProps), { done: (reactElement) => {
23
- resolve({
24
- htmlElement,
25
- reactElement,
26
- domRoot,
27
- });
28
- } }), []));
29
- // resolve({ htmlElement });
21
+ resolve({ domRoot, htmlElement });
30
22
  }
31
23
  });
32
24
  },
33
- // beforeEach: async (
34
- // s,
35
- // initializer,
36
- // testResource,
37
- // artificer,
38
- // initialValues
39
- // ): Promise<IStore> => {
40
- // return new Promise((resolve, rej) => {
41
- // console.log("beforeEach" + TesterantoComponent);
42
- // // const domRoot = ReactDom.createRoot(htmlElement);
43
- // // // Ignore these type errors
44
- // // domRoot.render(
45
- // // createElement(
46
- // // TesterantoComponent,
47
- // // {
48
- // // ...initializer,
49
- // // done: (reactElement) => {
50
- // // resolve({
51
- // // htmlElement,
52
- // // reactElement,
53
- // // domRoot,
54
- // // });
55
- // // },
56
- // // },
57
- // // []
58
- // // )
59
- // // );
60
- // });
61
- // },
25
+ beforeEach: async ({ domRoot, htmlElement }, initialValues, testResource, artificer) => {
26
+ return new Promise(async (resolve, rej) => {
27
+ domRoot.render(createElement(TesterantoComponent, Object.assign(Object.assign({}, initialValues), { done: (reactElement) => {
28
+ resolve({
29
+ htmlElement,
30
+ reactElement,
31
+ domRoot,
32
+ });
33
+ } }), []));
34
+ });
35
+ },
62
36
  andWhen: function (s, whenCB) {
63
37
  return whenCB(s);
64
38
  },
@@ -2,22 +2,17 @@ import React from "react";
2
2
  import renderer, { act } from "react-test-renderer";
3
3
  export const testInterface = {
4
4
  beforeEach: function (CComponent, propsAndChildren) {
5
- function Link(props) {
6
- const p = props.props;
7
- const c = props.children;
8
- return React.createElement(CComponent, p, c);
5
+ function Link(proper) {
6
+ return React.createElement(CComponent, proper(), []);
9
7
  }
10
8
  return new Promise((res, rej) => {
11
9
  act(async () => {
12
- const p = propsAndChildren;
13
- const y = new CComponent(p.props);
14
10
  const testRenderer = await renderer.create(Link(propsAndChildren));
15
11
  res(testRenderer);
16
12
  });
17
13
  });
18
14
  },
19
15
  andWhen: async function (renderer, whenCB) {
20
- // console.log("andWhen", whenCB)
21
16
  await act(() => whenCB(renderer));
22
17
  return renderer;
23
18
  },
@@ -25,15 +20,12 @@ export const testInterface = {
25
20
  // return whenCB()(s);
26
21
  // },
27
22
  butThen: async function (s, thenCB, tr) {
28
- console.log("butThen", thenCB.toString());
29
23
  return thenCB(s);
30
24
  },
31
25
  afterEach: async function (store, ndx, artificer) {
32
- // console.log("afterEach", store);
33
26
  return {};
34
27
  },
35
28
  afterAll: (store, artificer) => {
36
- // console.log("afterAll", store);
37
29
  return;
38
30
  },
39
31
  };
@@ -1,36 +1,40 @@
1
1
  import { PM_Web } from "./PM/web";
2
2
  import Testeranto from "./lib/core.js";
3
3
  import { defaultTestResourceRequirement, } from "./lib/index.js";
4
+ let errorCallback = (e) => { };
5
+ let unhandledrejectionCallback = (event) => {
6
+ console.log("window.addEventListener unhandledrejection", event);
7
+ // cb({ error: event.reason.message });
8
+ // throw event;
9
+ };
4
10
  export class WebTesteranto extends Testeranto {
5
11
  constructor(input, testSpecification, testImplementation, testResourceRequirement, testInterface) {
6
- super(input, testSpecification, testImplementation, testResourceRequirement, testInterface);
12
+ super(input, testSpecification, testImplementation, testResourceRequirement, testInterface, (cb) => {
13
+ window.removeEventListener("error", errorCallback);
14
+ errorCallback = (e) => {
15
+ console.log("window.addEventListener error", e);
16
+ cb(e);
17
+ // throw e;
18
+ };
19
+ window.addEventListener("error", errorCallback);
20
+ window.removeEventListener("unhandledrejection", unhandledrejectionCallback);
21
+ /////////////////////
22
+ window.removeEventListener("unhandledrejection", unhandledrejectionCallback);
23
+ unhandledrejectionCallback = (event) => {
24
+ console.log("window.addEventListener unhandledrejection", event);
25
+ cb({ error: event.reason.message });
26
+ // throw event;
27
+ };
28
+ window.addEventListener("unhandledrejection", unhandledrejectionCallback);
29
+ });
7
30
  }
8
31
  async receiveTestResourceConfig(partialTestResource) {
9
32
  const t = partialTestResource; //JSON.parse(partialTestResource);
10
33
  const pm = new PM_Web(t);
11
34
  const { failed, artifacts, logPromise, features } = await this.testJobs[0].receiveTestResourceConfig(pm);
12
- pm.customclose();
13
35
  return new Promise((res, rej) => {
14
- res(features);
36
+ res({ features, failed });
15
37
  });
16
- // return features;
17
- // Promise.all([...artifacts, logPromise]).then(async () => {
18
- // console.log("hello world");
19
- // pm.customclose();
20
- // // we can't close the window becuase we might be taking a screenshot
21
- // // window.close();
22
- // // console.log(
23
- // // "(window as any).browser",
24
- // // JSON.stringify(await (window as any).browser)
25
- // // );
26
- // // var currentWindow = (await (window as any).browser).getCurrentWindow();
27
- // // window.close();
28
- // // var customWindow = window.open("", "_blank", "");
29
- // // customWindow.close();
30
- // // this.puppetMaster.browser.page
31
- // // window["customclose"]();
32
- // // console.log("goodbye", window["customclose"]());
33
- // });
34
38
  }
35
39
  }
36
40
  export default async (input, testSpecification, testImplementation, testInterface, testResourceRequirement = defaultTestResourceRequirement) => {
@@ -0,0 +1,411 @@
1
+ import { spawn } from "child_process";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import readline from "readline";
5
+ import { glob } from "glob";
6
+ import { debounceWatch } from "@bscotch/debounce-watch";
7
+ import esbuild from "esbuild";
8
+ import esbuildNodeConfiger from "./esbuildConfigs/node.js";
9
+ import esbuildWebConfiger from "./esbuildConfigs/web.js";
10
+ import webHtmlFrame from "./web.html.js";
11
+ import { PM_Main } from "./PM/main.js";
12
+ readline.emitKeypressEvents(process.stdin);
13
+ if (process.stdin.isTTY)
14
+ process.stdin.setRawMode(true);
15
+ function parseTsErrors(logContent) {
16
+ fs.writeFileSync("docs/types/log.txt", logContent.join("\n"));
17
+ try {
18
+ const regex = /(^src(.*?))\(\d*,\d*\): error/gm;
19
+ const brokenFilesToLines = {};
20
+ for (let i = 0; i < logContent.length - 1; i++) {
21
+ let m;
22
+ while ((m = regex.exec(logContent[i])) !== null) {
23
+ // This is necessary to avoid infinite loops with zero-width matches
24
+ if (m.index === regex.lastIndex) {
25
+ regex.lastIndex++;
26
+ }
27
+ if (!brokenFilesToLines[m[1]]) {
28
+ brokenFilesToLines[m[1]] = new Set();
29
+ }
30
+ brokenFilesToLines[m[1]].add(i);
31
+ }
32
+ }
33
+ const final = Object.keys(brokenFilesToLines).reduce((mm, lm, ndx) => {
34
+ mm[lm] = Array.from(brokenFilesToLines[lm]).map((l, ndx3) => {
35
+ const a = Array.from(brokenFilesToLines[lm]);
36
+ return Object.keys(a).reduce((mm2, lm2, ndx2) => {
37
+ const acc = [];
38
+ let j = a[lm2] + 1;
39
+ let working = true;
40
+ while (j < logContent.length - 1 && working) {
41
+ if (!logContent[j].match(regex) &&
42
+ working &&
43
+ !logContent[j].match(/^..\/(.*?)\(\d*,\d*\)/)) {
44
+ acc.push(logContent[j]);
45
+ }
46
+ else {
47
+ working = false;
48
+ }
49
+ j++;
50
+ }
51
+ mm2[lm] = [logContent[l], ...acc];
52
+ return mm2;
53
+ }, {})[lm];
54
+ });
55
+ return mm;
56
+ }, {});
57
+ Object.keys(final).forEach((k) => {
58
+ fs.mkdirSync(`./docs/types/${k.split("/").slice(0, -1).join("/")}`, {
59
+ recursive: true,
60
+ });
61
+ fs.writeFileSync(`./docs/types/${k}.type_errors.txt`, final[k].flat().flat().join("\r\n"));
62
+ });
63
+ }
64
+ catch (error) {
65
+ console.error("Error reading or parsing the log file:", error);
66
+ process.exit(1);
67
+ }
68
+ }
69
+ function parseLintErrors(logContent) {
70
+ fs.writeFileSync("docs/eslint/log.txt", logContent.join("\n"));
71
+ try {
72
+ const regex = new RegExp(`^${process.cwd()}/(.*?)`, "gm");
73
+ const brokenFilesToLines = {};
74
+ for (let i = 0; i < logContent.length - 1; i++) {
75
+ let m;
76
+ while ((m = regex.exec(logContent[i])) !== null) {
77
+ // This is necessary to avoid infinite loops with zero-width matches
78
+ if (m.index === regex.lastIndex) {
79
+ regex.lastIndex++;
80
+ }
81
+ if (!brokenFilesToLines[m[1]]) {
82
+ brokenFilesToLines[m[1]] = new Set();
83
+ }
84
+ brokenFilesToLines[m[1]].add(i);
85
+ }
86
+ }
87
+ const final = Object.keys(brokenFilesToLines).reduce((mm, lm, ndx) => {
88
+ mm[lm] = Array.from(brokenFilesToLines[lm]).map((l, ndx3) => {
89
+ const a = Array.from(brokenFilesToLines[lm]);
90
+ return Object.keys(a).reduce((mm2, lm2, ndx2) => {
91
+ const acc = [];
92
+ let j = a[lm2] + 1;
93
+ let working = true;
94
+ while (j < logContent.length - 1 && working) {
95
+ if (!logContent[j].match(regex) &&
96
+ working
97
+ // &&
98
+ // !logContent[j].match(/^..\/(.*?)\(\d*,\d*\)/)
99
+ ) {
100
+ acc.push(logContent[j]);
101
+ }
102
+ else {
103
+ working = false;
104
+ }
105
+ j++;
106
+ }
107
+ mm2[lm] = [logContent[l], ...acc];
108
+ return mm2;
109
+ }, {})[lm];
110
+ });
111
+ return mm;
112
+ }, {});
113
+ Object.keys(final).forEach((k) => {
114
+ fs.mkdirSync(`./docs/eslint/${k.split("/").slice(0, -1).join("/")}`, {
115
+ recursive: true,
116
+ });
117
+ fs.writeFileSync(`./docs/eslint/${k}.lint_errors.txt`, final[k].flat().flat().join("\r\n"));
118
+ });
119
+ }
120
+ catch (error) {
121
+ console.error("Error reading or parsing the log file:", error);
122
+ process.exit(1);
123
+ }
124
+ }
125
+ const typecheck = () => {
126
+ const logContent = [];
127
+ fs.rmSync("docs/types", { force: true, recursive: true });
128
+ fs.mkdirSync("docs/types");
129
+ const tsc = spawn("tsc", ["-noEmit"]);
130
+ tsc.stdout.on("data", (data) => {
131
+ const lines = data.toString().split("\n");
132
+ logContent.push(...lines);
133
+ });
134
+ tsc.stderr.on("data", (data) => {
135
+ console.error(`stderr: ${data}`);
136
+ process.exit(-1);
137
+ });
138
+ tsc.on("close", (code) => {
139
+ parseTsErrors(logContent);
140
+ });
141
+ };
142
+ const eslint = () => {
143
+ const logContent = [];
144
+ fs.rmSync("docs/eslint", { force: true, recursive: true });
145
+ fs.mkdirSync("docs/eslint");
146
+ const tsc = spawn("eslint", ["./src"]);
147
+ tsc.stdout.on("data", (data) => {
148
+ const lines = data.toString().split("\n");
149
+ logContent.push(...lines);
150
+ });
151
+ tsc.stderr.on("data", (data) => {
152
+ console.error(`stderr: ${data}`);
153
+ process.exit(-1);
154
+ });
155
+ tsc.on("close", (code) => {
156
+ parseLintErrors(logContent);
157
+ });
158
+ };
159
+ const getRunnables = (tests, payload = {
160
+ nodeEntryPoints: {},
161
+ webEntryPoints: {},
162
+ }) => {
163
+ return tests.reduce((pt, cv, cndx, cry) => {
164
+ if (cv[1] === "node") {
165
+ pt.nodeEntryPoints[cv[0]] = path.resolve(`./docs/node/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`);
166
+ }
167
+ else if (cv[1] === "web") {
168
+ pt.webEntryPoints[cv[0]] = path.resolve(`./docs/web/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`);
169
+ }
170
+ if (cv[3].length) {
171
+ getRunnables(cv[3], payload);
172
+ }
173
+ return pt;
174
+ }, payload);
175
+ };
176
+ import(process.cwd() + "/" + process.argv[2]).then(async (module) => {
177
+ const rawConfig = module.default;
178
+ const getSecondaryEndpointsPoints = (runtime) => {
179
+ const meta = (ts, st) => {
180
+ ts.forEach((t) => {
181
+ if (t[1] === runtime) {
182
+ st.add(t[0]);
183
+ }
184
+ if (Array.isArray(t[3])) {
185
+ meta(t[3], st);
186
+ }
187
+ });
188
+ return st;
189
+ };
190
+ return Array.from(meta(config.tests, new Set()));
191
+ };
192
+ const config = Object.assign(Object.assign({}, rawConfig), { buildDir: process.cwd() + "/" + rawConfig.outdir });
193
+ let nodeDone = false;
194
+ let webDone = false;
195
+ let mode = config.devMode ? "DEV" : "PROD";
196
+ let status = "build";
197
+ let pm = new PM_Main(config);
198
+ const fileHashes = {};
199
+ const { nodeEntryPoints, webEntryPoints } = getRunnables(config.tests);
200
+ const onNodeDone = () => {
201
+ nodeDone = true;
202
+ onDone();
203
+ };
204
+ const onWebDone = () => {
205
+ webDone = true;
206
+ onDone();
207
+ };
208
+ // async function fileHash(filePath, algorithm = "md5") {
209
+ // return new Promise((resolve, reject) => {
210
+ // const hash = crypto.createHash(algorithm);
211
+ // const fileStream = fs.createReadStream(filePath);
212
+ // fileStream.on("data", (data) => {
213
+ // hash.update(data);
214
+ // });
215
+ // fileStream.on("end", () => {
216
+ // const fileHash = hash.digest("hex");
217
+ // resolve(fileHash);
218
+ // });
219
+ // fileStream.on("error", (error) => {
220
+ // reject(`Error reading file: ${error.message}`);
221
+ // });
222
+ // });
223
+ // }
224
+ const onDone = async () => {
225
+ if (nodeDone && webDone) {
226
+ status = "built";
227
+ }
228
+ if (nodeDone && webDone && status === "built") {
229
+ // Object.entries(nodeEntryPoints).forEach(([k, outputFile]) => {
230
+ // console.log("watching", outputFile);
231
+ // try {
232
+ // watch(outputFile, async (filename) => {
233
+ // const hash = await fileHash(outputFile);
234
+ // if (fileHashes[k] !== hash) {
235
+ // fileHashes[k] = hash;
236
+ // console.log(`< ${filename} `);
237
+ // pm.launchNode(k, outputFile);
238
+ // }
239
+ // });
240
+ // } catch (e) {
241
+ // console.error(e);
242
+ // }
243
+ // });
244
+ // Object.entries(webEntryPoints).forEach(([k, outputFile]) => {
245
+ // console.log("watching", outputFile);
246
+ // watch(outputFile, async (filename) => {
247
+ // const hash = await fileHash(outputFile);
248
+ // console.log(`< ${filename} ${hash}`);
249
+ // if (fileHashes[k] !== hash) {
250
+ // fileHashes[k] = hash;
251
+ // pm.launchWeb(k, outputFile);
252
+ // }
253
+ // });
254
+ // });
255
+ }
256
+ if (nodeDone && webDone && mode === "PROD") {
257
+ console.log("Testeranto-EsBuild is all done. Goodbye!");
258
+ process.exit();
259
+ }
260
+ else {
261
+ if (mode === "PROD") {
262
+ console.log("waiting for tests to finish");
263
+ console.log(JSON.stringify({
264
+ nodeDone: nodeDone,
265
+ webDone: webDone,
266
+ mode: mode,
267
+ }, null, 2));
268
+ }
269
+ else {
270
+ console.log("waiting for tests to change");
271
+ }
272
+ console.log("press 'q' to quit");
273
+ if (config.devMode) {
274
+ console.log("ready and watching for changes...");
275
+ }
276
+ else {
277
+ pm.shutDown();
278
+ }
279
+ ////////////////////////////////////////////////////////////////////////////////
280
+ }
281
+ };
282
+ console.log(`Press 'q' to shutdown gracefully. Press 'x' to shutdown forcefully.`);
283
+ process.stdin.on("keypress", (str, key) => {
284
+ if (key.name === "q") {
285
+ console.log("Testeranto-EsBuild is shutting down...");
286
+ mode = "PROD";
287
+ onDone();
288
+ }
289
+ });
290
+ // const eslint = new ESLint();
291
+ // const configEslint = await eslint.calculateConfigForFile(
292
+ // "./src/eslint.config.mjs"
293
+ // );
294
+ // // console.log(`configEslint`, configEslint);
295
+ // fs.watch("src", { recursive: true }, async (eventType, filename) => {
296
+ // if (eventType === "change") {
297
+ // console.log(`File ${filename} has been modified.`);
298
+ // const x = await eslint.lintFiles([`./src/${filename}`]);
299
+ // console.log(x[0].messages);
300
+ // } else if (eventType === "rename") {
301
+ // console.log(`File ${filename} has been created or deleted.`);
302
+ // }
303
+ // });
304
+ fs.writeFileSync(`${config.outdir}/testeranto.json`, JSON.stringify(config, null, 2));
305
+ Promise.resolve(Promise.all([...getSecondaryEndpointsPoints("web")].map(async (sourceFilePath) => {
306
+ const sourceFileSplit = sourceFilePath.split("/");
307
+ const sourceDir = sourceFileSplit.slice(0, -1);
308
+ const sourceFileName = sourceFileSplit[sourceFileSplit.length - 1];
309
+ const sourceFileNameMinusJs = sourceFileName
310
+ .split(".")
311
+ .slice(0, -1)
312
+ .join(".");
313
+ const htmlFilePath = path.normalize(`${process.cwd()}/${config.outdir}/web/${sourceDir.join("/")}/${sourceFileNameMinusJs}.html`);
314
+ const jsfilePath = `./${sourceFileNameMinusJs}.mjs`;
315
+ return fs.promises
316
+ .mkdir(path.dirname(htmlFilePath), { recursive: true })
317
+ .then((x) => fs.writeFileSync(htmlFilePath, webHtmlFrame(jsfilePath, htmlFilePath)));
318
+ })));
319
+ glob(`./${config.outdir}/chunk-*.mjs`, {
320
+ ignore: "node_modules/**",
321
+ }).then((chunks) => {
322
+ chunks.forEach((chunk) => {
323
+ fs.unlinkSync(chunk);
324
+ });
325
+ });
326
+ // const processDebouncedEvents: DebouncedEventsProcessor = (events) => {
327
+ // typecheck();
328
+ // };
329
+ debounceWatch((events) => {
330
+ typecheck();
331
+ eslint();
332
+ }, "./src", {
333
+ onlyFileExtensions: ["ts", "tsx", "mts"],
334
+ debounceWaitSeconds: 0.2,
335
+ allowOverlappingRuns: false,
336
+ });
337
+ await pm.startPuppeteer({
338
+ slowMo: 1,
339
+ // timeout: 1,
340
+ waitForInitialPage: false,
341
+ executablePath:
342
+ // process.env.CHROMIUM_PATH || "/opt/homebrew/bin/chromium",
343
+ "/opt/homebrew/bin/chromium",
344
+ headless: true,
345
+ dumpio: true,
346
+ // timeout: 0,
347
+ devtools: true,
348
+ args: [
349
+ "--auto-open-devtools-for-tabs",
350
+ `--remote-debugging-port=3234`,
351
+ // "--disable-features=IsolateOrigins,site-per-process",
352
+ "--disable-site-isolation-trials",
353
+ "--allow-insecure-localhost",
354
+ "--allow-file-access-from-files",
355
+ "--allow-running-insecure-content",
356
+ "--disable-dev-shm-usage",
357
+ "--disable-extensions",
358
+ "--disable-gpu",
359
+ "--disable-setuid-sandbox",
360
+ "--disable-site-isolation-trials",
361
+ "--disable-web-security",
362
+ "--no-first-run",
363
+ "--no-sandbox",
364
+ "--no-startup-window",
365
+ // "--no-zygote",
366
+ "--reduce-security-for-testing",
367
+ "--remote-allow-origins=*",
368
+ "--unsafely-treat-insecure-origin-as-secure=*",
369
+ // "--disable-features=IsolateOrigins",
370
+ // "--remote-allow-origins=ws://localhost:3234",
371
+ // "--single-process",
372
+ // "--unsafely-treat-insecure-origin-as-secure",
373
+ // "--unsafely-treat-insecure-origin-as-secure=ws://192.168.0.101:3234",
374
+ // "--disk-cache-dir=/dev/null",
375
+ // "--disk-cache-size=1",
376
+ // "--start-maximized",
377
+ ],
378
+ }, ".");
379
+ await Promise.all([
380
+ esbuild
381
+ .context(esbuildNodeConfiger(config, Object.keys(nodeEntryPoints)))
382
+ .then(async (nodeContext) => {
383
+ if (config.devMode) {
384
+ await nodeContext.watch().then((v) => {
385
+ onNodeDone();
386
+ });
387
+ }
388
+ else {
389
+ nodeContext.rebuild().then((v) => {
390
+ onNodeDone();
391
+ });
392
+ }
393
+ return nodeContext;
394
+ }),
395
+ esbuild
396
+ .context(esbuildWebConfiger(config, Object.keys(webEntryPoints)))
397
+ .then(async (webContext) => {
398
+ if (config.devMode) {
399
+ await webContext.watch().then((v) => {
400
+ onWebDone();
401
+ });
402
+ }
403
+ else {
404
+ webContext.rebuild().then((v) => {
405
+ onWebDone();
406
+ });
407
+ }
408
+ return webContext;
409
+ }),
410
+ ]);
411
+ });