testeranto 0.135.0 → 0.140.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 (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 +28 -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 +245 -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
package/docs.html ADDED
@@ -0,0 +1,537 @@
1
+
2
+ <!DOCTYPE html>
3
+ <html lang="en">
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>index.md</title>
8
+
9
+ <!-- Prism.js CSS -->
10
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet" />
11
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.css" rel="stylesheet" />
12
+
13
+ <!-- load style AFTER prism -->
14
+ <link rel="stylesheet" href="style.css">
15
+
16
+
17
+ </head>
18
+ <body>
19
+ <div class="parallax-background"></div>
20
+ <div id="container">
21
+ <h1>Testeranto docs and core concepts</h1>
22
+ <p>Testeranto&#39;s type system provides a rigorous framework for Behavior-Driven Development (BDD) testing. While powerful, the API can initially seem complex but everything you need to know can be summed up in <strong>3 core functions and 5 essential types</strong>. Follow these patterns, and TypeScript&#39;s type checker will guide you through the rest.</p>
23
+ <h3>⚠️ this doc is a work in progress. It is 99% accurate but needs some attention to be complete. ⚠️</h3>
24
+ <p>Let&#39;s break down the key components using a Rectangle class example.</p>
25
+ <h3>The Test Subject</h3>
26
+ <p>This is the thing-to-be-tested, for this example, a very simple implementation of a Rectangle</p>
27
+ <pre class="language-typescript line-numbers"><code class="language-typescript">class Rectangle {
28
+ constructor(public width: number, public height: number) {}
29
+
30
+ setWidth(w: number) {
31
+ this.width = w;
32
+ }
33
+ setHeight(h: number) {
34
+ this.height = h;
35
+ }
36
+ getArea() {
37
+ return this.width * this.height;
38
+ }
39
+ }</code></pre><h3>Testeranto&#39;s 3 functions</h3>
40
+ <p>For each of testeranto&#39;s runtime, there is a specific Testeranto main function. Each is it&#39;s own import but all 3 are called in the same way.</p>
41
+ <h4>Node</h4>
42
+ <pre>import Testeranto from "testeranto/src/Node"; // <- import the Node main function
43
+ // below this point, all runtimes are identical!
44
+
45
+ // Note the type parameters I, O, and M: these will be important later
46
+ export default Testeranto<
47
+ I extends Ibdd_in,
48
+ O extends Ibdd_out,
49
+ M
50
+ >(
51
+ Rectangle.prototype, // <- the subject of the test.
52
+ specification,
53
+ implementation,
54
+ interface
55
+ );</pre><h4>Web</h4>
56
+ <pre>import Testeranto from "testeranto/src/Web"; // <- import the Web main function
57
+ // below this point, all runtimes are identical!
58
+
59
+ import { implementation } from "./Rectangle.test.implementation";
60
+ import { specification } from "./Rectangle.test.specification";
61
+ import { interface } from "./Rectangle.test.interface";
62
+
63
+ // Note the type parameters I, O, and M: these will be important later
64
+ export default Testeranto<
65
+ I extends Ibdd_in,
66
+ O extends Ibdd_out,
67
+ M
68
+ >(
69
+ Rectangle.prototype, // <- the subject of the test.
70
+ specification,
71
+ implementation,
72
+ interface
73
+ );</pre><h4>Pure</h4>
74
+ <pre>import Testeranto from "testeranto/src/Pure"; // <- import the Pure main function
75
+ // below this point, all runtimes are identical!
76
+
77
+ import { implementation } from "./Rectangle.test.implementation";
78
+ import { specification } from "./Rectangle.test.specification";
79
+ import { interface } from "./Rectangle.test.interface";
80
+
81
+ // Note the type parameters I, O, and M: these will be important later
82
+ export default Testeranto<
83
+ I extends Ibdd_in,
84
+ O extends Ibdd_out,
85
+ M
86
+ >(
87
+ Rectangle.prototype, // <- the subject of the test.
88
+ specification,
89
+ implementation,
90
+ interface
91
+ );</pre><h3>Testeranto&#39;s 5 Essential Types</h3>
92
+ <p>Every testeranto test is built around these 5 types that form a complete testing pipeline:</p>
93
+ <ol>
94
+ <li><strong>ITestSpecification</strong> - The &quot;what&quot; of your tests (business requirements)</li>
95
+ <li><strong>ITestImplementation</strong> - The &quot;how&quot; of your tests (concrete operations)</li>
96
+ <li><strong>ITestInterface</strong> - The &quot;glue&quot; between specs and implementation</li>
97
+ <li><strong>Ibdd_in</strong> - Defines the internal test flow shape</li>
98
+ <li><strong>Ibdd_out</strong> - Defines the external test interface</li>
99
+ </ol>
100
+ <pre class="mermaid">flowchart LR
101
+ S[ITestSpecification] -->|defines| O[Ibdd_out]
102
+ I[ITestImplementation] -->|uses| O
103
+ I -->|uses| M[Modifier]
104
+ T[ITestInterface] -->|connects| N[Ibdd_in]
105
+ S -->|flows through| N
106
+ I -->|flows through| N
107
+
108
+ style S fill:#2aa198,stroke:#073642
109
+ style I fill:#859900,stroke:#073642
110
+ style T fill:#b58900,stroke:#073642
111
+ style O fill:#d33682,stroke:#073642
112
+ style N fill:#cb4b16,stroke:#073642
113
+ style M fill:#6c71c4,stroke:#073642</pre><h4>The Specification (ITestSpecification)</h4>
114
+ <p>The Specification defines the business requirements in plain language, completely separate from implementation details. This is where you describe <strong>what</strong> should be tested without worrying about <strong>how</strong>.</p>
115
+ <ul>
116
+ <li>Pure business logic</li>
117
+ <li>Human-readable test descriptions</li>
118
+ <li>Defines test suites, scenarios (Given/When/Then)</li>
119
+ <li>Maps directly to BDD concepts</li>
120
+ <li>Uses Ibdd_out for type safety</li>
121
+ </ul>
122
+ <pre class="language-typescript line-numbers"><code class="language-typescript">import {
123
+ Ibdd_in,
124
+ Ibdd_out,
125
+ ITestSpecification,
126
+ } from "testeranto/src/CoreTypes";
127
+
128
+ // Note the type parameters I and O. These are important!
129
+ export const specification: ITestSpecification<
130
+ I extends Ibdd_in,
131
+ O extends Ibdd_out,
132
+ > = (
133
+ Suite,
134
+ Given,
135
+ When,
136
+ Then,
137
+ Check
138
+ ) => {
139
+ return [
140
+ Suite.Default(
141
+ "Testing the Rectangle class",
142
+ {
143
+ test0: Given.Default(
144
+ ["https://api.github.com/repos/adamwong246/testeranto/issues/8"],
145
+ [],
146
+ [Then.getWidth(2)]
147
+ ),
148
+ test1: Given.Default(
149
+ [`Rectangles have width and height.`],
150
+ [When.setWidth(4), When.setHeight(5)],
151
+ [Then.getWidth(4), Then.getHeight(5), Then.area(20)]
152
+ ),
153
+ },
154
+
155
+ // Ignore this for now
156
+ []
157
+ ),
158
+ ];
159
+ };</code></pre><h4>The Implementation (ITestImplementation)</h4>
160
+ <p>The Implementation provides the concrete operations that bring specifications to life. This is where you define <strong>how</strong> each test step actually works.</p>
161
+ <ul>
162
+ <li><code>suites</code>: Test grouping and organization</li>
163
+ <li><code>givens</code>: Initial test states/setup</li>
164
+ <li><code>whens</code>: Actions that change state</li>
165
+ <li><code>thens</code>: Assertions and validations</li>
166
+ <li><code>checks</code>: Additional verification points</li>
167
+ </ul>
168
+ <pre>import {
169
+ Ibdd_in,
170
+ Ibdd_out,
171
+ ITestImplementation,
172
+ } from "testeranto/src/CoreTypes";
173
+
174
+ // Note the type parameters I and O. These are important!
175
+ export const implementation: ITestImplementation<
176
+ I extends Ibdd_in,
177
+ O extends Ibdd_out,
178
+ M
179
+ > = {
180
+ suites: {
181
+ Default: "a default suite",
182
+ },
183
+
184
+ givens: {
185
+ Default: () => new Rectangle(2, 2),
186
+ WidthAndHeightOf: (width, height) => new Rectangle(width, height),
187
+ },
188
+
189
+ whens: {
190
+ setWidth: (width: number) => (rectangle) => {
191
+ rectangle.setWidth(width);
192
+ return rectangle;
193
+ },
194
+ setHeight: (height: number) => (rectangle) => {
195
+ rectangle.setHeight(height);
196
+ return rectangle;
197
+ },
198
+ },
199
+
200
+ thens: {
201
+ getWidth: (expectedWidth) => (rectangle) => {
202
+ assert.equal(rectangle.getWidth(), expectedWidth);
203
+ return rectangle;
204
+ },
205
+ getHeight: (expectedHeight) => (rectangle) => {
206
+ assert.equal(rectangle.getHeight(), expectedHeight);
207
+ return rectangle;
208
+ },
209
+ area: (area) => (rectangle) => {
210
+ assert.equal(rectangle.area(), area);
211
+ return rectangle;
212
+ },
213
+ circumference: (circumference: number) => (rectangle: Rectangle) => {
214
+ assert.equal(rectangle.circumference(), circumference);
215
+ return rectangle;
216
+ },
217
+ },
218
+
219
+ checks: {
220
+ Default: () => new Rectangle(2, 2),
221
+ },
222
+ };</pre><h4>The Interface aka ITestInterface</h4>
223
+ <p>The test interface is code which is NOT BDD . The interface adapts your test subject so that the BDD hooks can be applied. The interface implements the traditional BDD steps &quot;before all&quot;, &quot;after all&quot;, &quot;before each&quot;, &quot;after each&quot;, etc</p>
224
+ <pre>
225
+ import {
226
+ Ibdd_in,
227
+ ITestInterface,
228
+ } from "testeranto/src/CoreTypes";
229
+
230
+ // Note the type parameter. This is important!
231
+ export const testInterface: ITestInterface<
232
+ I extends Ibdd_in,
233
+ > = {
234
+ beforeEach: async (subject, i) => {
235
+ return i();
236
+ },
237
+ andWhen: async function (s, whenCB, tr, utils) {
238
+ return whenCB(s, utils);
239
+ },
240
+ butThen: async (s, t, tr, pm) => {
241
+ return t(s, pm);
242
+ },
243
+ afterEach: (z) => {
244
+ return z;
245
+ },
246
+ afterAll: () => {},
247
+ assertThis: (x: any, y) => {},
248
+ };</pre><h4>type I aka Ibdd_in</h4>
249
+ <p>this type describes the &quot;inner&quot; shape of your BDD tests.</p>
250
+ <pre>import { Ibdd_in } from "testeranto/src/CoreTypes";
251
+
252
+ // TODO this is inaccurate
253
+ export type I = Ibdd_in<
254
+ null,
255
+ null,
256
+ Rectangle,
257
+ Rectangle,
258
+ Rectangle,
259
+ (...x) => (rectangle: Rectangle, utils: IPM) => Rectangle,
260
+ (rectangle: Rectangle, utils: IPM) => Rectangle
261
+ >;</pre><h4>type O aka Ibdd_out</h4>
262
+ <p>this type describes the &quot;outer&quot; shape of your BDD tests.</p>
263
+ <pre>import { Ibdd_out } from "testeranto/src/CoreTypes";
264
+
265
+ export type O = Ibdd_out<
266
+ // Suite
267
+ {
268
+ Default: [string];
269
+ },
270
+ // "Given" are initial states
271
+ {
272
+ Default;
273
+ WidthOfOneAndHeightOfOne;
274
+ WidthAndHeightOf: [number, number];
275
+ },
276
+ // "Whens" are steps which change the state of the test subject
277
+ {
278
+ HeightIsPubliclySetTo: [number];
279
+ WidthIsPubliclySetTo: [number];
280
+ setWidth: [number];
281
+ setHeight: [number];
282
+ },
283
+ // "Thens" are steps which make assertions of the test subject
284
+ {
285
+ AreaPlusCircumference: [number];
286
+ circumference: [number];
287
+ getWidth: [number];
288
+ getHeight: [number];
289
+ area: [number];
290
+ prototype: [];
291
+ },
292
+ // "Checks" are similar to "Givens"
293
+ {
294
+ Default;
295
+ WidthOfOneAndHeightOfOne;
296
+ WidthAndHeightOf: [number, number];
297
+ }
298
+ >;</pre><h4>type M (optional)</h4>
299
+ <p>this type describes the modifications to the shape of the &quot;specification&quot;. It can be used to make your BDD tests DRYer but is not necessary</p>
300
+ <pre>export type M = {
301
+ givens: {
302
+ [K in keyof O["givens"]]: (...Iw: O["givens"][K]) => Rectangle;
303
+ };
304
+ whens: {
305
+ [K in keyof O["whens"]]: (
306
+ ...Iw: O["whens"][K]
307
+ ) => (rectangle: Rectangle, utils: PM) => Rectangle;
308
+ };
309
+ thens: {
310
+ [K in keyof O["thens"]]: (
311
+ ...Iw: O["thens"][K]
312
+ ) => (rectangle: Rectangle, utils: PM) => Rectangle;
313
+ };
314
+ };</pre><h2>Putting it all together</h2>
315
+ <pre>// Make sure you import the right runtime
316
+ import Testeranto from "testeranto/src/Pure";
317
+
318
+ import {
319
+ Ibdd_in,
320
+ Ibdd_out,
321
+ ITestImplementation,
322
+ ITestSpecification,
323
+ ITestInterface,
324
+ } from "testeranto/src/CoreTypes";
325
+
326
+ // The test subject
327
+ class Rectangle {
328
+ constructor(public width: number, public height: number) {}
329
+
330
+ setWidth(w: number) {
331
+ this.width = w;
332
+ }
333
+ setHeight(h: number) {
334
+ this.height = h;
335
+ }
336
+ getArea() {
337
+ return this.width * this.height;
338
+ }
339
+ }
340
+
341
+ ////////////////////////////////////////////////////////
342
+
343
+ // TODO this is inaccurate
344
+ type I = Ibdd_in<
345
+ null,
346
+ null,
347
+ Rectangle,
348
+ Rectangle,
349
+ Rectangle,
350
+ (...x) => (rectangle: Rectangle, utils: IPM) => Rectangle,
351
+ (rectangle: Rectangle, utils: IPM) => Rectangle
352
+ >;
353
+
354
+ type O = Ibdd_out<
355
+ // Suites
356
+ {
357
+ Default: [string];
358
+ },
359
+ // Givens
360
+ {
361
+ Default;
362
+ WidthOfOneAndHeightOfOne;
363
+ WidthAndHeightOf: [number, number];
364
+ },
365
+ // Whens
366
+ {
367
+ HeightIsPubliclySetTo: [number];
368
+ WidthIsPubliclySetTo: [number];
369
+ setWidth: [number];
370
+ setHeight: [number];
371
+ },
372
+ // Thens
373
+ {
374
+ AreaPlusCircumference: [number];
375
+ circumference: [number];
376
+ getWidth: [number];
377
+ getHeight: [number];
378
+ area: [number];
379
+ prototype: [];
380
+ },
381
+ // Checks are broken right now, ignore them
382
+ {
383
+ Default;
384
+ WidthOfOneAndHeightOfOne;
385
+ WidthAndHeightOf: [number, number];
386
+ }
387
+ >;
388
+
389
+ type M = {
390
+ givens: {
391
+ [K in keyof O["givens"]]: (...Iw: O["givens"][K]) => Rectangle;
392
+ };
393
+ whens: {
394
+ [K in keyof O["whens"]]: (
395
+ ...Iw: O["whens"][K]
396
+ ) => (rectangle: Rectangle, utils: PM) => Rectangle;
397
+ };
398
+ thens: {
399
+ [K in keyof O["thens"]]: (
400
+ ...Iw: O["thens"][K]
401
+ ) => (rectangle: Rectangle, utils: PM) => Rectangle;
402
+ };
403
+ };
404
+
405
+ const testInterface: ITestInterface<
406
+ I extends Ibdd_in,
407
+ > = {
408
+ beforeEach: async (subject, i) => {
409
+ return i();
410
+ },
411
+ andWhen: async function (s, whenCB, tr, utils) {
412
+ return whenCB(s, utils);
413
+ },
414
+ butThen: async (s, t, tr, pm) => {
415
+ return t(s, pm);
416
+ },
417
+ afterEach: (z) => {
418
+ return z;
419
+ },
420
+ afterAll: () => {},
421
+ assertThis: (x: any, y) => {},
422
+ };
423
+
424
+ const testImplementation: ITestImplementation<
425
+ I extends Ibdd_in,
426
+ O extends Ibdd_out,
427
+ M
428
+ > = {
429
+ suites: {
430
+ Default: "a default suite",
431
+ },
432
+
433
+ givens: {
434
+ Default: () => new Rectangle(2, 2),
435
+ WidthAndHeightOf: (width, height) => new Rectangle(width, height),
436
+ },
437
+
438
+ whens: {
439
+ setWidth: (width: number) => (rectangle) => {
440
+ rectangle.setWidth(width);
441
+ return rectangle;
442
+ },
443
+ setHeight: (height: number) => (rectangle) => {
444
+ rectangle.setHeight(height);
445
+ return rectangle;
446
+ },
447
+ },
448
+
449
+ thens: {
450
+ getWidth: (expectedWidth) => (rectangle) => {
451
+ assert.equal(rectangle.getWidth(), expectedWidth);
452
+ return rectangle;
453
+ },
454
+ getHeight: (expectedHeight) => (rectangle) => {
455
+ assert.equal(rectangle.getHeight(), expectedHeight);
456
+ return rectangle;
457
+ },
458
+ area: (area) => (rectangle) => {
459
+ assert.equal(rectangle.area(), area);
460
+ return rectangle;
461
+ },
462
+ circumference: (circumference: number) => (rectangle: Rectangle) => {
463
+ assert.equal(rectangle.circumference(), circumference);
464
+ return rectangle;
465
+ },
466
+ },
467
+
468
+ checks: {
469
+ Default: () => new Rectangle(2, 2),
470
+ },
471
+ };
472
+
473
+ const testSpecification: ITestSpecification<
474
+ I extends Ibdd_in,
475
+ O extends Ibdd_out,
476
+ > = (
477
+ Suite,
478
+ Given,
479
+ When,
480
+ Then,
481
+ Check
482
+ ) => {
483
+ return [
484
+ Suite.Default(
485
+ "Testing the Rectangle class",
486
+ {
487
+ test0: Given.Default(
488
+ ["https://api.github.com/repos/adamwong246/testeranto/issues/8"],
489
+ [],
490
+ [Then.getWidth(2)]
491
+ ),
492
+ test1: Given.Default(
493
+ [`Rectangles have width and height.`],
494
+ [When.setWidth(4), When.setHeight(5)],
495
+ [Then.getWidth(4), Then.getHeight(5), Then.area(20)]
496
+ ),
497
+ },
498
+
499
+ // Ignore this for now
500
+ []
501
+ ),
502
+ ];
503
+ };
504
+
505
+ // 1 function will launch the test
506
+ export default Testeranto<
507
+ I extends Ibdd_in,
508
+ O extends Ibdd_out,
509
+ M
510
+ >(
511
+ Rectangle.prototype,
512
+ testSpecification,
513
+ testSmplementation,
514
+ testSnterface
515
+ );
516
+
517
+
518
+ </pre>
519
+ </div>
520
+ <!-- Prism.js JS -->
521
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
522
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-typescript.min.js"></script>
523
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
524
+ <script>
525
+ document.addEventListener('DOMContentLoaded', function() {
526
+ Prism.highlightAll();
527
+
528
+ // Parallax effect
529
+ const parallaxBg = document.querySelector('.parallax-background');
530
+ window.addEventListener('scroll', function() {
531
+ const scrollPosition = window.pageYOffset;
532
+ parallaxBg.style.transform = 'translateY(scrollPosition)';
533
+ });
534
+ });
535
+ </script>
536
+ </body>
537
+ </html>