testeranto 0.135.0 → 0.140.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.
Files changed (187) hide show
  1. package/.aider.chat.history.md +13976 -0
  2. package/.aider.input.history +530 -0
  3. package/.aider.tags.cache.v3/{d8/b0/a8966fcd65890fd9f70d7afe8141.val → bd/91/b71f967fd074cf4b757081b429b7.val} +0 -0
  4. package/.aider.tags.cache.v3/cache.db +0 -0
  5. package/.aider.tags.cache.v3/{8e/ec/2d4659a1589a0187a757ab1cbefa.val → fb/96/b0f91c7e75e08fc5a6907633cf99.val} +0 -0
  6. package/README.md +29 -135
  7. package/bundle.js +1 -1
  8. package/dist/common/src/Init.js +4 -1
  9. package/dist/common/src/Node.js +1 -1
  10. package/dist/common/src/PM/__tests__/nodeSidecar.testeranto.js +2 -2
  11. package/dist/common/src/Web.js +2 -2
  12. package/dist/common/src/build.js +7 -73
  13. package/dist/common/src/defaultConfig.js +0 -1
  14. package/dist/common/src/lib/abstractBase.js +2 -0
  15. package/dist/common/src/lib/basebuilder.js +4 -0
  16. package/dist/common/src/lib/core.js +2 -0
  17. package/dist/common/src/run.js +1 -1
  18. package/dist/common/src/utils/buildTemplates.js +88 -0
  19. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  20. package/dist/module/src/Init.js +4 -1
  21. package/dist/module/src/Node.js +1 -1
  22. package/dist/module/src/PM/__tests__/nodeSidecar.testeranto.js +2 -2
  23. package/dist/module/src/Project.js +41 -47
  24. package/dist/module/src/TestReport.js +34 -31
  25. package/dist/module/src/Web.js +2 -2
  26. package/dist/module/src/build.js +7 -73
  27. package/dist/module/src/defaultConfig.js +0 -1
  28. package/dist/module/src/lib/abstractBase.js +2 -0
  29. package/dist/module/src/lib/basebuilder.js +4 -0
  30. package/dist/module/src/lib/core.js +2 -0
  31. package/dist/module/src/run.js +1 -1
  32. package/dist/module/src/utils/buildTemplates.js +82 -0
  33. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  34. package/dist/prebuild/Project.js +62 -13
  35. package/dist/prebuild/TestReport.js +39 -18
  36. package/dist/prebuild/build.mjs +96 -73
  37. package/dist/prebuild/init-docs.mjs +0 -4
  38. package/dist/tsconfig.tsbuildinfo +1 -0
  39. package/dist/types/src/CoreTypes.d.ts +5 -3
  40. package/dist/types/src/Node.d.ts +3 -3
  41. package/dist/types/src/PM/__tests__/nodeSidecar.testeranto.d.ts +17 -1
  42. package/dist/types/src/PM/__tests__/pureSidecar.testeranto.d.ts +17 -1
  43. package/dist/types/src/PM/__tests__/webSidecar.testeranto.d.ts +17 -1
  44. package/dist/types/src/PM/nodeSidecar.d.ts +2 -2
  45. package/dist/types/src/Pure.d.ts +3 -3
  46. package/dist/types/src/Types.d.ts +18 -14
  47. package/dist/types/src/Web.d.ts +3 -3
  48. package/dist/types/src/lib/abstractBase.d.ts +8 -8
  49. package/dist/types/src/lib/basebuilder.d.ts +3 -3
  50. package/dist/types/src/lib/classBuilder.d.ts +2 -2
  51. package/dist/types/src/lib/core.d.ts +2 -2
  52. package/dist/types/src/lib/index.d.ts +7 -6
  53. package/dist/types/src/lib/types.d.ts +8 -8
  54. package/dist/types/src/mothership/test.d.ts +20 -1
  55. package/dist/types/src/utils/buildTemplates.d.ts +3 -0
  56. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  57. package/docs/index.md +344 -54
  58. package/docs/style.md +116 -0
  59. package/docs.html +537 -0
  60. package/example.css +351 -0
  61. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Black.ttf +0 -0
  62. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Bold.ttf +0 -0
  63. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-ExtraBold.ttf +0 -0
  64. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Light.ttf +0 -0
  65. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Medium.ttf +0 -0
  66. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Regular.ttf +0 -0
  67. package/fonts/M_PLUS_Rounded_1c/MPLUSRounded1c-Thin.ttf +0 -0
  68. package/fonts/M_PLUS_Rounded_1c/OFL.txt +91 -0
  69. package/index.html +246 -24
  70. package/logo.svg +72 -0
  71. package/package.json +6 -2
  72. package/scripts/compile-docs.js +89 -0
  73. package/src/CoreTypes.ts +24 -43
  74. package/src/Init.ts +4 -4
  75. package/src/Node.ts +6 -20
  76. package/src/PM/__tests__/nodeSidecar.testeranto.ts +13 -20
  77. package/src/PM/__tests__/pureSidecar.testeranto.ts +8 -15
  78. package/src/PM/__tests__/webSidecar.testeranto.ts +8 -15
  79. package/src/PM/nodeSidecar.ts +2 -2
  80. package/src/PM/pure.ts +0 -4
  81. package/src/Project.tsx +289 -292
  82. package/src/Pure.ts +13 -14
  83. package/src/PureSidecar.ts +1 -0
  84. package/src/TestReport.tsx +179 -165
  85. package/src/Types.ts +29 -144
  86. package/src/Web.ts +15 -11
  87. package/src/build.ts +22 -73
  88. package/src/defaultConfig.ts +2 -1
  89. package/src/lib/BaseSuite.test.ts +457 -0
  90. package/src/lib/BaseSuite.ts +155 -0
  91. package/src/lib/abstractBase.ts +7 -162
  92. package/src/lib/basebuilder.ts +11 -11
  93. package/src/lib/classBuilder.ts +8 -3
  94. package/src/lib/core.ts +12 -12
  95. package/src/lib/index.ts +21 -24
  96. package/src/lib/types.ts +23 -9
  97. package/src/mothership/test.ts +13 -10
  98. package/src/run.ts +1 -1
  99. package/src/style.css +1 -1
  100. package/src/utils/buildTemplates.ts +88 -0
  101. package/style.css +496 -0
  102. package/testeranto/bundles/node/{mothership/chunk-V2EQEXU2.mjs → allTests/chunk-4PJCC2XT.mjs} +66 -59
  103. package/testeranto/bundles/node/allTests/metafile.json +4151 -0
  104. package/testeranto/bundles/node/allTests/src/PM/__tests__/nodeSidecar.testeranto.mjs +187 -0
  105. package/testeranto/bundles/node/{mothership → allTests}/src/PM/__tests__/pureSidecar.testeranto.mjs +1 -1
  106. package/testeranto/bundles/node/{mothership → allTests}/src/PM/__tests__/webSidecar.testeranto.mjs +1 -1
  107. package/testeranto/bundles/node/allTests/src/lib/BaseSuite.test.mjs +305 -0
  108. package/testeranto/bundles/node/{mothership → allTests}/src/mothership/test.mjs +1 -1
  109. package/testeranto/dev.html +29 -0
  110. package/testeranto/index.html +28 -27
  111. package/testeranto/reports/allTests/config.json +57 -0
  112. package/testeranto/reports/{mothership/index.html → allTests/dev.html} +2 -0
  113. package/testeranto/reports/allTests/index.html +26 -0
  114. package/testeranto/reports/{mothership/src/PM/__tests__/sidecar.testeranto/node/index.html → allTests/src/PM/__tests__/nodeSidecar.testeranto/node/dev.html} +4 -3
  115. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/index.html +21 -0
  116. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/lint_errors.json +80 -0
  117. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/message +1 -0
  118. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/prompt.txt +8 -0
  119. package/testeranto/reports/allTests/src/PM/__tests__/nodeSidecar.testeranto/node/type_errors.txt +28 -0
  120. package/testeranto/reports/{mothership/src/PM/__tests__/webSidecar.testeranto/node/index.html → allTests/src/PM/__tests__/pureSidecar.testeranto/node/dev.html} +4 -3
  121. package/testeranto/reports/allTests/src/PM/__tests__/pureSidecar.testeranto/node/index.html +21 -0
  122. package/testeranto/reports/{mothership → allTests}/src/PM/__tests__/pureSidecar.testeranto/node/lint_errors.json +12 -12
  123. package/testeranto/reports/allTests/src/PM/__tests__/pureSidecar.testeranto/node/message +1 -0
  124. package/testeranto/reports/allTests/src/PM/__tests__/pureSidecar.testeranto/node/prompt.txt +8 -0
  125. package/testeranto/reports/allTests/src/PM/__tests__/pureSidecar.testeranto/node/type_errors.txt +32 -0
  126. package/testeranto/reports/{mothership/src/PM/__tests__/nodeSidecar.testeranto/node/index.html → allTests/src/PM/__tests__/webSidecar.testeranto/node/dev.html} +4 -3
  127. package/testeranto/reports/allTests/src/PM/__tests__/webSidecar.testeranto/node/index.html +21 -0
  128. package/testeranto/reports/{mothership → allTests}/src/PM/__tests__/webSidecar.testeranto/node/lint_errors.json +12 -12
  129. package/testeranto/reports/allTests/src/PM/__tests__/webSidecar.testeranto/node/message +1 -0
  130. package/testeranto/reports/allTests/src/PM/__tests__/webSidecar.testeranto/node/prompt.txt +8 -0
  131. package/testeranto/reports/allTests/src/PM/__tests__/webSidecar.testeranto/node/type_errors.txt +32 -0
  132. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/console_log.txt +35 -0
  133. package/testeranto/reports/{mothership/src/PM/__tests__/pureSidecar.testeranto/node/index.html → allTests/src/lib/BaseSuite.test/node/dev.html} +4 -3
  134. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/index.html +21 -0
  135. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/lint_errors.json +608 -0
  136. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/message +1 -0
  137. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/prompt.txt +7 -0
  138. package/testeranto/reports/allTests/src/lib/BaseSuite.test/node/type_errors.txt +68 -0
  139. package/testeranto/reports/allTests/src/mothership/test/node/dev.html +21 -0
  140. package/testeranto/reports/allTests/src/mothership/test/node/index.html +21 -0
  141. package/testeranto/reports/allTests/src/mothership/test/node/message +1 -0
  142. package/testeranto/reports/allTests/src/mothership/test/node/prompt.txt +8 -0
  143. package/testeranto/reports/allTests/src/mothership/test/node/type_errors.txt +24 -0
  144. package/testeranto/reports/allTests/summary.json +37 -0
  145. package/testeranto.config.ts +16 -26
  146. package/tsc.log +66 -69
  147. package/dist/common/src/SP__Polygon.test.js +0 -10
  148. package/dist/module/src/ReportClient.js +0 -132
  149. package/dist/module/src/SP__Polygon.test.js +0 -8
  150. package/dist/prebuild/ReportClient.js +0 -3
  151. package/dist/types/src/SP__Polygon.test.d.ts +0 -1
  152. package/src/ReportClient.tsx +0 -164
  153. package/src/SP__Polygon.test.ts +0 -13
  154. package/testeranto/ReportClient.css +0 -11367
  155. package/testeranto/ReportClient.js +0 -24641
  156. package/testeranto/bundles/node/mothership/metafile.json +0 -389
  157. package/testeranto/bundles/node/mothership/src/PM/__tests__/nodeSidecar.testeranto.mjs +0 -1219
  158. package/testeranto/bundles/node/mothership/src/PM/__tests__/sidecar.testeranto.mjs +0 -1199
  159. package/testeranto/reports/mothership/config.json +0 -25
  160. package/testeranto/reports/mothership/src/PM/__tests__/nodeSidecar.testeranto/node/console_log.txt +0 -0
  161. package/testeranto/reports/mothership/src/PM/__tests__/nodeSidecar.testeranto/node/lint_errors.json +0 -1564
  162. package/testeranto/reports/mothership/src/PM/__tests__/nodeSidecar.testeranto/node/prompt.txt +0 -22
  163. package/testeranto/reports/mothership/src/PM/__tests__/nodeSidecar.testeranto/node/type_errors.txt +0 -35
  164. package/testeranto/reports/mothership/src/PM/__tests__/pureSidecar.testeranto/node/prompt.txt +0 -12
  165. package/testeranto/reports/mothership/src/PM/__tests__/pureSidecar.testeranto/node/type_errors.txt +0 -26
  166. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/bdd_errors.txt +0 -1
  167. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/console_log.txt +0 -0
  168. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/lint_errors.json +0 -1564
  169. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/log.txt +0 -0
  170. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/prompt.txt +0 -22
  171. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/tests.json +0 -56
  172. package/testeranto/reports/mothership/src/PM/__tests__/sidecar.testeranto/node/type_errors.txt +0 -29
  173. package/testeranto/reports/mothership/src/PM/__tests__/webSidecar.testeranto/node/prompt.txt +0 -12
  174. package/testeranto/reports/mothership/src/PM/__tests__/webSidecar.testeranto/node/type_errors.txt +0 -26
  175. package/testeranto/reports/mothership/src/mothership/test/node/bdd_errors.txt +0 -1
  176. package/testeranto/reports/mothership/src/mothership/test/node/console_log.txt +0 -4
  177. package/testeranto/reports/mothership/src/mothership/test/node/index.html +0 -20
  178. package/testeranto/reports/mothership/src/mothership/test/node/log.txt +0 -0
  179. package/testeranto/reports/mothership/src/mothership/test/node/prompt.txt +0 -12
  180. package/testeranto/reports/mothership/src/mothership/test/node/tests.json +0 -24
  181. package/testeranto/reports/mothership/src/mothership/test/node/type_errors.txt +0 -18
  182. package/testeranto/reports/mothership/summary.json +0 -9
  183. /package/testeranto/bundles/node/{mothership → allTests}/chunk-PG6KUKNP.mjs +0 -0
  184. /package/testeranto/bundles/pure/{mothership → allTests}/metafile.json +0 -0
  185. /package/testeranto/bundles/web/{mothership → allTests}/metafile.json +0 -0
  186. /package/testeranto/reports/{mothership/src/PM/__tests__/nodeSidecar.testeranto → allTests/src/lib/BaseSuite.test}/node/log.txt +0 -0
  187. /package/testeranto/reports/{mothership → allTests}/src/mothership/test/node/lint_errors.json +0 -0
@@ -0,0 +1,457 @@
1
+ import { BaseSuite } from "./BaseSuite";
2
+ import { BaseGiven, BaseWhen, BaseThen, BaseCheck } from "./abstractBase";
3
+ import { ITTestResourceConfiguration, ITestArtifactory, ITLog } from ".";
4
+ import { IPM } from "./types";
5
+ import {
6
+ Ibdd_in,
7
+ Ibdd_out,
8
+ ITestSpecification,
9
+ ITestImplementation,
10
+ ITestInterface,
11
+ } from "../CoreTypes";
12
+ import Testeranto from "../Node";
13
+
14
+ // 1. Define our test types with full type safety
15
+ type TestStore = {
16
+ testStore: boolean;
17
+ testSelection?: boolean;
18
+ error?: Error;
19
+ };
20
+
21
+ type TestSelection = {
22
+ testSelection: boolean;
23
+ error?: boolean;
24
+ };
25
+
26
+ type I = Ibdd_in<
27
+ null, // iinput
28
+ BaseSuite<any, any>, // isubject
29
+ TestStore, // istore
30
+ TestSelection, // iselection
31
+ () => Promise<TestStore>, // given
32
+ (store: TestStore) => Promise<TestStore>, // when
33
+ (store: TestStore) => Promise<TestSelection> // then
34
+ >;
35
+
36
+ type O = Ibdd_out<
37
+ {
38
+ Default: [string]; // Suite names
39
+ },
40
+ {
41
+ Default: []; // Given states
42
+ },
43
+ {
44
+ TestWhen: []; // When actions
45
+ RunSuite: [];
46
+ },
47
+ {
48
+ TestThen: []; // Then assertions
49
+ FeaturesIncludes: [feature: string];
50
+ StoreValid: [];
51
+ },
52
+ {
53
+ TestCheck: []; // Check validations
54
+ }
55
+ >;
56
+
57
+ // 2. Mock implementations with proper typing
58
+ class MockGiven extends BaseGiven<I> {
59
+ constructor(
60
+ name: string,
61
+ features: string[],
62
+ whens: BaseWhen<I>[],
63
+ thens: BaseThen<I>[]
64
+ ) {
65
+ super(
66
+ name,
67
+ features,
68
+ whens,
69
+ thens,
70
+ async () => ({ testStore: true }), // givenCB
71
+ {} // initialValues
72
+ );
73
+ }
74
+
75
+ async givenThat(
76
+ subject: I["isubject"],
77
+ testResourceConfiguration: ITTestResourceConfiguration,
78
+ artifactory: ITestArtifactory,
79
+ givenCB: I["given"],
80
+ initialValues: any,
81
+ pm: IPM
82
+ ): Promise<TestStore> {
83
+ return { testStore: true };
84
+ }
85
+
86
+ uberCatcher(e: Error): void {
87
+ console.error("Given error:", e);
88
+ }
89
+ }
90
+
91
+ class MockWhen extends BaseWhen<I> {
92
+ async andWhen(
93
+ store: TestStore,
94
+ whenCB: (x: TestSelection) => Promise<TestStore>,
95
+ testResource: ITTestResourceConfiguration,
96
+ pm: IPM
97
+ ): Promise<TestStore> {
98
+ return { ...store, testStore: true };
99
+ }
100
+ }
101
+
102
+ class MockThen extends BaseThen<I> {
103
+ async butThen(
104
+ store: TestStore,
105
+ thenCB: (s: TestSelection) => Promise<TestSelection>,
106
+ testResourceConfiguration: ITTestResourceConfiguration,
107
+ pm: IPM
108
+ ): Promise<TestSelection> {
109
+ return { testSelection: true };
110
+ }
111
+ }
112
+
113
+ class MockCheck extends BaseCheck<I> {
114
+ async checkThat(
115
+ subject: I["isubject"],
116
+ testResourceConfiguration: ITTestResourceConfiguration,
117
+ artifactory: ITestArtifactory,
118
+ initializer: any,
119
+ initialValues: any,
120
+ pm: IPM
121
+ ): Promise<TestStore> {
122
+ return { testStore: true };
123
+ }
124
+ }
125
+
126
+ class TestableSuite extends BaseSuite<I, O> {
127
+ constructor(name: string, index: number) {
128
+ super(
129
+ name,
130
+ index,
131
+ {
132
+ testGiven: new MockGiven(
133
+ "testGiven",
134
+ ["testFeature"],
135
+ [
136
+ new MockWhen("testWhen", () =>
137
+ Promise.resolve({ testStore: true })
138
+ ),
139
+ ],
140
+ [
141
+ new MockThen("testThen", async () =>
142
+ Promise.resolve({ testSelection: true })
143
+ ),
144
+ ]
145
+ ),
146
+ },
147
+ [
148
+ new MockCheck(
149
+ "testCheck",
150
+ ["testFeature"],
151
+ () => Promise.resolve({ testStore: true }),
152
+ null,
153
+ () => {}
154
+ ),
155
+ ]
156
+ );
157
+ }
158
+ }
159
+
160
+ // 3. Enhanced Test Specification with more test cases
161
+ const specification: ITestSpecification<I, O> = (
162
+ Suite: SuiteSpecification<I, O>,
163
+ Given: GivenSpecification<I, O>,
164
+ When: WhenSpecification<I, O>,
165
+ Then: ThenSpecification<I, O>,
166
+ Check: ITestCheckCallback<I, O>
167
+ ) => [
168
+ Suite.Default(
169
+ "BaseSuite Core Functionality Tests",
170
+ {
171
+ // Test initialization and basic properties
172
+ initialization: Given.Default(
173
+ ["BaseSuite should initialize with correct name and index"],
174
+ [],
175
+ [
176
+ Then.SuiteNameMatches("testSuite"),
177
+ Then.SuiteIndexMatches(0),
178
+ Then.FeaturesIncludes("testFeature"),
179
+ ]
180
+ ),
181
+
182
+ // Test execution flow
183
+ execution: Given.Default(
184
+ ["BaseSuite should execute all phases successfully"],
185
+ [When.RunSuite()],
186
+ [Then.StoreValid(), Then.NoErrorsOccurred(), Then.AllChecksCompleted()]
187
+ ),
188
+
189
+ // Test multiple features
190
+ multipleFeatures: Given.Default(
191
+ ["BaseSuite should handle multiple features"],
192
+ [When.AddFeature("additionalFeature")],
193
+ [
194
+ Then.FeaturesIncludes("testFeature"),
195
+ Then.FeaturesIncludes("additionalFeature"),
196
+ Then.FeatureCountMatches(2),
197
+ ]
198
+ ),
199
+
200
+ // Test error handling
201
+ errorHandling: Given.Default(
202
+ ["BaseSuite should handle errors gracefully"],
203
+ [When.RunSuiteWithError()],
204
+ [
205
+ Then.ErrorCountMatches(1),
206
+ // Then.FailedFlagSet(),
207
+ ]
208
+ ),
209
+ },
210
+ [
211
+ // Additional validation checks
212
+ // Check.Default(
213
+ // ["Verify suite state after all tests"],
214
+ // [],
215
+ // [
216
+ // Then.AllTestsCompleted(),
217
+ // Then.CleanExit()
218
+ // ]
219
+ // )
220
+ ]
221
+ ),
222
+ ];
223
+
224
+ // 4. Enhanced Test Implementation with more operations
225
+ const implementation: ITestImplementation<I, O> = {
226
+ suites: {
227
+ Default: "BaseSuite Comprehensive Test Suite" as const,
228
+ },
229
+
230
+ givens: {
231
+ Default: (): TestableSuite => new TestableSuite("testSuite", 0),
232
+ },
233
+
234
+ whens: {
235
+ RunSuite:
236
+ (): ((suite: TestableSuite) => Promise<TestableSuite>) =>
237
+ async (suite: TestableSuite) => {
238
+ const mockConfig: ITTestResourceConfiguration = {
239
+ name: "test",
240
+ fs: "/tmp",
241
+ ports: [3000],
242
+ environment: {},
243
+ timeout: 5000,
244
+ retries: 3,
245
+ };
246
+ const mockArtifactory: ITestArtifactory = (
247
+ key: string,
248
+ value: unknown
249
+ ) => {};
250
+ const mockTLog: ITLog = (...args: any[]) => {};
251
+ const mockPM: IPM = {
252
+ server: null,
253
+ testResourceConfiguration: mockConfig,
254
+ start: async () => {},
255
+ stop: async () => {},
256
+ testArtiFactoryfileWriter: () => {},
257
+ $: () => {},
258
+ click: () => {},
259
+ closePage: () => {},
260
+ createWriteStream: async () => "",
261
+ };
262
+
263
+ return await suite.run(
264
+ null,
265
+ mockConfig,
266
+ mockArtifactory,
267
+ mockTLog,
268
+ mockPM
269
+ );
270
+ },
271
+
272
+ RunSuiteWithError:
273
+ (): ((suite: TestableSuite) => Promise<TestableSuite>) =>
274
+ async (suite: TestableSuite) => {
275
+ // Force an error by passing invalid config
276
+ try {
277
+ await suite.run(
278
+ null,
279
+ {} as ITTestResourceConfiguration, // Invalid config
280
+ () => {},
281
+ () => {},
282
+ {} as IPM
283
+ );
284
+ } catch (e) {
285
+ // Error is caught and counted by BaseSuite
286
+ }
287
+ return suite;
288
+ },
289
+
290
+ AddFeature:
291
+ (feature: string): ((suite: TestableSuite) => TestableSuite) =>
292
+ (suite: TestableSuite) => {
293
+ // Add a feature to the first given
294
+ const firstGivenKey = Object.keys(suite.givens)[0];
295
+ if (firstGivenKey) {
296
+ suite.givens[firstGivenKey].features.push(feature);
297
+ }
298
+ return suite;
299
+ },
300
+ },
301
+
302
+ thens: {
303
+ SuiteNameMatches:
304
+ (expectedName: string): ((suite: TestableSuite) => TestableSuite) =>
305
+ (suite: TestableSuite) => {
306
+ if (suite.name !== expectedName) {
307
+ throw new Error(
308
+ `Expected suite name '${expectedName}', got '${suite.name}'`
309
+ );
310
+ }
311
+ return suite;
312
+ },
313
+
314
+ SuiteIndexMatches:
315
+ (expectedIndex: number): ((suite: TestableSuite) => TestableSuite) =>
316
+ (suite: TestableSuite) => {
317
+ if (suite.index !== expectedIndex) {
318
+ throw new Error(
319
+ `Expected suite index ${expectedIndex}, got ${suite.index}`
320
+ );
321
+ }
322
+ return suite;
323
+ },
324
+
325
+ FeaturesIncludes:
326
+ (feature: string): ((suite: TestableSuite) => TestableSuite) =>
327
+ (suite: TestableSuite) => {
328
+ if (!suite.features().includes(feature)) {
329
+ throw new Error(`Expected features to include ${feature}`);
330
+ }
331
+ return suite;
332
+ },
333
+
334
+ FeatureCountMatches:
335
+ (expectedCount: number): ((suite: TestableSuite) => TestableSuite) =>
336
+ (suite: TestableSuite) => {
337
+ const actualCount = suite.features().length;
338
+ if (actualCount !== expectedCount) {
339
+ throw new Error(
340
+ `Expected ${expectedCount} features, got ${actualCount}`
341
+ );
342
+ }
343
+ return suite;
344
+ },
345
+
346
+ StoreValid:
347
+ (): ((suite: TestableSuite) => TestableSuite) =>
348
+ (suite: TestableSuite) => {
349
+ if (!suite.store?.testStore) {
350
+ throw new Error("Expected valid store after execution");
351
+ }
352
+ return suite;
353
+ },
354
+
355
+ NoErrorsOccurred:
356
+ (): ((suite: TestableSuite) => TestableSuite) =>
357
+ (suite: TestableSuite) => {
358
+ if (suite.failed || suite.fails > 0) {
359
+ throw new Error("Expected no errors to occur during execution");
360
+ }
361
+ return suite;
362
+ },
363
+
364
+ ErrorCountMatches:
365
+ (expectedCount: number): ((suite: TestableSuite) => TestableSuite) =>
366
+ (suite: TestableSuite) => {
367
+ if (suite.fails !== expectedCount) {
368
+ throw new Error(
369
+ `Expected ${expectedCount} errors, got ${suite.fails}`
370
+ );
371
+ }
372
+ return suite;
373
+ },
374
+
375
+ FailedFlagSet:
376
+ (): ((suite: TestableSuite) => TestableSuite) =>
377
+ (suite: TestableSuite) => {
378
+ if (!suite.failed) {
379
+ throw new Error("Expected failed flag to be set after error");
380
+ }
381
+ return suite;
382
+ },
383
+
384
+ AllChecksCompleted:
385
+ (): ((suite: TestableSuite) => TestableSuite) =>
386
+ (suite: TestableSuite) => {
387
+ if (suite.checks.some((check) => !check.key)) {
388
+ throw new Error("Expected all checks to be completed");
389
+ }
390
+ return suite;
391
+ },
392
+
393
+ AllTestsCompleted:
394
+ (): ((suite: TestableSuite) => TestableSuite) =>
395
+ (suite: TestableSuite) => {
396
+ if (!suite.store) {
397
+ throw new Error("Expected all tests to be completed");
398
+ }
399
+ return suite;
400
+ },
401
+
402
+ CleanExit:
403
+ (): ((suite: TestableSuite) => TestableSuite) =>
404
+ (suite: TestableSuite) => {
405
+ if (suite.failed && suite.fails === 0) {
406
+ throw new Error("Expected clean exit state");
407
+ }
408
+ return suite;
409
+ },
410
+ },
411
+
412
+ checks: {
413
+ Default: (): TestableSuite => new TestableSuite("testCheck", 1),
414
+ },
415
+ };
416
+
417
+ // 5. Fully typed Test Interface
418
+ const testInterface: ITestInterface<I> = {
419
+ beforeEach: async (
420
+ subject: I["isubject"],
421
+ initializer: (context?: any) => I["given"]
422
+ ): Promise<I["istore"]> => initializer(),
423
+
424
+ andWhen: async (
425
+ store: I["istore"],
426
+ whenCB: I["when"],
427
+ testResource: ITTestResourceConfiguration,
428
+ pm: IPM
429
+ ): Promise<I["istore"]> => whenCB(store, pm),
430
+
431
+ butThen: async (
432
+ store: I["istore"],
433
+ thenCB: I["then"],
434
+ testResource: ITTestResourceConfiguration,
435
+ pm: IPM
436
+ ): Promise<I["iselection"]> => thenCB(store, pm),
437
+
438
+ afterEach: (store: I["istore"]): I["istore"] => store,
439
+
440
+ afterAll: (store: I["istore"], pm: IPM): void => {},
441
+
442
+ assertThis: (result: I["then"] | undefined): boolean => !!result,
443
+
444
+ beforeAll: async (
445
+ input: I["iinput"],
446
+ testResource: ITTestResourceConfiguration,
447
+ pm: IPM
448
+ ): Promise<I["isubject"]> => input as unknown as I["isubject"],
449
+ };
450
+
451
+ // 6. Run the tests
452
+ export default Testeranto<I, O, {}>(
453
+ BaseSuite.prototype,
454
+ specification,
455
+ implementation,
456
+ testInterface
457
+ );
@@ -0,0 +1,155 @@
1
+ import { ITTestResourceConfiguration, ITestArtifactory } from ".";
2
+ import { Ibdd_in_any, Ibdd_out_any } from "../CoreTypes";
3
+ import { IGivens, BaseCheck } from "./abstractBase";
4
+ import { beforeAllProxy, afterAllProxy } from "./pmProxy";
5
+ import { IPM } from "./types";
6
+
7
+ export abstract class BaseSuite<I extends Ibdd_in_any, O extends Ibdd_out_any> {
8
+ name: string;
9
+ givens: IGivens<I>;
10
+ checks: BaseCheck<I>[];
11
+ store: I["istore"];
12
+ testResourceConfiguration: ITTestResourceConfiguration;
13
+ index: number;
14
+ failed: boolean;
15
+ fails: number;
16
+
17
+ constructor(
18
+ name: string,
19
+ index: number,
20
+ givens: IGivens<I> = {},
21
+ checks: BaseCheck<I>[] = []
22
+ ) {
23
+ this.name = name;
24
+ this.index = index;
25
+ this.givens = givens;
26
+ this.checks = checks;
27
+ this.fails = 0;
28
+ }
29
+
30
+ public features() {
31
+ const features = Object.keys(this.givens)
32
+ .map((k) => this.givens[k].features)
33
+ .flat()
34
+ .filter((value, index, array) => {
35
+ return array.indexOf(value) === index;
36
+ });
37
+ return features || [];
38
+ }
39
+
40
+ public toObj() {
41
+ const givens = Object.keys(this.givens).map((k) => this.givens[k].toObj());
42
+ const checks = Object.keys(this.checks).map((k) => this.checks[k].toObj());
43
+
44
+ return {
45
+ name: this.name,
46
+ givens,
47
+ checks,
48
+ fails: this.fails,
49
+ failed: this.failed,
50
+ features: this.features(),
51
+ };
52
+ }
53
+
54
+ setup(
55
+ s: I["iinput"],
56
+ artifactory: ITestArtifactory,
57
+ tr: ITTestResourceConfiguration,
58
+ pm: IPM
59
+ ): Promise<I["isubject"]> {
60
+ return new Promise((res) => res(s as unknown as I["isubject"]));
61
+ }
62
+
63
+ assertThat(t: Awaited<I["then"]> | undefined): boolean {
64
+ return !!t;
65
+ }
66
+
67
+ afterAll(store: I["istore"], artifactory: ITestArtifactory, pm: IPM) {
68
+ return store;
69
+ }
70
+
71
+ async run(
72
+ input: I["iinput"],
73
+ testResourceConfiguration: ITTestResourceConfiguration,
74
+ artifactory: (fPath: string, value: unknown) => void,
75
+ tLog: (...string) => void,
76
+ pm: IPM
77
+ ): Promise<BaseSuite<I, O>> {
78
+ this.testResourceConfiguration = testResourceConfiguration;
79
+ // tLog("test resources: ", JSON.stringify(testResourceConfiguration));
80
+
81
+ const suiteArtifactory = (fPath: string, value: unknown) =>
82
+ artifactory(`suite-${this.index}-${this.name}/${fPath}`, value);
83
+
84
+ // console.log("\nSuite:", this.index, this.name);
85
+ tLog("\nSuite:", this.index, this.name);
86
+ const sNdx = this.index;
87
+ // const sName = this.name;
88
+
89
+ const subject = await this.setup(
90
+ input,
91
+ suiteArtifactory,
92
+ testResourceConfiguration,
93
+ beforeAllProxy(pm, sNdx.toString())
94
+ );
95
+
96
+ for (const [gKey, g] of Object.entries(this.givens)) {
97
+ const giver = this.givens[gKey];
98
+ this.store = await giver.give(
99
+ subject,
100
+ gKey,
101
+ testResourceConfiguration,
102
+ this.assertThat,
103
+ suiteArtifactory,
104
+ tLog,
105
+ pm,
106
+ sNdx
107
+ ).catch((e) => {
108
+ this.failed = true;
109
+ this.fails = this.fails + 1;
110
+ console.error("Given error:", e);
111
+ throw e;
112
+ });
113
+ }
114
+
115
+ for (const [ndx, thater] of this.checks.entries()) {
116
+ await thater.check(
117
+ subject,
118
+ thater.name,
119
+ testResourceConfiguration,
120
+ this.assertThat,
121
+ suiteArtifactory,
122
+ tLog,
123
+ pm
124
+ );
125
+ }
126
+
127
+ try {
128
+ this.afterAll(
129
+ this.store,
130
+ artifactory,
131
+ afterAllProxy(pm, sNdx.toString())
132
+ );
133
+ } catch (e) {
134
+ console.error(e);
135
+ // this.fails.push(this);
136
+ // return this;
137
+ }
138
+
139
+ // @TODO fix me
140
+ // for (const k of Object.keys(this.givens)) {
141
+ // const giver = this.givens[k];
142
+
143
+ // try {
144
+ // giver.afterAll(this.store, artifactory, pm);
145
+ // } catch (e) {
146
+ // console.error(e);
147
+ // this.fails.push(giver);
148
+ // return this;
149
+ // }
150
+ // }
151
+ ////////////////
152
+
153
+ return this;
154
+ }
155
+ }