@neurodevs/node-tdd 0.2.5 → 1.0.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 (326) hide show
  1. package/.vscode/launch.json +52 -57
  2. package/.vscode/settings.json +61 -66
  3. package/.vscode/tasks.json +98 -129
  4. package/README.md +1 -0
  5. package/build/.spruce/settings.json +3 -10
  6. package/build/__tests__/MockFetch.d.ts +18 -0
  7. package/build/__tests__/MockFetch.js +55 -0
  8. package/build/__tests__/MockFetch.js.map +1 -0
  9. package/build/__tests__/{impl → behavioral}/AbstractModuleTest.test.d.ts +2 -3
  10. package/build/__tests__/{impl → behavioral}/AbstractModuleTest.test.js +3 -12
  11. package/build/__tests__/behavioral/AbstractModuleTest.test.js.map +1 -0
  12. package/build/__tests__/behavioral/utilities/AllHooksCalledEvenIfNotDefined.test.d.ts +5 -0
  13. package/build/__tests__/behavioral/utilities/AllHooksCalledEvenIfNotDefined.test.js +34 -0
  14. package/build/__tests__/behavioral/utilities/AllHooksCalledEvenIfNotDefined.test.js.map +1 -0
  15. package/build/__tests__/behavioral/utilities/Assert.test.d.ts +45 -0
  16. package/build/__tests__/behavioral/utilities/Assert.test.js +645 -0
  17. package/build/__tests__/behavioral/utilities/Assert.test.js.map +1 -0
  18. package/build/__tests__/behavioral/utilities/InstanceParentTestCanAccessParentMethods.test.d.ts +4 -0
  19. package/build/__tests__/behavioral/utilities/InstanceParentTestCanAccessParentMethods.test.js +23 -0
  20. package/build/__tests__/behavioral/utilities/InstanceParentTestCanAccessParentMethods.test.js.map +1 -0
  21. package/build/__tests__/behavioral/utilities/MockFetch.test.d.ts +28 -0
  22. package/build/__tests__/behavioral/utilities/MockFetch.test.js +211 -0
  23. package/build/__tests__/behavioral/utilities/MockFetch.test.js.map +1 -0
  24. package/build/__tests__/behavioral/utilities/StackCleaner.test.d.ts +4 -0
  25. package/build/__tests__/behavioral/utilities/StackCleaner.test.js +46 -0
  26. package/build/__tests__/behavioral/utilities/StackCleaner.test.js.map +1 -0
  27. package/build/__tests__/behavioral/utilities/StaticParentTestCanAccessParentMethods.test.d.ts +7 -0
  28. package/build/__tests__/behavioral/utilities/StaticParentTestCanAccessParentMethods.test.js +32 -0
  29. package/build/__tests__/behavioral/utilities/StaticParentTestCanAccessParentMethods.test.js.map +1 -0
  30. package/build/__tests__/behavioral/utilities/StaticTestInheritsAbstractSpruceTestProperly.test.d.ts +4 -0
  31. package/build/__tests__/behavioral/utilities/StaticTestInheritsAbstractSpruceTestProperly.test.js +19 -0
  32. package/build/__tests__/behavioral/utilities/StaticTestInheritsAbstractSpruceTestProperly.test.js.map +1 -0
  33. package/build/__tests__/behavioral/utilities/Stringify.test.d.ts +5 -0
  34. package/build/__tests__/behavioral/utilities/Stringify.test.js +127 -0
  35. package/build/__tests__/behavioral/utilities/Stringify.test.js.map +1 -0
  36. package/build/__tests__/behavioral/utilities/TestDecoratorResolver.test.d.ts +7 -0
  37. package/build/__tests__/behavioral/utilities/TestDecoratorResolver.test.js +38 -0
  38. package/build/__tests__/behavioral/utilities/TestDecoratorResolver.test.js.map +1 -0
  39. package/build/__tests__/behavioral/utilities/TestOnBasic.test.d.ts +12 -0
  40. package/build/__tests__/behavioral/utilities/TestOnBasic.test.js +68 -0
  41. package/build/__tests__/behavioral/utilities/TestOnBasic.test.js.map +1 -0
  42. package/build/__tests__/behavioral/utilities/TestOnInstance.test.d.ts +28 -0
  43. package/build/__tests__/behavioral/utilities/TestOnInstance.test.js +289 -0
  44. package/build/__tests__/behavioral/utilities/TestOnInstance.test.js.map +1 -0
  45. package/build/__tests__/behavioral/utilities/TestOnInstanceExtendsTest.test.d.ts +9 -0
  46. package/build/__tests__/behavioral/utilities/TestOnInstanceExtendsTest.test.js +118 -0
  47. package/build/__tests__/behavioral/utilities/TestOnInstanceExtendsTest.test.js.map +1 -0
  48. package/build/__tests__/behavioral/utilities/TestOnInstanceExtendsTestWithHooks.test.d.ts +5 -0
  49. package/build/__tests__/behavioral/utilities/TestOnInstanceExtendsTestWithHooks.test.js +78 -0
  50. package/build/__tests__/behavioral/utilities/TestOnInstanceExtendsTestWithHooks.test.js.map +1 -0
  51. package/build/__tests__/behavioral/utilities/TestOnInstanceWithParentBeforeAll.test.d.ts +4 -0
  52. package/build/__tests__/behavioral/utilities/TestOnInstanceWithParentBeforeAll.test.js +23 -0
  53. package/build/__tests__/behavioral/utilities/TestOnInstanceWithParentBeforeAll.test.js.map +1 -0
  54. package/build/__tests__/behavioral/utilities/TestOnInstanceWithTwoLevelsOfInheritence.test.d.ts +4 -0
  55. package/build/__tests__/behavioral/utilities/TestOnInstanceWithTwoLevelsOfInheritence.test.js +24 -0
  56. package/build/__tests__/behavioral/utilities/TestOnInstanceWithTwoLevelsOfInheritence.test.js.map +1 -0
  57. package/build/__tests__/behavioral/utilities/TestResolver.test.d.ts +7 -0
  58. package/build/__tests__/behavioral/utilities/TestResolver.test.js +38 -0
  59. package/build/__tests__/behavioral/utilities/TestResolver.test.js.map +1 -0
  60. package/build/__tests__/behavioral/utilities/TestResolverOnStatic.test.d.ts +4 -0
  61. package/build/__tests__/behavioral/utilities/TestResolverOnStatic.test.js +20 -0
  62. package/build/__tests__/behavioral/utilities/TestResolverOnStatic.test.js.map +1 -0
  63. package/build/__tests__/behavioral/workspace/JestJsonParser.test.d.ts +18 -0
  64. package/build/__tests__/behavioral/workspace/JestJsonParser.test.js +267 -0
  65. package/build/__tests__/behavioral/workspace/JestJsonParser.test.js.map +1 -0
  66. package/build/__tests__/behavioral/workspace/TestReporter.test.d.ts +16 -0
  67. package/build/__tests__/behavioral/workspace/TestReporter.test.js +227 -0
  68. package/build/__tests__/behavioral/workspace/TestReporter.test.js.map +1 -0
  69. package/build/__tests__/behavioral/workspace/TestRunner.test.d.ts +15 -0
  70. package/build/__tests__/behavioral/workspace/TestRunner.test.js +99 -0
  71. package/build/__tests__/behavioral/workspace/TestRunner.test.js.map +1 -0
  72. package/build/__tests__/behavioral/workspace/Widgets.test.d.ts +13 -0
  73. package/build/__tests__/behavioral/workspace/Widgets.test.js +99 -0
  74. package/build/__tests__/behavioral/workspace/Widgets.test.js.map +1 -0
  75. package/build/__tests__/mock-terminal-kit.d.ts +79 -0
  76. package/build/__tests__/mock-terminal-kit.js +103 -0
  77. package/build/__tests__/mock-terminal-kit.js.map +1 -0
  78. package/build/__tests__/support/AbstractForInstanceTest.d.ts +4 -0
  79. package/build/__tests__/support/AbstractForInstanceTest.js +9 -0
  80. package/build/__tests__/support/AbstractForInstanceTest.js.map +1 -0
  81. package/build/__tests__/support/AbstractLevelOneTest.d.ts +3 -0
  82. package/build/__tests__/support/AbstractLevelOneTest.js +4 -0
  83. package/build/__tests__/support/AbstractLevelOneTest.js.map +1 -0
  84. package/build/__tests__/support/AbstractLevelTwoTest.d.ts +7 -0
  85. package/build/__tests__/support/AbstractLevelTwoTest.js +14 -0
  86. package/build/__tests__/support/AbstractLevelTwoTest.js.map +1 -0
  87. package/build/__tests__/support/AbstractStaticTest.d.ts +7 -0
  88. package/build/__tests__/support/AbstractStaticTest.js +14 -0
  89. package/build/__tests__/support/AbstractStaticTest.js.map +1 -0
  90. package/build/__tests__/support/AbstractTestOnInstanceTest.d.ts +22 -0
  91. package/build/__tests__/support/AbstractTestOnInstanceTest.js +23 -0
  92. package/build/__tests__/support/AbstractTestOnInstanceTest.js.map +1 -0
  93. package/build/__tests__/support/AbstractTestOnInstanceWithHooks.d.ts +26 -0
  94. package/build/__tests__/support/AbstractTestOnInstanceWithHooks.js +59 -0
  95. package/build/__tests__/support/AbstractTestOnInstanceWithHooks.js.map +1 -0
  96. package/build/__tests__/support/jest.setup.d.ts +1 -0
  97. package/build/__tests__/support/jest.setup.js +4 -0
  98. package/build/__tests__/support/jest.setup.js.map +1 -0
  99. package/build/__tests__/support/onTestFileResult.d.ts +244 -0
  100. package/build/__tests__/support/onTestFileResult.js +980 -0
  101. package/build/__tests__/support/onTestFileResult.js.map +1 -0
  102. package/build/impl/AbstractModuleTest.d.ts +18 -4
  103. package/build/impl/AbstractModuleTest.js +47 -9
  104. package/build/impl/AbstractModuleTest.js.map +1 -1
  105. package/build/index.d.ts +4 -4
  106. package/build/index.js +4 -4
  107. package/build/index.js.map +1 -1
  108. package/build/utilities/AssertionError.d.ts +3 -0
  109. package/build/utilities/AssertionError.js +12 -0
  110. package/build/utilities/AssertionError.js.map +1 -0
  111. package/build/utilities/StackCleaner.d.ts +4 -0
  112. package/build/utilities/StackCleaner.js +10 -0
  113. package/build/utilities/StackCleaner.js.map +1 -0
  114. package/build/utilities/TestDecoratorResolver.d.ts +35 -0
  115. package/build/utilities/TestDecoratorResolver.js +93 -0
  116. package/build/utilities/TestDecoratorResolver.js.map +1 -0
  117. package/build/utilities/assert.d.ts +49 -0
  118. package/build/utilities/assert.js +255 -0
  119. package/build/utilities/assert.js.map +1 -0
  120. package/build/utilities/assert.utility.d.ts +28 -0
  121. package/build/utilities/assert.utility.js +185 -0
  122. package/build/utilities/assert.utility.js.map +1 -0
  123. package/build/utilities/decorators.d.ts +9 -0
  124. package/build/utilities/decorators.js +133 -0
  125. package/build/utilities/decorators.js.map +1 -0
  126. package/build/workspace/CommandService.d.ts +49 -0
  127. package/build/workspace/CommandService.js +179 -0
  128. package/build/workspace/CommandService.js.map +1 -0
  129. package/build/workspace/JestJsonParser.d.ts +15 -0
  130. package/build/workspace/JestJsonParser.js +149 -0
  131. package/build/workspace/JestJsonParser.js.map +1 -0
  132. package/build/workspace/TKButtonWidget.d.ts +13 -0
  133. package/build/workspace/TKButtonWidget.js +37 -0
  134. package/build/workspace/TKButtonWidget.js.map +1 -0
  135. package/build/workspace/TestLogItemGenerator.d.ts +15 -0
  136. package/build/workspace/TestLogItemGenerator.js +142 -0
  137. package/build/workspace/TestLogItemGenerator.js.map +1 -0
  138. package/build/workspace/TestReporter.d.ts +103 -0
  139. package/build/workspace/TestReporter.js +677 -0
  140. package/build/workspace/TestReporter.js.map +1 -0
  141. package/build/workspace/TestRunner.d.ts +24 -0
  142. package/build/workspace/TestRunner.js +95 -0
  143. package/build/workspace/TestRunner.js.map +1 -0
  144. package/build/workspace/TkBaseWidget.d.ts +37 -0
  145. package/build/workspace/TkBaseWidget.js +185 -0
  146. package/build/workspace/TkBaseWidget.js.map +1 -0
  147. package/build/workspace/TkInputWidget.d.ts +16 -0
  148. package/build/workspace/TkInputWidget.js +64 -0
  149. package/build/workspace/TkInputWidget.js.map +1 -0
  150. package/build/workspace/TkLayoutCellWidget.d.ts +18 -0
  151. package/build/workspace/TkLayoutCellWidget.js +32 -0
  152. package/build/workspace/TkLayoutCellWidget.js.map +1 -0
  153. package/build/workspace/TkLayoutWidget.d.ts +34 -0
  154. package/build/workspace/TkLayoutWidget.js +130 -0
  155. package/build/workspace/TkLayoutWidget.js.map +1 -0
  156. package/build/workspace/TkMenuBarWidget.d.ts +13 -0
  157. package/build/workspace/TkMenuBarWidget.js +71 -0
  158. package/build/workspace/TkMenuBarWidget.js.map +1 -0
  159. package/build/workspace/TkPopupWidget.d.ts +16 -0
  160. package/build/workspace/TkPopupWidget.js +36 -0
  161. package/build/workspace/TkPopupWidget.js.map +1 -0
  162. package/build/workspace/TkProgressBarWidget.d.ts +10 -0
  163. package/build/workspace/TkProgressBarWidget.js +39 -0
  164. package/build/workspace/TkProgressBarWidget.js.map +1 -0
  165. package/build/workspace/TkTextWidget.d.ts +20 -0
  166. package/build/workspace/TkTextWidget.js +115 -0
  167. package/build/workspace/TkTextWidget.js.map +1 -0
  168. package/build/workspace/TkWindowWidget.d.ts +22 -0
  169. package/build/workspace/TkWindowWidget.js +88 -0
  170. package/build/workspace/TkWindowWidget.js.map +1 -0
  171. package/build/workspace/WidgetFactory.d.ts +6 -0
  172. package/build/workspace/WidgetFactory.js +21 -0
  173. package/build/workspace/WidgetFactory.js.map +1 -0
  174. package/build/workspace/button.types.d.ts +15 -0
  175. package/build/workspace/button.types.js +6 -0
  176. package/build/workspace/button.types.js.map +1 -0
  177. package/build/workspace/duration.utility.d.ts +4 -0
  178. package/build/workspace/duration.utility.js +26 -0
  179. package/build/workspace/duration.utility.js.map +1 -0
  180. package/build/workspace/factory.types.d.ts +89 -0
  181. package/build/workspace/factory.types.js +37 -0
  182. package/build/workspace/factory.types.js.map +1 -0
  183. package/build/workspace/input.types.d.ts +18 -0
  184. package/build/workspace/input.types.js +7 -0
  185. package/build/workspace/input.types.js.map +1 -0
  186. package/build/workspace/keySelectChoices.d.ts +517 -0
  187. package/build/workspace/keySelectChoices.js +2 -0
  188. package/build/workspace/keySelectChoices.js.map +1 -0
  189. package/build/workspace/layout.types.d.ts +33 -0
  190. package/build/workspace/layout.types.js +2 -0
  191. package/build/workspace/layout.types.js.map +1 -0
  192. package/build/workspace/menuBar.types.d.ts +19 -0
  193. package/build/workspace/menuBar.types.js +6 -0
  194. package/build/workspace/menuBar.types.js.map +1 -0
  195. package/build/workspace/popup.types.d.ts +13 -0
  196. package/build/workspace/popup.types.js +6 -0
  197. package/build/workspace/popup.types.js.map +1 -0
  198. package/build/workspace/progressBar.types.d.ts +10 -0
  199. package/build/workspace/progressBar.types.js +2 -0
  200. package/build/workspace/progressBar.types.js.map +1 -0
  201. package/build/workspace/table.types.d.ts +6 -0
  202. package/build/workspace/table.types.js +2 -0
  203. package/build/workspace/table.types.js.map +1 -0
  204. package/build/workspace/termKit.utility.d.ts +12 -0
  205. package/build/workspace/termKit.utility.js +128 -0
  206. package/build/workspace/termKit.utility.js.map +1 -0
  207. package/build/workspace/test.types.d.ts +24 -0
  208. package/build/workspace/test.types.js +2 -0
  209. package/build/workspace/test.types.js.map +1 -0
  210. package/build/workspace/testRunner.cli.d.ts +1 -0
  211. package/build/workspace/testRunner.cli.js +149 -0
  212. package/build/workspace/testRunner.cli.js.map +1 -0
  213. package/build/workspace/text.types.d.ts +20 -0
  214. package/build/workspace/text.types.js +7 -0
  215. package/build/workspace/text.types.js.map +1 -0
  216. package/build/workspace/widget.utilities.d.ts +5 -0
  217. package/build/workspace/widget.utilities.js +20 -0
  218. package/build/workspace/widget.utilities.js.map +1 -0
  219. package/build/workspace/widgets.types.d.ts +66 -0
  220. package/build/workspace/widgets.types.js +2 -0
  221. package/build/workspace/widgets.types.js.map +1 -0
  222. package/build/workspace/window.types.d.ts +18 -0
  223. package/build/workspace/window.types.js +9 -0
  224. package/build/workspace/window.types.js.map +1 -0
  225. package/eslint.config.js +3 -0
  226. package/package.json +30 -37
  227. package/prettier.config.js +3 -0
  228. package/src/.spruce/settings.json +3 -10
  229. package/src/__tests__/MockFetch.ts +100 -0
  230. package/src/__tests__/behavioral/AbstractModuleTest.test.ts +15 -0
  231. package/src/__tests__/behavioral/utilities/AllHooksCalledEvenIfNotDefined.test.ts +31 -0
  232. package/src/__tests__/behavioral/utilities/Assert.test.ts +826 -0
  233. package/src/__tests__/behavioral/utilities/InstanceParentTestCanAccessParentMethods.test.ts +14 -0
  234. package/src/__tests__/behavioral/utilities/MockFetch.test.ts +240 -0
  235. package/src/__tests__/behavioral/utilities/StackCleaner.test.ts +46 -0
  236. package/src/__tests__/behavioral/utilities/StaticParentTestCanAccessParentMethods.test.ts +34 -0
  237. package/src/__tests__/behavioral/utilities/StaticTestInheritsAbstractSpruceTestProperly.test.ts +11 -0
  238. package/src/__tests__/behavioral/utilities/Stringify.test.ts +169 -0
  239. package/src/__tests__/behavioral/utilities/TestDecoratorResolver.test.ts +51 -0
  240. package/src/__tests__/behavioral/utilities/TestOnBasic.test.ts +62 -0
  241. package/src/__tests__/behavioral/utilities/TestOnInstance.test.ts +439 -0
  242. package/src/__tests__/behavioral/utilities/TestOnInstanceExtendsTest.test.ts +237 -0
  243. package/src/__tests__/behavioral/utilities/TestOnInstanceExtendsTestWithHooks.test.ts +85 -0
  244. package/src/__tests__/behavioral/utilities/TestOnInstanceWithParentBeforeAll.test.ts +14 -0
  245. package/src/__tests__/behavioral/utilities/TestOnInstanceWithTwoLevelsOfInheritence.test.ts +16 -0
  246. package/src/__tests__/behavioral/utilities/TestResolver.test.ts +48 -0
  247. package/src/__tests__/behavioral/utilities/TestResolverOnStatic.test.ts +12 -0
  248. package/src/__tests__/behavioral/workspace/JestJsonParser.test.ts +357 -0
  249. package/src/__tests__/behavioral/workspace/TestReporter.test.ts +257 -0
  250. package/src/__tests__/behavioral/workspace/TestRunner.test.ts +87 -0
  251. package/src/__tests__/behavioral/workspace/Widgets.test.ts +90 -0
  252. package/src/__tests__/mock-terminal-kit.ts +115 -0
  253. package/src/__tests__/support/AbstractForInstanceTest.ts +12 -0
  254. package/src/__tests__/support/AbstractLevelOneTest.ts +3 -0
  255. package/src/__tests__/support/AbstractLevelTwoTest.ts +16 -0
  256. package/src/__tests__/support/AbstractStaticTest.ts +16 -0
  257. package/src/__tests__/support/AbstractTestOnInstanceTest.ts +30 -0
  258. package/src/__tests__/support/AbstractTestOnInstanceWithHooks.ts +138 -0
  259. package/src/__tests__/support/jest.setup.ts +2 -0
  260. package/src/__tests__/support/onTestFileResult.ts +1008 -0
  261. package/src/impl/AbstractModuleTest.ts +59 -10
  262. package/src/index.ts +4 -4
  263. package/src/utilities/AssertionError.ts +14 -0
  264. package/src/utilities/StackCleaner.ts +14 -0
  265. package/src/utilities/TestDecoratorResolver.ts +118 -0
  266. package/src/utilities/assert.ts +583 -0
  267. package/src/utilities/assert.utility.ts +295 -0
  268. package/src/utilities/decorators.ts +167 -0
  269. package/src/workspace/CommandService.ts +256 -0
  270. package/src/workspace/JestJsonParser.ts +255 -0
  271. package/src/workspace/TKButtonWidget.ts +54 -0
  272. package/src/workspace/TestLogItemGenerator.ts +184 -0
  273. package/src/workspace/TestReporter.ts +865 -0
  274. package/src/workspace/TestRunner.ts +128 -0
  275. package/src/workspace/TkBaseWidget.ts +249 -0
  276. package/src/workspace/TkInputWidget.ts +83 -0
  277. package/src/workspace/TkLayoutCellWidget.ts +46 -0
  278. package/src/workspace/TkLayoutWidget.ts +181 -0
  279. package/src/workspace/TkMenuBarWidget.ts +95 -0
  280. package/src/workspace/TkPopupWidget.ts +47 -0
  281. package/src/workspace/TkProgressBarWidget.ts +54 -0
  282. package/src/workspace/TkTextWidget.ts +158 -0
  283. package/src/workspace/TkWindowWidget.ts +122 -0
  284. package/src/workspace/WidgetFactory.ts +33 -0
  285. package/src/workspace/button.types.ts +19 -0
  286. package/src/workspace/duration.utility.ts +34 -0
  287. package/src/workspace/factory.types.ts +101 -0
  288. package/src/workspace/input.types.ts +22 -0
  289. package/src/workspace/keySelectChoices.ts +134 -0
  290. package/src/workspace/layout.types.ts +40 -0
  291. package/src/workspace/menuBar.types.ts +24 -0
  292. package/src/workspace/popup.types.ts +17 -0
  293. package/src/workspace/progressBar.types.ts +13 -0
  294. package/src/workspace/table.types.ts +9 -0
  295. package/src/workspace/termKit.utility.ts +130 -0
  296. package/src/workspace/terminal-kit.d.ts +28 -0
  297. package/src/workspace/test.types.ts +34 -0
  298. package/src/workspace/testRunner.cli.ts +159 -0
  299. package/src/workspace/text.types.ts +26 -0
  300. package/src/workspace/widget.utilities.ts +35 -0
  301. package/src/workspace/widgets.types.ts +102 -0
  302. package/src/workspace/window.types.ts +22 -0
  303. package/tsconfig.json +23 -27
  304. package/build/__tests__/AbstractPackageTest.d.ts +0 -4
  305. package/build/__tests__/AbstractPackageTest.js +0 -7
  306. package/build/__tests__/AbstractPackageTest.js.map +0 -1
  307. package/build/__tests__/functions/assertFunction.test.d.ts +0 -5
  308. package/build/__tests__/functions/assertFunction.test.js +0 -23
  309. package/build/__tests__/functions/assertFunction.test.js.map +0 -1
  310. package/build/__tests__/functions/testFunction.test.d.ts +0 -5
  311. package/build/__tests__/functions/testFunction.test.js +0 -23
  312. package/build/__tests__/functions/testFunction.test.js.map +0 -1
  313. package/build/__tests__/impl/AbstractModuleTest.test.js.map +0 -1
  314. package/build/functions/assert.d.ts +0 -3
  315. package/build/functions/assert.js +0 -4
  316. package/build/functions/assert.js.map +0 -1
  317. package/build/functions/test.d.ts +0 -3
  318. package/build/functions/test.js +0 -4
  319. package/build/functions/test.js.map +0 -1
  320. package/eslint.config.mjs +0 -3
  321. package/src/__tests__/AbstractPackageTest.ts +0 -7
  322. package/src/__tests__/functions/assertFunction.test.ts +0 -22
  323. package/src/__tests__/functions/testFunction.test.ts +0 -22
  324. package/src/__tests__/impl/AbstractModuleTest.test.ts +0 -34
  325. package/src/functions/assert.ts +0 -4
  326. package/src/functions/test.ts +0 -4
@@ -0,0 +1,295 @@
1
+ import chalk from 'chalk'
2
+ import { escapeRegExp, get, includes, isObject, isObjectLike } from 'lodash-es'
3
+ import AssertionError from './AssertionError.js'
4
+ import { Assert } from './assert.js'
5
+
6
+ export const UNDEFINED_PLACEHOLDER = '_____________undefined_____________'
7
+ export const FUNCTION_PLACEHOLDER = '_____________function_____________'
8
+ export const CIRCULAR_PLACEHOLDER = '_____________circular_____________'
9
+ export const NULL_PLACEHOLDER = '_____________null_____________'
10
+
11
+ const assertUtil = {
12
+ fail(message?: string, stack?: string) {
13
+ throw new AssertionError(message ?? 'Fail!', stack)
14
+ },
15
+
16
+ stringify(object: any): string {
17
+ let stringified
18
+
19
+ if (Array.isArray(object)) {
20
+ stringified = `[\n ${object.map((o) =>
21
+ this.stringify(o).split('\n').join('\n ')
22
+ )}\n]`
23
+ } else if (typeof object === 'number') {
24
+ // this hack allows the Test Reporter to render number errors (they got eaten by terminal-kit's style regex)
25
+ stringified = chalk.bgBlack.white(` ${object} `)
26
+ } else if (object instanceof Error) {
27
+ stringified = `${object.stack ?? object.message}`
28
+ } else if (object instanceof RegExp) {
29
+ stringified = `${object.toString()}`
30
+ } else if (typeof object === 'undefined') {
31
+ stringified = 'undefined'
32
+ } else if (typeof object === 'string') {
33
+ stringified = `"${object}"`
34
+ } else {
35
+ stringified = JSON.stringify(
36
+ assertUtil.dropInPlaceholders(object),
37
+ undefined,
38
+ 2
39
+ ).replace(/\\/g, '')
40
+ }
41
+
42
+ if (stringified.length > 5000) {
43
+ stringified =
44
+ stringified.substr(0, 1000) +
45
+ '\n\n... big object ...\n\n' +
46
+ stringified.substr(stringified.length - 1000)
47
+ }
48
+
49
+ stringified = assertUtil.replacePlaceholders(stringified)
50
+
51
+ return `${chalk.bold(stringified)}`
52
+ },
53
+
54
+ replacePlaceholders(str: string) {
55
+ return str
56
+ .replace(
57
+ new RegExp(`"${UNDEFINED_PLACEHOLDER}"`, 'g'),
58
+ chalk.italic('undefined')
59
+ )
60
+ .replace(
61
+ new RegExp(`"${FUNCTION_PLACEHOLDER}"`, 'g'),
62
+ chalk.italic('Function')
63
+ )
64
+ .replace(
65
+ new RegExp(`"${NULL_PLACEHOLDER}"`, 'g'),
66
+ chalk.italic('NULL')
67
+ )
68
+ },
69
+
70
+ dropInPlaceholders(obj: Record<string, any>) {
71
+ const checkedObjects: { obj: any; depth: number }[] = [
72
+ { obj, depth: 0 },
73
+ ]
74
+
75
+ let updated = this.dropInPlaceholder(
76
+ obj,
77
+ (obj, depth) => {
78
+ if (
79
+ isObject(obj) &&
80
+ checkedObjects.some((checked) => {
81
+ return checked.obj === obj && checked.depth < depth
82
+ })
83
+ ) {
84
+ return true
85
+ }
86
+
87
+ checkedObjects.push({ obj, depth })
88
+
89
+ return false
90
+ },
91
+ CIRCULAR_PLACEHOLDER
92
+ )
93
+
94
+ updated = this.dropInPlaceholder(
95
+ updated,
96
+ (obj) => typeof obj === 'undefined',
97
+ UNDEFINED_PLACEHOLDER
98
+ )
99
+
100
+ updated = this.dropInPlaceholder(
101
+ updated,
102
+ (obj) => typeof obj === 'function',
103
+ FUNCTION_PLACEHOLDER
104
+ )
105
+
106
+ updated = this.dropInPlaceholder(
107
+ updated,
108
+ (obj) => obj === null,
109
+ NULL_PLACEHOLDER
110
+ )
111
+
112
+ return updated
113
+ },
114
+
115
+ dropInPlaceholder(
116
+ obj: Record<string, any>,
117
+ checker: (obj: any, depth: number) => boolean,
118
+ placeholder: string,
119
+ depth = 1
120
+ ) {
121
+ if (!isObject(obj)) {
122
+ return obj
123
+ }
124
+ const updated: Record<string, any> | any[] = Array.isArray(obj)
125
+ ? []
126
+ : {}
127
+
128
+ Object.keys(obj).forEach((key) => {
129
+ //@ts-ignore
130
+ updated[key] =
131
+ // @ts-ignore
132
+ checker(obj[key], depth) ? placeholder : obj[key]
133
+
134
+ //@ts-ignore
135
+ if (typeof updated[key] !== 'function' && isObject(updated[key])) {
136
+ //@ts-ignore
137
+ updated[key] = this.dropInPlaceholder(
138
+ //@ts-ignore
139
+ updated[key],
140
+ checker,
141
+ placeholder,
142
+ depth + 1
143
+ )
144
+ }
145
+ })
146
+
147
+ return updated
148
+ },
149
+
150
+ doHaystacksPassCheck(
151
+ haystacks: any[],
152
+ needle: any,
153
+ check: Assert['doesInclude']
154
+ ) {
155
+ return !!haystacks.find((haystack) => {
156
+ try {
157
+ check(haystack, needle)
158
+ return true
159
+ } catch {
160
+ return false
161
+ }
162
+ })
163
+ },
164
+
165
+ assertTypeof(actual: any, type: string, message: string | undefined) {
166
+ if (typeof actual !== type) {
167
+ this.fail(message ?? `${JSON.stringify(actual)} is not a ${type}`)
168
+ }
169
+ },
170
+
171
+ assertErrorIncludes(
172
+ matcher: string | RegExp | undefined,
173
+ err: Error,
174
+ msg?: string | undefined
175
+ ) {
176
+ const originalErrorMessage = err.message ?? ''
177
+ const errorMessage = originalErrorMessage.toLowerCase()
178
+ const needle =
179
+ typeof matcher === 'string' ? matcher.toLowerCase() : matcher
180
+
181
+ if (
182
+ typeof needle === 'string' &&
183
+ errorMessage.search(needle) === -1 &&
184
+ !errorMessage.includes(needle)
185
+ ) {
186
+ this.fail(
187
+ msg ??
188
+ `Expected thrown error whose message contains: \n\n${chalk.bold(
189
+ matcher
190
+ )}\n\nbut got back:\n\n\`${chalk.bold(originalErrorMessage)}\`.`,
191
+ '\n\nStack: ' + err.stack
192
+ )
193
+ } else if (
194
+ needle instanceof RegExp &&
195
+ errorMessage.search(needle) === -1 &&
196
+ originalErrorMessage.search(needle) === -1
197
+ ) {
198
+ this.fail(
199
+ msg ??
200
+ `Expected thrown error whose message matches the regex: \n\n${chalk.bold(
201
+ matcher
202
+ )}\n\nbut got back:\n\n\`${chalk.bold(originalErrorMessage)}\`.`,
203
+ '\n\nStack: ' + err.stack
204
+ )
205
+ }
206
+ },
207
+
208
+ partialContains(object: any, subObject: any) {
209
+ const objProps = object ? Object.getOwnPropertyNames(object) : []
210
+ const subProps = subObject ? Object.getOwnPropertyNames(subObject) : []
211
+
212
+ if (objProps.length == 0 || subProps.length === 0) {
213
+ return
214
+ }
215
+
216
+ if (subProps.length > objProps.length) {
217
+ return false
218
+ }
219
+
220
+ for (const subProp of subProps) {
221
+ if (!Object.prototype.hasOwnProperty.call(object, subProp)) {
222
+ return false
223
+ }
224
+
225
+ if (
226
+ (!isObjectLike(object[subProp]) ||
227
+ !isObjectLike(subObject[subProp])) &&
228
+ object[subProp] !== subObject[subProp]
229
+ ) {
230
+ return false
231
+ }
232
+
233
+ if (
234
+ isObjectLike(object[subProp]) &&
235
+ isObjectLike(subObject[subProp]) &&
236
+ !this.partialContains(object[subProp], subObject[subProp])
237
+ ) {
238
+ return false
239
+ }
240
+ }
241
+
242
+ return true
243
+ },
244
+
245
+ valueAtPath(object: Record<string, any>, path: string) {
246
+ return get(object, path)
247
+ },
248
+
249
+ parseIncludeNeedle(needle: any): {
250
+ needleHasArrayNotation: boolean
251
+ path?: string
252
+ expected?: any
253
+ } {
254
+ const path = Object.keys(needle)[0]
255
+ const expected = path && needle[path]
256
+ const needleHasArrayNotation = !!(path && path.search(/\[\]\./) > -1)
257
+ return { needleHasArrayNotation, path, expected }
258
+ },
259
+
260
+ splitPathBasedOnArrayNotation(path: string, haystack: any) {
261
+ const pathParts = path.split('[].')
262
+ const pathToFirstArray = pathParts.shift() ?? ''
263
+ const pathAfterFirstArray = pathParts.join('[].')
264
+ const actualBeforeArray = this.valueAtPath(haystack, pathToFirstArray)
265
+ return { actualBeforeArray, pathAfterFirstArray }
266
+ },
267
+
268
+ foundUsing3rdPartyIncludes(
269
+ haystack: any,
270
+ needle: any,
271
+ isHaystackObject: boolean
272
+ ) {
273
+ let passed = false
274
+ const escapedNeedle =
275
+ typeof needle === 'string' ? escapeRegExp(needle) : needle
276
+ if (
277
+ typeof haystack === 'string' &&
278
+ typeof needle === 'string' &&
279
+ haystack.search(escapedNeedle) > -1
280
+ ) {
281
+ passed = true
282
+ }
283
+
284
+ if (isHaystackObject && includes(haystack, escapedNeedle)) {
285
+ passed = true
286
+ }
287
+
288
+ if (isHaystackObject && this.partialContains(haystack, escapedNeedle)) {
289
+ passed = true
290
+ }
291
+ return passed
292
+ },
293
+ }
294
+
295
+ export default assertUtil
@@ -0,0 +1,167 @@
1
+ import TestDecoratorResolver, {
2
+ TestLifecycleListeners,
3
+ } from './TestDecoratorResolver.js'
4
+
5
+ if (typeof it === 'undefined') {
6
+ //@ts-ignore
7
+ global.it = () => {}
8
+ }
9
+
10
+ let areLifecycleHooksInPlace = false
11
+
12
+ /** Hooks up before, after, etc. */
13
+ function hookupTestClassToJestLifecycle(Target: any) {
14
+ if (areLifecycleHooksInPlace) {
15
+ return
16
+ }
17
+
18
+ areLifecycleHooksInPlace = true
19
+ const hooks = ['beforeAll', 'beforeEach', 'afterAll', 'afterEach']
20
+ hooks.forEach((hook) => {
21
+ // @ts-ignore
22
+ if (global[hook]) {
23
+ // @ts-ignore
24
+ global[hook](async () => {
25
+ TestDecoratorResolver.resolveTestClass(Target)
26
+ if (hook === 'beforeEach') {
27
+ await TestLifecycleListeners.emitWillRunBeforeEach()
28
+ await runBeforeEach(Target)
29
+ await TestLifecycleListeners.emitDidRunBeforeEach()
30
+ } else if (hook === 'afterEach') {
31
+ await TestLifecycleListeners.emitWillRunAfterEach()
32
+ await runAfterEach(Target)
33
+ await TestLifecycleListeners.emitDidRunAfterEach()
34
+ TestDecoratorResolver.reset()
35
+ } else if (hook === 'beforeAll') {
36
+ await TestLifecycleListeners.emitWillRunBeforeAll()
37
+ await runBeforeAll(Target)
38
+ await TestLifecycleListeners.emitDidRunBeforeAll()
39
+ TestDecoratorResolver.reset()
40
+ } else if (hook === 'afterAll') {
41
+ await TestLifecycleListeners.emitWillRunAfterAll()
42
+ await runAfterAll(Target)
43
+ await TestLifecycleListeners.emitDidRunAfterAll()
44
+ }
45
+ })
46
+ }
47
+ })
48
+ }
49
+
50
+ async function runBeforeAll(Target: any) {
51
+ await callStaticHook(Target, 'beforeAll')
52
+ }
53
+
54
+ async function runAfterAll(Target: any) {
55
+ await callStaticHook(Target, 'afterAll')
56
+ }
57
+
58
+ async function callStaticHook(Target: any, hook: 'beforeAll' | 'afterAll') {
59
+ const Class =
60
+ TestDecoratorResolver.ActiveTestClass ??
61
+ (typeof Target === 'function' ? Target : Target.constructor)
62
+ const cb = Class?.[hook]
63
+ await cb?.call(Class)
64
+ }
65
+
66
+ async function runAfterEach(Target: any) {
67
+ if (TestDecoratorResolver.ActiveTestClass) {
68
+ const Resolved = TestDecoratorResolver.resolveTestClass(Target)
69
+ await Resolved.afterEach?.apply(Resolved)
70
+ } else if (Target.afterEach) {
71
+ await Target.afterEach?.apply?.(Target)
72
+ } else {
73
+ await Target?.constructor.afterEach?.apply?.(Target.constructor)
74
+ }
75
+ }
76
+
77
+ async function runBeforeEach(Target: any) {
78
+ if (TestDecoratorResolver.ActiveTestClass) {
79
+ const Resolved = TestDecoratorResolver.resolveTestClass(Target)
80
+ await Resolved.beforeEach?.apply(Resolved)
81
+ } else if (Target.beforeEach) {
82
+ await Target.beforeEach?.apply?.(Target)
83
+ } else {
84
+ await Target?.constructor.beforeEach?.apply?.(Target.constructor)
85
+ }
86
+ }
87
+
88
+ /** Test decorator */
89
+ export default function test(description?: string, ...args: any[]) {
90
+ return function (
91
+ Target: any,
92
+ propertyKey: string,
93
+ descriptor: PropertyDescriptor
94
+ ) {
95
+ hookupTestClassToJestLifecycle(Target)
96
+
97
+ it(description ?? propertyKey, async () => {
98
+ const Resolved = TestDecoratorResolver.resolveTestClass(Target)
99
+
100
+ if (!Resolved[propertyKey]) {
101
+ throw new Error(
102
+ `The test '${propertyKey}()' should NOT be static when tests run with suite(). Or, if you are not using suite(), you MUST make your test static.`
103
+ )
104
+ }
105
+
106
+ const bound = descriptor.value.bind(Resolved)
107
+
108
+ //@ts-ignore
109
+ global.activeTest = {
110
+ file: Target.name,
111
+ test: propertyKey,
112
+ }
113
+ return bound(...args)
114
+ })
115
+ }
116
+ }
117
+
118
+ export function suite() {
119
+ return function (Target: any) {
120
+ TestDecoratorResolver.ActiveTestClass = Target
121
+ }
122
+ }
123
+
124
+ /** Only decorator */
125
+ test.only = (description?: string, ...args: any[]) => {
126
+ return function (
127
+ target: any,
128
+ propertyKey: string,
129
+ descriptor: PropertyDescriptor
130
+ ) {
131
+ hookupTestClassToJestLifecycle(target)
132
+
133
+ it.only(description ?? propertyKey, async () => {
134
+ const bound = descriptor.value.bind(
135
+ TestDecoratorResolver.resolveTestClass(target)
136
+ )
137
+ return bound(...args)
138
+ })
139
+ }
140
+ }
141
+
142
+ /** Todo decorator */
143
+ test.todo = (description?: string, ..._args: any[]) => {
144
+ return function (target: any, propertyKey: string) {
145
+ hookupTestClassToJestLifecycle(target)
146
+
147
+ it.todo(description ?? propertyKey)
148
+ }
149
+ }
150
+
151
+ /** Skip decorator */
152
+ test.skip = (description?: string, ...args: any[]) => {
153
+ return function (
154
+ target: any,
155
+ propertyKey: string,
156
+ descriptor: PropertyDescriptor
157
+ ) {
158
+ hookupTestClassToJestLifecycle(target)
159
+
160
+ it.skip(description ?? propertyKey, async () => {
161
+ const bound = descriptor.value.bind(
162
+ TestDecoratorResolver.resolveTestClass(target)
163
+ )
164
+ return bound(...args)
165
+ })
166
+ }
167
+ }
@@ -0,0 +1,256 @@
1
+ import { spawn, SpawnOptions, ChildProcess } from 'child_process'
2
+ import { Writable } from 'stream'
3
+
4
+ process.setMaxListeners(100)
5
+
6
+ export default class CommandServiceImpl implements CommandService {
7
+ private cwd: string
8
+ private activeChildProcess: ChildProcess | undefined
9
+ private ignoreCloseErrors = false
10
+ private static fakeResponses: {
11
+ command: string | RegExp
12
+ response: FakedCommandResponse
13
+ }[] = []
14
+ private static commandsRunCapturedByMockResponses: string[] = []
15
+
16
+ public constructor(cwd: string) {
17
+ this.cwd = cwd
18
+ }
19
+
20
+ public getCwd() {
21
+ return this.cwd
22
+ }
23
+
24
+ public setCwd(cwd: string) {
25
+ this.cwd = cwd
26
+ }
27
+
28
+ public async execute(
29
+ cmd: string,
30
+ options?: ExecuteCommandOptions
31
+ ): Promise<{
32
+ stdout: string
33
+ }> {
34
+ const cwd = this.cwd
35
+ const args = options?.args || this.parseArgv(cmd)
36
+ const executable = options?.args ? cmd : args.shift()
37
+ const boundKill = this.kill.bind(this)
38
+
39
+ if (!executable) {
40
+ throw new Error('Bad params sent to command service')
41
+ }
42
+
43
+ const { mockResponse, mockKey } = this.getMockResponse(executable, args)
44
+
45
+ if (mockResponse) {
46
+ CommandServiceImpl.commandsRunCapturedByMockResponses.push(mockKey)
47
+ mockResponse.callback?.(executable, args)
48
+
49
+ if (mockResponse.code !== 0) {
50
+ throw new Error(
51
+ `Command failed: ${executable} ${args.join(' ')}`
52
+ )
53
+ }
54
+
55
+ return { stdout: mockResponse.stdout ?? '' }
56
+ }
57
+
58
+ process.on('exit', boundKill)
59
+
60
+ return new Promise((resolve, reject) => {
61
+ let stdout = ''
62
+ let stderr = ''
63
+ const spawnOptions: SpawnOptions = options?.shouldStream
64
+ ? {
65
+ stdio: 'inherit',
66
+ cwd,
67
+ env: {
68
+ PATH: process.env.PATH,
69
+ IS_CLI: 'true',
70
+ FORCE_COLOR: options?.forceColor ? '1' : '0',
71
+ ...options?.env,
72
+ },
73
+ }
74
+ : {
75
+ cwd,
76
+ env: {
77
+ PATH: process.env.PATH,
78
+ IS_CLI: 'true',
79
+ FORCE_COLOR: options?.forceColor ? '1' : '0',
80
+ ...options?.env,
81
+ },
82
+ shell: true,
83
+ ...options?.spawnOptions,
84
+ }
85
+
86
+ let child: ChildProcess
87
+ if (spawnOptions.shell) {
88
+ const commandStr = options?.args
89
+ ? [executable, ...args].join(' ')
90
+ : cmd
91
+ child = spawn(commandStr, spawnOptions)
92
+ } else {
93
+ child = spawn(executable, args, spawnOptions)
94
+ }
95
+ this.activeChildProcess = child
96
+
97
+ if (options?.outStream) {
98
+ child.stdout?.pipe(options.outStream)
99
+ }
100
+
101
+ child.stdout?.addListener('data', (data) => {
102
+ options?.onData?.(data.toString())
103
+ stdout += data
104
+ })
105
+
106
+ child.stderr?.addListener('data', (data) => {
107
+ options?.onError?.(data.toString())
108
+ stderr += data
109
+ })
110
+
111
+ const closeHandler = (code: number) => {
112
+ process.off('exit', boundKill)
113
+
114
+ if (!this.activeChildProcess) {
115
+ return
116
+ }
117
+ this.activeChildProcess = undefined
118
+
119
+ setTimeout(() => {
120
+ child.stdout?.removeAllListeners()
121
+ child.stderr?.removeAllListeners()
122
+ child.removeAllListeners()
123
+
124
+ if (
125
+ code === 0 ||
126
+ this.ignoreCloseErrors ||
127
+ options?.ignoreErrors
128
+ ) {
129
+ resolve({ stdout })
130
+ this.ignoreCloseErrors = false
131
+ } else {
132
+ reject(
133
+ new Error(
134
+ `Command failed (exit ${code}): ${executable} ${args.join(' ')}\n${stderr}`
135
+ )
136
+ )
137
+ }
138
+ }, 0)
139
+ }
140
+
141
+ child.addListener('close', closeHandler)
142
+ child.addListener('exit', closeHandler)
143
+ })
144
+ }
145
+
146
+ private parseArgv(cmd: string): string[] {
147
+ const result: string[] = []
148
+ let current = ''
149
+ let inQuote = false
150
+ let quoteChar = ''
151
+
152
+ for (let i = 0; i < cmd.length; i++) {
153
+ const ch = cmd[i]
154
+ if (inQuote) {
155
+ if (ch === quoteChar) {
156
+ inQuote = false
157
+ } else {
158
+ current += ch
159
+ }
160
+ } else if (ch === '"' || ch === "'") {
161
+ inQuote = true
162
+ quoteChar = ch
163
+ } else if (ch === ' ') {
164
+ if (current.length > 0) {
165
+ result.push(current)
166
+ current = ''
167
+ }
168
+ } else {
169
+ current += ch
170
+ }
171
+ }
172
+ if (current.length > 0) {
173
+ result.push(current)
174
+ }
175
+ return result
176
+ }
177
+
178
+ public kill = () => {
179
+ const child = this.activeChildProcess
180
+ if (child?.pid) {
181
+ this.ignoreCloseErrors = true
182
+ try {
183
+ process.kill(-child.pid, 'SIGTERM')
184
+ } catch {
185
+ try {
186
+ child.kill('SIGTERM')
187
+ } catch {}
188
+ }
189
+ }
190
+ }
191
+
192
+ public pid = () => {
193
+ return this.activeChildProcess?.pid
194
+ }
195
+
196
+ private getMockResponse(executable: string, args: string[]) {
197
+ const mockKey = `${executable} ${args.join(' ')}`.trim()
198
+ const commands = CommandServiceImpl.fakeResponses
199
+ const match = commands.find((r) =>
200
+ r.command instanceof RegExp
201
+ ? mockKey.search(r.command) > -1
202
+ : r.command.replace(/ +/gis, '') ===
203
+ mockKey.replace(/ +/gis, '')
204
+ )
205
+
206
+ return { mockResponse: match?.response, mockKey }
207
+ }
208
+
209
+ public static fakeCommand(
210
+ command: string | RegExp,
211
+ response: FakedCommandResponse
212
+ ) {
213
+ this.fakeResponses.unshift({
214
+ command,
215
+ response,
216
+ })
217
+ }
218
+
219
+ public static clearFakedResponses() {
220
+ this.fakeResponses = []
221
+ }
222
+ }
223
+
224
+ export type FakedCommandCallback = (executable: string, args: any[]) => void
225
+
226
+ interface FakedCommandResponse {
227
+ code: number
228
+ stdout?: string
229
+ stderr?: string
230
+ callback?: FakedCommandCallback
231
+ }
232
+
233
+ export interface CommandService {
234
+ execute(
235
+ cmd: string,
236
+ options?: ExecuteCommandOptions
237
+ ): Promise<{
238
+ stdout: string
239
+ }>
240
+ getCwd(): string
241
+ setCwd(cwd: string): void
242
+ kill(): void
243
+ pid(): number | undefined
244
+ }
245
+
246
+ export interface ExecuteCommandOptions {
247
+ ignoreErrors?: boolean
248
+ args?: string[]
249
+ shouldStream?: boolean
250
+ outStream?: Writable
251
+ onError?: (error: string) => void
252
+ onData?: (data: string) => void
253
+ spawnOptions?: SpawnOptions
254
+ forceColor?: boolean
255
+ env?: Record<string, any>
256
+ }