@gogocat/data-bind 1.11.0 → 2.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 (274) hide show
  1. package/.editorconfig +14 -14
  2. package/.vscode/launch.json +12 -12
  3. package/CONFIGURATION.md +294 -0
  4. package/REACTIVE_MODE.md +553 -0
  5. package/README.md +266 -829
  6. package/babel.config.json +30 -0
  7. package/dist/js/_escape.d.ts +14 -0
  8. package/dist/js/_escape.d.ts.map +1 -0
  9. package/dist/js/applyBinding.d.ts +11 -0
  10. package/dist/js/applyBinding.d.ts.map +1 -0
  11. package/dist/js/attrBinding.d.ts +12 -0
  12. package/dist/js/attrBinding.d.ts.map +1 -0
  13. package/dist/js/binder.d.ts +67 -0
  14. package/dist/js/binder.d.ts.map +1 -0
  15. package/dist/js/changeBinding.d.ts +19 -0
  16. package/dist/js/changeBinding.d.ts.map +1 -0
  17. package/dist/js/commentWrapper.d.ts +39 -0
  18. package/dist/js/commentWrapper.d.ts.map +1 -0
  19. package/dist/js/config.d.ts +55 -0
  20. package/dist/js/config.d.ts.map +1 -0
  21. package/dist/js/createBindingOption.d.ts +32 -0
  22. package/dist/js/createBindingOption.d.ts.map +1 -0
  23. package/dist/js/createEventBinding.d.ts +10 -0
  24. package/dist/js/createEventBinding.d.ts.map +1 -0
  25. package/dist/js/cssBinding.d.ts +15 -0
  26. package/dist/js/cssBinding.d.ts.map +1 -0
  27. package/dist/js/dataBind.js +2772 -2519
  28. package/dist/js/dataBind.min.js +8 -1
  29. package/dist/js/dataBind.min.js.map +1 -1
  30. package/dist/js/domWalker.d.ts +9 -0
  31. package/dist/js/domWalker.d.ts.map +1 -0
  32. package/dist/js/forOfBinding.d.ts +12 -0
  33. package/dist/js/forOfBinding.d.ts.map +1 -0
  34. package/dist/js/hoverBinding.d.ts +13 -0
  35. package/dist/js/hoverBinding.d.ts.map +1 -0
  36. package/dist/js/ifBinding.d.ts +12 -0
  37. package/dist/js/ifBinding.d.ts.map +1 -0
  38. package/dist/js/index.d.ts +10 -0
  39. package/dist/js/index.d.ts.map +1 -0
  40. package/dist/js/modelBinding.d.ts +12 -0
  41. package/dist/js/modelBinding.d.ts.map +1 -0
  42. package/dist/js/postProcess.d.ts +3 -0
  43. package/dist/js/postProcess.d.ts.map +1 -0
  44. package/dist/js/pubSub.d.ts +11 -0
  45. package/dist/js/pubSub.d.ts.map +1 -0
  46. package/dist/js/reactiveProxy.d.ts +28 -0
  47. package/dist/js/reactiveProxy.d.ts.map +1 -0
  48. package/dist/js/renderForOfBinding.d.ts +8 -0
  49. package/dist/js/renderForOfBinding.d.ts.map +1 -0
  50. package/dist/js/renderIfBinding.d.ts +22 -0
  51. package/dist/js/renderIfBinding.d.ts.map +1 -0
  52. package/dist/js/renderIteration.d.ts +16 -0
  53. package/dist/js/renderIteration.d.ts.map +1 -0
  54. package/dist/js/renderTemplate.d.ts +14 -0
  55. package/dist/js/renderTemplate.d.ts.map +1 -0
  56. package/dist/js/renderTemplatesBinding.d.ts +19 -0
  57. package/dist/js/renderTemplatesBinding.d.ts.map +1 -0
  58. package/dist/js/showBinding.d.ts +13 -0
  59. package/dist/js/showBinding.d.ts.map +1 -0
  60. package/dist/js/switchBinding.d.ts +13 -0
  61. package/dist/js/switchBinding.d.ts.map +1 -0
  62. package/dist/js/textBinding.d.ts +13 -0
  63. package/dist/js/textBinding.d.ts.map +1 -0
  64. package/dist/js/types/_escape.d.ts +14 -0
  65. package/dist/js/types/_escape.d.ts.map +1 -0
  66. package/dist/js/types/applyBinding.d.ts +11 -0
  67. package/dist/js/types/applyBinding.d.ts.map +1 -0
  68. package/dist/js/types/attrBinding.d.ts +12 -0
  69. package/dist/js/types/attrBinding.d.ts.map +1 -0
  70. package/dist/js/types/binder.d.ts +67 -0
  71. package/dist/js/types/binder.d.ts.map +1 -0
  72. package/dist/js/types/changeBinding.d.ts +19 -0
  73. package/dist/js/types/changeBinding.d.ts.map +1 -0
  74. package/dist/js/types/commentWrapper.d.ts +39 -0
  75. package/dist/js/types/commentWrapper.d.ts.map +1 -0
  76. package/dist/js/types/config.d.ts +55 -0
  77. package/dist/js/types/config.d.ts.map +1 -0
  78. package/dist/js/types/createBindingOption.d.ts +32 -0
  79. package/dist/js/types/createBindingOption.d.ts.map +1 -0
  80. package/dist/js/types/createEventBinding.d.ts +10 -0
  81. package/dist/js/types/createEventBinding.d.ts.map +1 -0
  82. package/dist/js/types/cssBinding.d.ts +15 -0
  83. package/dist/js/types/cssBinding.d.ts.map +1 -0
  84. package/dist/js/types/domWalker.d.ts +9 -0
  85. package/dist/js/types/domWalker.d.ts.map +1 -0
  86. package/dist/js/types/forOfBinding.d.ts +12 -0
  87. package/dist/js/types/forOfBinding.d.ts.map +1 -0
  88. package/dist/js/types/hoverBinding.d.ts +13 -0
  89. package/dist/js/types/hoverBinding.d.ts.map +1 -0
  90. package/dist/js/types/ifBinding.d.ts +12 -0
  91. package/dist/js/types/ifBinding.d.ts.map +1 -0
  92. package/dist/js/types/index.d.ts +10 -0
  93. package/dist/js/types/index.d.ts.map +1 -0
  94. package/dist/js/types/modelBinding.d.ts +12 -0
  95. package/dist/js/types/modelBinding.d.ts.map +1 -0
  96. package/dist/js/types/postProcess.d.ts +3 -0
  97. package/dist/js/types/postProcess.d.ts.map +1 -0
  98. package/dist/js/types/pubSub.d.ts +11 -0
  99. package/dist/js/types/pubSub.d.ts.map +1 -0
  100. package/dist/js/types/reactiveProxy.d.ts +28 -0
  101. package/dist/js/types/reactiveProxy.d.ts.map +1 -0
  102. package/dist/js/types/renderForOfBinding.d.ts +8 -0
  103. package/dist/js/types/renderForOfBinding.d.ts.map +1 -0
  104. package/dist/js/types/renderIfBinding.d.ts +22 -0
  105. package/dist/js/types/renderIfBinding.d.ts.map +1 -0
  106. package/dist/js/types/renderIteration.d.ts +16 -0
  107. package/dist/js/types/renderIteration.d.ts.map +1 -0
  108. package/dist/js/types/renderTemplate.d.ts +14 -0
  109. package/dist/js/types/renderTemplate.d.ts.map +1 -0
  110. package/dist/js/types/renderTemplatesBinding.d.ts +19 -0
  111. package/dist/js/types/renderTemplatesBinding.d.ts.map +1 -0
  112. package/dist/js/types/showBinding.d.ts +13 -0
  113. package/dist/js/types/showBinding.d.ts.map +1 -0
  114. package/dist/js/types/switchBinding.d.ts +13 -0
  115. package/dist/js/types/switchBinding.d.ts.map +1 -0
  116. package/dist/js/types/textBinding.d.ts +13 -0
  117. package/dist/js/types/textBinding.d.ts.map +1 -0
  118. package/dist/js/types/types.d.ts +111 -0
  119. package/dist/js/types/types.d.ts.map +1 -0
  120. package/dist/js/types/util.d.ts +119 -0
  121. package/dist/js/types/util.d.ts.map +1 -0
  122. package/dist/js/types.d.ts +111 -0
  123. package/dist/js/types.d.ts.map +1 -0
  124. package/dist/js/util.d.ts +119 -0
  125. package/dist/js/util.d.ts.map +1 -0
  126. package/eslint.config.js +124 -0
  127. package/examples/DBMONSTER_COMPARISON.md +123 -0
  128. package/examples/afterRenderDemo.html +119 -0
  129. package/examples/bootstrap/css/animate.css +1579 -1579
  130. package/examples/bootstrap/css/bootstrap.min.css +6 -6
  131. package/examples/bootstrap/css/homeservices.css +378 -390
  132. package/examples/bootstrap/css/open-iconic.css +511 -511
  133. package/examples/bootstrap/fonts/open-iconic.svg +543 -543
  134. package/examples/bootstrap/js/compMessageDialog.js +20 -19
  135. package/examples/bootstrap/js/compSearchBar.js +12 -19
  136. package/examples/bootstrap/js/compSearchResults.js +50 -46
  137. package/examples/bootstrap/js/featureAdsResult.json +65 -65
  138. package/examples/bootstrap/js/searchResult.json +57 -57
  139. package/examples/bootstrap.html +343 -332
  140. package/examples/css/baseTodo.css +141 -141
  141. package/examples/css/dbMonsterStyles.css +27 -27
  142. package/examples/css/indexTodo.css +374 -374
  143. package/examples/dbmonsterForOfReactive.html +40 -0
  144. package/examples/dbmonsterReact.html +19 -0
  145. package/examples/forOfBindingSimpleDebug.html +45 -0
  146. package/examples/form.html +20 -4
  147. package/examples/globalConfig.html +131 -0
  148. package/examples/js/afterRenderDemo.js +190 -0
  149. package/examples/js/appTodo.js +46 -46
  150. package/examples/js/attrBindingDemo.js +2 -2
  151. package/examples/js/dbMonApp.js +24 -26
  152. package/examples/js/dbMonAppReact.jsx +79 -0
  153. package/examples/js/dbMonAppReactive.js +28 -0
  154. package/examples/js/fiberDemo.js +4 -4
  155. package/examples/js/filtersDemo.js +8 -8
  156. package/examples/js/forOfDemo.js +7 -9
  157. package/examples/js/forOfDemoComplex.js +44 -17
  158. package/examples/js/form.js +44 -12
  159. package/examples/js/globalConfig.js +117 -0
  160. package/examples/js/ifBindingDemo.js +16 -16
  161. package/examples/js/reactiveDemo.js +119 -0
  162. package/examples/js/switchBindingDemo.js +8 -8
  163. package/examples/react-dbmonster/dist/bundle.js +43 -0
  164. package/examples/react-dbmonster/package-lock.json +537 -0
  165. package/examples/react-dbmonster/package.json +16 -0
  166. package/examples/react-dbmonster/src/index.jsx +80 -0
  167. package/examples/reactiveDemo.html +127 -0
  168. package/examples/refreshRateTest.html +75 -75
  169. package/index.html +841 -0
  170. package/package.json +31 -34
  171. package/rollup.config.js +79 -36
  172. package/src/{_escape.js → _escape.ts} +19 -17
  173. package/src/applyBinding.ts +179 -0
  174. package/src/{attrBinding.js → attrBinding.ts} +14 -13
  175. package/src/binder.ts +289 -0
  176. package/src/changeBinding.ts +93 -0
  177. package/src/{commentWrapper.js → commentWrapper.ts} +33 -30
  178. package/src/config.ts +107 -0
  179. package/src/createBindingOption.ts +91 -0
  180. package/src/createEventBinding.ts +88 -0
  181. package/src/{cssBinding.js → cssBinding.ts} +13 -11
  182. package/src/{domWalker.js → domWalker.ts} +44 -30
  183. package/src/{forOfBinding.js → forOfBinding.ts} +4 -3
  184. package/src/hoverBinding.ts +84 -0
  185. package/src/{ifBinding.js → ifBinding.ts} +14 -12
  186. package/src/index.ts +53 -0
  187. package/src/{modelBinding.js → modelBinding.ts} +11 -9
  188. package/src/postProcess.ts +22 -0
  189. package/src/{pubSub.js → pubSub.ts} +24 -15
  190. package/src/reactiveProxy.ts +285 -0
  191. package/src/{renderForOfBinding.js → renderForOfBinding.ts} +55 -33
  192. package/src/{renderIfBinding.js → renderIfBinding.ts} +45 -20
  193. package/src/renderIteration.ts +53 -0
  194. package/src/renderTemplate.ts +165 -0
  195. package/src/renderTemplatesBinding.ts +73 -0
  196. package/src/{showBinding.js → showBinding.ts} +4 -3
  197. package/src/{switchBinding.js → switchBinding.ts} +18 -15
  198. package/src/{textBinding.js → textBinding.ts} +5 -4
  199. package/src/types.ts +124 -0
  200. package/src/util.ts +810 -0
  201. package/test/css/reporter.css +9 -9
  202. package/test/fixtures/dataBindBootstrap.html +2 -2
  203. package/test/fixtures/formBindings.html +9 -1
  204. package/test/globals.d.ts +19 -0
  205. package/test/helpers/testHelper.js +46 -11
  206. package/test/mocks/featureAdsResult.json +65 -65
  207. package/test/mocks/searchResult.json +57 -57
  208. package/test/specs/{attrBinding.spec.js → attrBinding.spec.ts} +103 -106
  209. package/test/specs/{binder.spec.js → binder.spec.ts} +29 -27
  210. package/test/specs/blurBinding.spec.ts +60 -0
  211. package/test/specs/chainableUse.spec.ts +125 -0
  212. package/test/specs/clickBinding.spec.ts +194 -0
  213. package/test/specs/{cssBinding.spec.js → cssBinding.spec.ts} +72 -79
  214. package/test/specs/{dataBindBootstrap.spec.js → dataBindBootstrap.spec.ts} +332 -313
  215. package/test/specs/{filter.spec.js → filter.spec.ts} +75 -76
  216. package/test/specs/{forOfBinding.spec.js → forOfBinding.spec.ts} +208 -219
  217. package/test/specs/formBinding.spec.ts +272 -0
  218. package/test/specs/ifBinding.spec.ts +165 -0
  219. package/test/specs/{nestedComponent.spec.js → nestedComponent.spec.ts} +88 -88
  220. package/test/specs/reactiveProxy.spec.ts +465 -0
  221. package/test/specs/{showBinding.spec.js → showBinding.spec.ts} +148 -149
  222. package/test/specs/{switchBinding.spec.js → switchBinding.spec.ts} +172 -173
  223. package/test/specs/templateBinding.spec.ts +273 -0
  224. package/test/specs/{textBinding.spec.js → textBinding.spec.ts} +47 -48
  225. package/test/tsconfig.json +31 -0
  226. package/test-output.txt +200 -0
  227. package/test-reactive.html +224 -0
  228. package/tsconfig.json +28 -0
  229. package/vendors/lodash.custom.js +4577 -4577
  230. package/vendors/lodash.custom.min.js +45 -45
  231. package/vitest.config.js +27 -0
  232. package/.eslintrc.js +0 -1
  233. package/.grunt/grunt-contrib-jasmine/boot.js +0 -161
  234. package/.grunt/grunt-contrib-jasmine/dist/js/dataBind.js +0 -9
  235. package/.grunt/grunt-contrib-jasmine/grunt-template-jasmine-istanbul/reporter.js +0 -23
  236. package/.grunt/grunt-contrib-jasmine/jasmine-html.js +0 -853
  237. package/.grunt/grunt-contrib-jasmine/jasmine.css +0 -271
  238. package/.grunt/grunt-contrib-jasmine/jasmine.js +0 -9761
  239. package/.grunt/grunt-contrib-jasmine/jasmine_favicon.png +0 -0
  240. package/.grunt/grunt-contrib-jasmine/json2.js +0 -489
  241. package/.grunt/grunt-contrib-jasmine/reporter.js +0 -107
  242. package/coverage/coverage.json +0 -1
  243. package/coverage/lcov/lcov-report/base.css +0 -213
  244. package/coverage/lcov/lcov-report/index.html +0 -93
  245. package/coverage/lcov/lcov-report/js/dataBind.js.html +0 -6596
  246. package/coverage/lcov/lcov-report/js/index.html +0 -93
  247. package/coverage/lcov/lcov-report/prettify.css +0 -1
  248. package/coverage/lcov/lcov-report/prettify.js +0 -1
  249. package/coverage/lcov/lcov-report/sort-arrow-sprite.png +0 -0
  250. package/coverage/lcov/lcov-report/sorter.js +0 -158
  251. package/coverage/lcov/lcov.info +0 -1991
  252. package/eslintrc.json +0 -40
  253. package/examples/bootstrap/js/bootstrap.min.js +0 -6
  254. package/examples/bootstrap/js/popper.min.js +0 -5
  255. package/examples/bootstrap/js/searchSuggestion.js +0 -58
  256. package/examples/bootstrap/js/typeahead.jquery.js +0 -1538
  257. package/gruntfile.js +0 -92
  258. package/gulpfile.js +0 -32
  259. package/src/binder.js +0 -422
  260. package/src/changeBinding.js +0 -57
  261. package/src/config.js +0 -65
  262. package/src/createBindingOption.js +0 -66
  263. package/src/createEventBinding.js +0 -46
  264. package/src/eventSystem.js +0 -46
  265. package/src/hoverBinding.js +0 -57
  266. package/src/index.js +0 -26
  267. package/src/renderTemplate.js +0 -128
  268. package/src/util.js +0 -648
  269. package/test/specs/blurBinding.spec.js +0 -57
  270. package/test/specs/formBinding.spec.js +0 -292
  271. package/test/specs/ifBinding.spec.js +0 -169
  272. package/test/specs/templateBinding.spec.js +0 -117
  273. package/vendors/jasmine-jquery.js +0 -841
  274. package/vendors/jquery-3.2.1.min.js +0 -4
@@ -1,48 +1,47 @@
1
- describe('Given [data-bind-comp="text-component"] inited', () => {
2
- const namespace = {};
3
- const testContent2 = 'text-binding content';
4
-
5
- jasmine.getFixtures().fixturesPath = 'test';
6
-
7
- beforeEach(() => {
8
- loadFixtures('./fixtures/textBinding.html');
9
-
10
- namespace.viewModel = {
11
- heading: 'my text-binding Component',
12
- description: 'test description',
13
- getTextContent: function() {
14
- return testContent2;
15
- },
16
- updateView: function(opt) {
17
- this.APP.render(opt);
18
- },
19
- };
20
-
21
- namespace.myTextComponent = dataBind.init(document.querySelector('[data-bind-comp="text-component"]'), namespace.viewModel);
22
-
23
- namespace.myTextComponent.render();
24
- });
25
-
26
- afterEach(() => {
27
- // clean up all app/components
28
- for (const prop in namespace) {
29
- if (namespace.hasOwnProperty(prop)) {
30
- delete namespace[prop];
31
- }
32
- }
33
- });
34
-
35
- it('Then [data-bind-comp="myTextComponent"] should have render', (done) => {
36
- setTimeout(() => {
37
- const $heading = document.getElementById('text-binding-heading');
38
- const $textBindingContent = document.getElementById('text-binding-content');
39
- const $textBindingContent2 = document.getElementById('text-binding-content2');
40
-
41
- expect($heading.textContent).toBe(namespace.viewModel.heading);
42
- expect($textBindingContent.textContent).toBe(namespace.viewModel.description);
43
- expect($textBindingContent2.textContent).toBe(testContent2);
44
-
45
- done();
46
- }, 200);
47
- });
48
- });
1
+ import {describe, it, expect, beforeEach, afterEach} from 'vitest';
2
+ import {waitFor} from '@testing-library/dom';
3
+
4
+ describe('Given [data-bind-comp="text-component"] inited', () => {
5
+ const namespace: any = {};
6
+ const testContent2 = 'text-binding content';
7
+
8
+ beforeEach(() => {
9
+ loadFixture('test/fixtures/textBinding.html');
10
+
11
+ namespace.viewModel = {
12
+ heading: 'my text-binding Component',
13
+ description: 'test description',
14
+ getTextContent() {
15
+ return testContent2;
16
+ },
17
+ updateView(opt?: any) {
18
+ this.APP.render(opt);
19
+ },
20
+ };
21
+
22
+ namespace.myTextComponent = dataBind.init(document.querySelector('[data-bind-comp="text-component"]'), namespace.viewModel);
23
+
24
+ namespace.myTextComponent.render();
25
+ });
26
+
27
+ afterEach(() => {
28
+ // clean up all app/components
29
+ for (const prop in namespace) {
30
+ if (Object.prototype.hasOwnProperty.call(namespace, prop)) {
31
+ delete namespace[prop];
32
+ }
33
+ }
34
+ });
35
+
36
+ it('Then [data-bind-comp="myTextComponent"] should have render', async () => {
37
+ await waitFor(() => {
38
+ const $heading = document.getElementById('text-binding-heading')!;
39
+ const $textBindingContent = document.getElementById('text-binding-content')!;
40
+ const $textBindingContent2 = document.getElementById('text-binding-content2')!;
41
+
42
+ expect($heading.textContent).toBe(namespace.viewModel.heading);
43
+ expect($textBindingContent.textContent).toBe(namespace.viewModel.description);
44
+ expect($textBindingContent2.textContent).toBe(testContent2);
45
+ }, {timeout: 500});
46
+ });
47
+ });
@@ -0,0 +1,31 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2015",
4
+ "module": "ESNext",
5
+ "lib": ["ES2015", "DOM"],
6
+ "strict": false,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "moduleResolution": "node",
11
+ "resolveJsonModule": true,
12
+ "allowSyntheticDefaultImports": true,
13
+ "noUnusedLocals": false,
14
+ "noUnusedParameters": false,
15
+ "noImplicitAny": false,
16
+ "strictNullChecks": false,
17
+ "strictFunctionTypes": false,
18
+ "strictPropertyInitialization": false,
19
+ "noImplicitThis": false,
20
+ "allowJs": true,
21
+ "noEmit": true,
22
+ "types": ["vitest/globals"]
23
+ },
24
+ "include": [
25
+ "./**/*.ts",
26
+ "./globals.d.ts"
27
+ ],
28
+ "exclude": [
29
+ "../node_modules"
30
+ ]
31
+ }
@@ -0,0 +1,200 @@
1
+
2
+ > @gogocat/data-bind@1.12.0 test
3
+ > vitest run
4
+
5
+
6
+ RUN v2.1.9 /Users/adamchow/My-workspace/dataBind
7
+
8
+ ❯ test/specs/switchBinding.spec.js (0 test)
9
+ ❯ test/specs/ifBinding.spec.js (0 test)
10
+ ❯ test/specs/nestedComponent.spec.js (0 test)
11
+ ❯ test/specs/templateBinding.spec.js (0 test)
12
+ ❯ test/specs/showBinding.spec.js (0 test)
13
+ stderr | test/specs/forOfBinding.spec.js > When search-results-component with forOf binding inited > Then [data-bind-comp="search-results-component"] should have render
14
+ error in rendering: TypeError: __vite_ssr_import_1__.default is not a function
15
+ at /Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:33:25
16
+ at Array.forEach (<anonymous>)
17
+ at Module.renderTemplatesBinding [as default] (/Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:32:40)
18
+ at Binder.render (/Users/adamchow/My-workspace/dataBind/src/binder.js:141:31)
19
+ at Timeout._onTimeout (/Users/adamchow/My-workspace/dataBind/src/util.js:365:24)
20
+ at listOnTimeout (node:internal/timers:594:17)
21
+ at processTimers (node:internal/timers:529:7)
22
+
23
+ ✓ test/specs/attrBinding.spec.js (5 tests) 107ms
24
+ ❯ test/specs/dataBindBootstrap.spec.js (5 tests | 5 failed) 75ms
25
+ × Given dataBindBootstrp initised > Then [data-bind-comp="search-bar"] should has bond with namespace.searchBarComponentVM 44ms
26
+ → spyOn is not defined
27
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
28
+ × Given dataBindBootstrp initised > When [data-bind-comp="search-bar"] was server rendered then show binding should not update element 8ms
29
+ → spyOn is not defined
30
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
31
+ × Given dataBindBootstrp initised > When change #searchWord input value to "Handyman" viewModel onSearchWordChange should have been called 6ms
32
+ → spyOn is not defined
33
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
34
+ × Given dataBindBootstrp initised > When change #location input value to "Melbourne" viewModel onSearchLocationChange should have been called 10ms
35
+ → spyOn is not defined
36
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
37
+ × Given dataBindBootstrp initised > When [data-bind-comp="search-bar"] was server rendered "data-server-rendered" attribute should have removed 6ms
38
+ → spyOn is not defined
39
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
40
+ stderr | test/specs/dataBindBootstrap.spec.js
41
+ error in rendering: TypeError: __vite_ssr_import_1__.default is not a function
42
+ at /Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:33:25
43
+ at Array.forEach (<anonymous>)
44
+ at Module.renderTemplatesBinding [as default] (/Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:32:40)
45
+ at Binder.render (/Users/adamchow/My-workspace/dataBind/src/binder.js:141:31)
46
+ at Timeout._onTimeout (/Users/adamchow/My-workspace/dataBind/src/util.js:365:24)
47
+ at listOnTimeout (node:internal/timers:594:17)
48
+ at processTimers (node:internal/timers:529:7)
49
+ error in rendering: TypeError: __vite_ssr_import_1__.default is not a function
50
+ at /Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:33:25
51
+ at Array.forEach (<anonymous>)
52
+ at Module.renderTemplatesBinding [as default] (/Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:32:40)
53
+ at Binder.render (/Users/adamchow/My-workspace/dataBind/src/binder.js:141:31)
54
+ at Timeout._onTimeout (/Users/adamchow/My-workspace/dataBind/src/util.js:365:24)
55
+ at listOnTimeout (node:internal/timers:594:17)
56
+ at processTimers (node:internal/timers:529:7)
57
+ error in rendering: TypeError: __vite_ssr_import_1__.default is not a function
58
+ at /Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:33:25
59
+ at Array.forEach (<anonymous>)
60
+ at Module.renderTemplatesBinding [as default] (/Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:32:40)
61
+ at Binder.render (/Users/adamchow/My-workspace/dataBind/src/binder.js:141:31)
62
+ at Timeout._onTimeout (/Users/adamchow/My-workspace/dataBind/src/util.js:365:24)
63
+ at listOnTimeout (node:internal/timers:594:17)
64
+ at processTimers (node:internal/timers:529:7)
65
+
66
+ stderr | Timeout._onTimeout (/Users/adamchow/My-workspace/dataBind/src/util.js:370:29)
67
+ error in rendering: TypeError: __vite_ssr_import_1__.default is not a function
68
+ at /Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:33:25
69
+ at Array.forEach (<anonymous>)
70
+ at Module.renderTemplatesBinding [as default] (/Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:32:40)
71
+ at Binder.render (/Users/adamchow/My-workspace/dataBind/src/binder.js:141:31)
72
+ at Timeout._onTimeout (/Users/adamchow/My-workspace/dataBind/src/util.js:365:24)
73
+ at listOnTimeout (node:internal/timers:594:17)
74
+ at processTimers (node:internal/timers:529:7)
75
+ error in rendering: TypeError: __vite_ssr_import_1__.default is not a function
76
+ at /Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:33:25
77
+ at Array.forEach (<anonymous>)
78
+ at Module.renderTemplatesBinding [as default] (/Users/adamchow/My-workspace/dataBind/src/renderTemplatesBinding.js:32:40)
79
+ at Binder.render (/Users/adamchow/My-workspace/dataBind/src/binder.js:141:31)
80
+ at Timeout._onTimeout (/Users/adamchow/My-workspace/dataBind/src/util.js:365:24)
81
+ at listOnTimeout (node:internal/timers:594:17)
82
+ at processTimers (node:internal/timers:529:7)
83
+
84
+ ✓ test/specs/binder.spec.js (5 tests) 4ms
85
+ ❯ test/specs/filter.spec.js (3 tests | 3 failed) 18ms
86
+ × Given [data-bind-comp="filter-component"] inited > Then [data-bind-comp="filter-component"] should render story with once filter and not intro 15ms
87
+ → expected <div id="intro" …(2)>…(2)</div> to be null // Object.is equality
88
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
89
+ × Given [data-bind-comp="filter-component"] inited > Should render intro but not story section after update viewModel 2ms
90
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
91
+ × Given [data-bind-comp="filter-component"] inited > Should render story and stroyPrice pass through filters | toDiscount | addGst 1ms
92
+ → Cannot read properties of null (reading 'textContent')
93
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
94
+ ❯ test/specs/blurBinding.spec.js (2 tests | 2 failed) 33ms
95
+ × Given [data-bind-comp="blur-component"] initised > should render heading defined in viewModel 30ms
96
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
97
+ × Given [data-bind-comp="blur-component"] initised > should update "blurInput" value after onBlur 2ms
98
+ → Cannot read properties of undefined (reading 'hasOwnProperty')
99
+ ✓ test/specs/textBinding.spec.js (1 test) 25ms
100
+ ❯ test/specs/forOfBinding.spec.js (4 tests | 1 failed) 532ms
101
+ × When search-results-component with forOf binding inited > Then [data-bind-comp="search-results-component"] should have render 525ms
102
+ → expected '' to be 'Featured service providers' // Object.is equality
103
+
104
+ Ignored nodes: comments, script, style
105
+ <html>
106
+ <head />
107
+ <body>
108
+ <div
109
+ class="container"
110
+ >
111
+ 
112
+ 
113
+ <h5>
114
+ For of binding complex demo
115
+ </h5>
116
+ 
117
+ 
118
+ <div
119
+ class="container search-result"
120
+ data-bind-comp="search-results-component"
121
+ >
122
+ 
123
+ 
124
+ <h4
125
+ class="text-center section-title"
126
+ data-bind-text="searchResultTitle"
127
+ id="searchResultTitle"
128
+ />
129
+ 
130
+ 
131
+ <div
132
+ class="card-columns"
133
+ data-bind-tmp="{id: 'searchResultItem', data: 'searchResults'}"
134
+ id="search-result-columns"
135
+ >
136
+ 
137
+ 
138
+ <div
139
+ class="card result-item"
140
+ data-bind-css="result.highlightCss"
141
+ data-bind-for="result in searchResults"
142
+ >
143
+ 
144
+ 
145
+ <img
146
+ class="card-img-top result-item__img"
147
+ data-bind-attr="$root.getResultItemAttr($index)"
148
+ />
149
+ 
150
+ 
151
+ <div
152
+ class="card-body"
153
+ data-bind-tmp="{id: 'searchResultItemBody', data: 'result'}"
154
+ />
155
+ 
156
+ 
157
+ <div
158
+ data-bind-tmp="{id: 'searchResultItemFooter', data: 'result'}"
159
+ />
160
+ 
161
+ 
162
+ </div>
163
+ 
164
+ 
165
+ </div>
166
+ 
167
+ 
168
+ </div>
169
+ 
170
+ 
171
+ </div>
172
+ 
173
+
174
+ 
175
+ 
176
+ 
177
+ <template
178
+ id="searchResultItem"
179
+ />
180
+ 
181
+
182
+ 
183
+ <template
184
+ id="searchResultItemBody"
185
+ />
186
+ 
187
+
188
+ 
189
+ <template
190
+ id="searchResultItemFooter"
191
+ />
192
+ 
193
+
194
+ 
195
+ <template
196
+ id="searchResultItemBookMark"
197
+ />
198
+ </body>
199
+ </html>
200
+ ❯ test/specs/cssBinding.spec.js (3 tests | 3 failed) 543ms
@@ -0,0 +1,224 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Reactive Proxy Test</title>
5
+ <style>
6
+ body { font-family: Arial; padding: 20px; }
7
+ .test { margin: 10px 0; padding: 10px; border: 1px solid #ddd; }
8
+ .pass { background: #d4edda; }
9
+ .fail { background: #f8d7da; }
10
+ pre { background: #f5f5f5; padding: 10px; }
11
+ </style>
12
+ </head>
13
+ <body>
14
+ <h1>Reactive Proxy Test Suite</h1>
15
+ <div id="results"></div>
16
+
17
+ <script src="dist/js/dataBind.min.js"></script>
18
+ <script>
19
+ const results = [];
20
+
21
+ function test(name, fn) {
22
+ try {
23
+ fn();
24
+ results.push({name, status: 'pass', error: null});
25
+ console.log('✅', name);
26
+ } catch (error) {
27
+ results.push({name, status: 'fail', error: error.message});
28
+ console.error('❌', name, error);
29
+ }
30
+ }
31
+
32
+ let renderCount = 0;
33
+ function resetRenderCount() {
34
+ renderCount = 0;
35
+ }
36
+
37
+ // Test 1: Simple property change
38
+ test('1. Simple property change triggers render', () => {
39
+ resetRenderCount();
40
+ const viewModel = {name: 'John', age: 30};
41
+ const component = dataBind.init(document.createElement('div'), viewModel);
42
+ component.render = () => { renderCount++; };
43
+
44
+ component.viewModel.name = 'Jane';
45
+
46
+ setTimeout(() => {
47
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
48
+ }, 100);
49
+ });
50
+
51
+ // Test 2: Nested object change
52
+ test('2. Nested object property change triggers render', () => {
53
+ resetRenderCount();
54
+ const viewModel = {
55
+ user: {
56
+ profile: {
57
+ name: 'John'
58
+ }
59
+ }
60
+ };
61
+ const component = dataBind.init(document.createElement('div'), viewModel);
62
+ component.render = () => { renderCount++; };
63
+
64
+ component.viewModel.user.profile.name = 'Jane';
65
+
66
+ setTimeout(() => {
67
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
68
+ }, 100);
69
+ });
70
+
71
+ // Test 3: Array push
72
+ test('3. Array push triggers render', () => {
73
+ resetRenderCount();
74
+ const viewModel = {items: [1, 2, 3]};
75
+ const component = dataBind.init(document.createElement('div'), viewModel);
76
+ component.render = () => { renderCount++; };
77
+
78
+ component.viewModel.items.push(4);
79
+
80
+ setTimeout(() => {
81
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
82
+ if (component.viewModel.items.length !== 4) throw new Error('Array length incorrect');
83
+ }, 100);
84
+ });
85
+
86
+ // Test 4: Array pop
87
+ test('4. Array pop triggers render', () => {
88
+ resetRenderCount();
89
+ const viewModel = {items: [1, 2, 3]};
90
+ const component = dataBind.init(document.createElement('div'), viewModel);
91
+ component.render = () => { renderCount++; };
92
+
93
+ component.viewModel.items.pop();
94
+
95
+ setTimeout(() => {
96
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
97
+ if (component.viewModel.items.length !== 2) throw new Error('Array length incorrect');
98
+ }, 100);
99
+ });
100
+
101
+ // Test 5: Array splice
102
+ test('5. Array splice triggers render', () => {
103
+ resetRenderCount();
104
+ const viewModel = {items: [1, 2, 3]};
105
+ const component = dataBind.init(document.createElement('div'), viewModel);
106
+ component.render = () => { renderCount++; };
107
+
108
+ component.viewModel.items.splice(1, 1);
109
+
110
+ setTimeout(() => {
111
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
112
+ }, 100);
113
+ });
114
+
115
+ // Test 6: Array index assignment
116
+ test('6. Array index assignment triggers render', () => {
117
+ resetRenderCount();
118
+ const viewModel = {items: [1, 2, 3]};
119
+ const component = dataBind.init(document.createElement('div'), viewModel);
120
+ component.render = () => { renderCount++; };
121
+
122
+ component.viewModel.items[0] = 99;
123
+
124
+ setTimeout(() => {
125
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
126
+ if (component.viewModel.items[0] !== 99) throw new Error('Value not updated');
127
+ }, 100);
128
+ });
129
+
130
+ // Test 7: Array of objects - modify object property
131
+ test('7. Array of objects - modify object property triggers render', () => {
132
+ resetRenderCount();
133
+ const viewModel = {
134
+ todos: [
135
+ {text: 'Task 1', done: false},
136
+ {text: 'Task 2', done: false}
137
+ ]
138
+ };
139
+ const component = dataBind.init(document.createElement('div'), viewModel);
140
+ component.render = () => { renderCount++; };
141
+
142
+ component.viewModel.todos[0].done = true;
143
+
144
+ setTimeout(() => {
145
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
146
+ if (component.viewModel.todos[0].done !== true) throw new Error('Value not updated');
147
+ }, 100);
148
+ });
149
+
150
+ // Test 8: Array of objects - push new object
151
+ test('8. Array of objects - push new object triggers render', () => {
152
+ resetRenderCount();
153
+ const viewModel = {
154
+ todos: [
155
+ {text: 'Task 1', done: false}
156
+ ]
157
+ };
158
+ const component = dataBind.init(document.createElement('div'), viewModel);
159
+ component.render = () => { renderCount++; };
160
+
161
+ component.viewModel.todos.push({text: 'Task 2', done: false});
162
+
163
+ setTimeout(() => {
164
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
165
+ if (component.viewModel.todos.length !== 2) throw new Error('Array length incorrect');
166
+ }, 100);
167
+ });
168
+
169
+ // Test 9: Deep nested array
170
+ test('9. Deep nested array triggers render', () => {
171
+ resetRenderCount();
172
+ const viewModel = {
173
+ data: {
174
+ lists: {
175
+ items: [1, 2, 3]
176
+ }
177
+ }
178
+ };
179
+ const component = dataBind.init(document.createElement('div'), viewModel);
180
+ component.render = () => { renderCount++; };
181
+
182
+ component.viewModel.data.lists.items.push(4);
183
+
184
+ setTimeout(() => {
185
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
186
+ }, 100);
187
+ });
188
+
189
+ // Test 10: Batch updates (multiple changes = 1 render due to RAF)
190
+ test('10. Multiple changes batched into single render', () => {
191
+ resetRenderCount();
192
+ const viewModel = {name: 'John', age: 30, email: 'john@test.com'};
193
+ const component = dataBind.init(document.createElement('div'), viewModel);
194
+ component.render = () => { renderCount++; };
195
+
196
+ component.viewModel.name = 'Jane';
197
+ component.viewModel.age = 25;
198
+ component.viewModel.email = 'jane@test.com';
199
+
200
+ setTimeout(() => {
201
+ // Should only be 1 render due to RAF debouncing
202
+ if (renderCount !== 1) throw new Error(`Expected 1 render, got ${renderCount}`);
203
+ }, 100);
204
+ });
205
+
206
+ // Display results after all tests
207
+ setTimeout(() => {
208
+ const resultsDiv = document.getElementById('results');
209
+ const passCount = results.filter(r => r.status === 'pass').length;
210
+ const failCount = results.filter(r => r.status === 'fail').length;
211
+
212
+ resultsDiv.innerHTML = `
213
+ <h2>Results: ${passCount} passed, ${failCount} failed</h2>
214
+ ${results.map(r => `
215
+ <div class="test ${r.status}">
216
+ <strong>${r.status === 'pass' ? '✅' : '❌'} ${r.name}</strong>
217
+ ${r.error ? `<pre>${r.error}</pre>` : ''}
218
+ </div>
219
+ `).join('')}
220
+ `;
221
+ }, 200);
222
+ </script>
223
+ </body>
224
+ </html>
package/tsconfig.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2015",
4
+ "module": "ESNext",
5
+ "lib": ["ES2015", "DOM"],
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "outDir": "./dist/types",
9
+ "rootDir": "./src",
10
+ "strict": false,
11
+ "esModuleInterop": true,
12
+ "skipLibCheck": true,
13
+ "forceConsistentCasingInFileNames": true,
14
+ "moduleResolution": "node",
15
+ "resolveJsonModule": true,
16
+ "allowSyntheticDefaultImports": true,
17
+ "noUnusedLocals": false,
18
+ "noUnusedParameters": false,
19
+ "noImplicitAny": false,
20
+ "strictNullChecks": false,
21
+ "strictFunctionTypes": false,
22
+ "strictPropertyInitialization": false,
23
+ "noImplicitThis": false,
24
+ "allowJs": true
25
+ },
26
+ "include": ["src/**/*"],
27
+ "exclude": ["node_modules", "dist", "test"]
28
+ }