@angular-wave/angular.ts 0.9.3 → 0.9.5

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 (703) hide show
  1. package/@types/angular.d.ts +4 -19
  2. package/@types/animations/animate.d.ts +2 -2
  3. package/@types/animations/animation.d.ts +1 -1
  4. package/@types/core/compile/attributes.d.ts +1 -1
  5. package/@types/core/compile/compile.d.ts +2 -2
  6. package/@types/core/controller/controller.d.ts +1 -1
  7. package/@types/core/controller/interface.d.ts +6 -0
  8. package/@types/core/di/ng-module.d.ts +27 -26
  9. package/@types/core/filter/filter.d.ts +5 -5
  10. package/@types/core/interpolate/interface.d.ts +13 -0
  11. package/@types/core/interpolate/interpolate.d.ts +1 -13
  12. package/@types/core/scope/scope.d.ts +4 -1
  13. package/@types/directive/http/http.d.ts +16 -16
  14. package/@types/directive/http/interface.d.ts +27 -0
  15. package/@types/directive/include/include.d.ts +4 -4
  16. package/@types/directive/inject/inject.d.ts +12 -0
  17. package/@types/directive/model/model.d.ts +1 -1
  18. package/@types/directive/script/script.d.ts +2 -2
  19. package/@types/directive/setter/setter.d.ts +4 -4
  20. package/@types/filters/filter.d.ts +2 -2
  21. package/@types/filters/filters.d.ts +2 -2
  22. package/@types/filters/interface.d.ts +8 -0
  23. package/@types/filters/limit-to.d.ts +2 -2
  24. package/@types/filters/order-by.d.ts +2 -2
  25. package/@types/interface.d.ts +105 -82
  26. package/@types/namespace.d.ts +76 -0
  27. package/@types/router/state/interface.d.ts +8 -8
  28. package/@types/router/state-filters.d.ts +4 -4
  29. package/@types/router/template-factory.d.ts +8 -8
  30. package/@types/router/transition/hook-builder.d.ts +5 -2
  31. package/@types/router/transition/hook-registry.d.ts +11 -2
  32. package/@types/router/transition/transition-service.d.ts +6 -2
  33. package/@types/router/transition/transition.d.ts +2 -2
  34. package/@types/router/view/view.d.ts +1 -8
  35. package/@types/router/view-scroll.d.ts +4 -2
  36. package/@types/services/{anchor-scroll.d.ts → anchor-scroll/anchor-scroll.d.ts} +2 -2
  37. package/@types/services/exception/exception-handler.d.ts +2 -2
  38. package/@types/services/exception/interface.d.ts +1 -1
  39. package/@types/services/http/http.d.ts +40 -2
  40. package/@types/services/http/interface.d.ts +11 -0
  41. package/@types/services/location/location.d.ts +1 -4
  42. package/@types/services/sce/sce.d.ts +3 -4
  43. package/@types/services/template-cache/template-cache.d.ts +4 -4
  44. package/@types/services/template-request/interface.d.ts +22 -0
  45. package/@types/services/{template-request.d.ts → template-request/template-request.d.ts} +4 -7
  46. package/@types/shared/common.d.ts +8 -69
  47. package/@types/shared/hof.d.ts +7 -7
  48. package/dist/angular-ts.esm.js +510 -570
  49. package/dist/angular-ts.umd.js +510 -570
  50. package/dist/angular-ts.umd.min.js +1 -1
  51. package/package.json +8 -1
  52. package/.github/workflows/ci.yml +0 -104
  53. package/.github/workflows/gh-pages.yml +0 -75
  54. package/.husky/pre-commit +0 -5
  55. package/.prettierignore +0 -9
  56. package/@types/services/cookie-reader.d.ts +0 -4
  57. package/@types/services/http-backend/http-backend.d.ts +0 -58
  58. package/@types/services/template-cache/interface.d.ts +0 -10
  59. package/CHANGELOG.md +0 -17667
  60. package/CODE_OF_CONDUCT.md +0 -3
  61. package/CONTRIBUTING.md +0 -247
  62. package/DEVELOPERS.md +0 -499
  63. package/Makefile +0 -60
  64. package/RELEASE.md +0 -86
  65. package/TRIAGING.md +0 -127
  66. package/docs/.cspell.yml +0 -8
  67. package/docs/.github/dependabot.yml +0 -14
  68. package/docs/.nvmrc +0 -1
  69. package/docs/CONTRIBUTING.md +0 -28
  70. package/docs/Dockerfile +0 -4
  71. package/docs/LICENSE +0 -201
  72. package/docs/README.md +0 -217
  73. package/docs/assets/icons/logo.svg +0 -1
  74. package/docs/assets/scss/_variables_project.scss +0 -12
  75. package/docs/assets/scss/_variables_project_after_bs.scss +0 -8
  76. package/docs/assets/scss/index.scss +0 -48
  77. package/docs/config.yaml +0 -15
  78. package/docs/content/_index.md +0 -28
  79. package/docs/content/docs/_index.md +0 -61
  80. package/docs/content/docs/directive/_index.md +0 -4
  81. package/docs/content/docs/directive/app.md +0 -11
  82. package/docs/content/docs/directive/aria.md +0 -0
  83. package/docs/content/docs/directive/bind.md +0 -72
  84. package/docs/content/docs/directive/blur.md +0 -38
  85. package/docs/content/docs/directive/channel.md +0 -37
  86. package/docs/content/docs/directive/class-even.md +0 -47
  87. package/docs/content/docs/directive/class-odd.md +0 -48
  88. package/docs/content/docs/directive/class.md +0 -64
  89. package/docs/content/docs/directive/click.md +0 -41
  90. package/docs/content/docs/directive/cloak.md +0 -74
  91. package/docs/content/docs/directive/copy.md +0 -38
  92. package/docs/content/docs/directive/cut.md +0 -40
  93. package/docs/content/docs/directive/dblclick.md +0 -41
  94. package/docs/content/docs/directive/focus.md +0 -38
  95. package/docs/content/docs/directive/get.md +0 -203
  96. package/docs/content/docs/directive/include.md +0 -7
  97. package/docs/content/docs/directive/keydown.md +0 -38
  98. package/docs/content/docs/directive/keyup.md +0 -38
  99. package/docs/content/docs/directive/load.md +0 -43
  100. package/docs/content/docs/directive/mousedown.md +0 -38
  101. package/docs/content/docs/directive/mouseenter.md +0 -38
  102. package/docs/content/docs/directive/mouseleave.md +0 -38
  103. package/docs/content/docs/directive/mousemove.md +0 -38
  104. package/docs/content/docs/directive/mouseout.md +0 -38
  105. package/docs/content/docs/directive/mouseover.md +0 -38
  106. package/docs/content/docs/directive/mouseup.md +0 -38
  107. package/docs/content/docs/directive/non-bindable.md +0 -28
  108. package/docs/content/docs/filter/_index.md +0 -4
  109. package/docs/content/docs/provider/_index.md +0 -4
  110. package/docs/content/docs/provider/eventBusProvider.md +0 -35
  111. package/docs/content/docs/provider/locationProvider.md +0 -26
  112. package/docs/content/docs/provider/logProvider.md +0 -59
  113. package/docs/content/docs/provider/templateCacheProvider.md +0 -100
  114. package/docs/content/docs/service/_index.md +0 -4
  115. package/docs/content/docs/service/eventBus.md +0 -56
  116. package/docs/content/docs/service/location.md +0 -57
  117. package/docs/content/docs/service/log.md +0 -113
  118. package/docs/content/docs/service/templateCache.md +0 -64
  119. package/docs/content/docs/service/url.md +0 -5
  120. package/docs/docker-compose.yaml +0 -12
  121. package/docs/docsy.work +0 -5
  122. package/docs/docsy.work.sum +0 -0
  123. package/docs/go.mod +0 -5
  124. package/docs/go.sum +0 -6
  125. package/docs/hugo-disabled.toml +0 -220
  126. package/docs/hugo.yaml +0 -200
  127. package/docs/layouts/404.html +0 -13
  128. package/docs/layouts/_markup/render-heading.html +0 -1
  129. package/docs/layouts/partials/hooks/head-end.html +0 -3
  130. package/docs/layouts/shortcodes/showcss.html +0 -2
  131. package/docs/layouts/shortcodes/showhtml.html +0 -2
  132. package/docs/layouts/shortcodes/showjs.html +0 -2
  133. package/docs/layouts/shortcodes/showraw.html +0 -1
  134. package/docs/layouts/shortcodes/version.html +0 -1
  135. package/docs/package-lock.json +0 -2293
  136. package/docs/package.json +0 -53
  137. package/docs/static/examples/counter/counter-test.html +0 -13
  138. package/docs/static/examples/counter/counter.html +0 -5
  139. package/docs/static/examples/counter/counter.test.js +0 -28
  140. package/docs/static/examples/eventbus/eventbus-test.html +0 -15
  141. package/docs/static/examples/eventbus/eventbus.html +0 -13
  142. package/docs/static/examples/eventbus/eventbus.js +0 -15
  143. package/docs/static/examples/eventbus/eventbus.test.js +0 -19
  144. package/docs/static/examples/ng-bind/ng-bind.html +0 -9
  145. package/docs/static/examples/ng-blur/ng-blur.html +0 -9
  146. package/docs/static/examples/ng-channel/ng-channel-test.html +0 -17
  147. package/docs/static/examples/ng-channel/ng-channel.html +0 -24
  148. package/docs/static/examples/ng-channel/ng-channel.test.js +0 -31
  149. package/docs/static/examples/ng-class/ng-class.html +0 -71
  150. package/docs/static/examples/ng-class-even/ng-class-even.html +0 -8
  151. package/docs/static/examples/ng-class-odd/ng-class-odd.html +0 -8
  152. package/docs/static/examples/ng-click/ng-click.html +0 -6
  153. package/docs/static/examples/ng-copy/ng-copy.html +0 -6
  154. package/docs/static/examples/ng-cut/ng-cut.html +0 -6
  155. package/docs/static/examples/ng-dblclick/ng-dblclick.html +0 -10
  156. package/docs/static/examples/ng-focus/ng-focus.html +0 -9
  157. package/docs/static/examples/ng-keydown/ng-keydown.html +0 -9
  158. package/docs/static/examples/ng-keyup/ng-keyup.html +0 -9
  159. package/docs/static/examples/ng-load/ng-load.html +0 -8
  160. package/docs/static/examples/ng-mousedown/ng-mousedown.html +0 -6
  161. package/docs/static/examples/ng-mouseenter/ng-mouseenter.html +0 -4
  162. package/docs/static/examples/ng-mouseleave/ng-mouseleave.html +0 -4
  163. package/docs/static/examples/ng-mousemove/ng-mousemove.html +0 -4
  164. package/docs/static/examples/ng-mouseout/ng-mouseout.html +0 -4
  165. package/docs/static/examples/ng-mouseover/ng-mouseover.html +0 -4
  166. package/docs/static/examples/ng-mouseup/ng-mouseup.html +0 -4
  167. package/docs/static/examples/ng-non-bindable/ng-non-bindable-test.html +0 -13
  168. package/docs/static/examples/ng-non-bindable/ng-non-bindable.html +0 -3
  169. package/docs/static/examples/ng-non-bindable/ng-non-bindable.test.js +0 -11
  170. package/docs/static/typedoc/.nojekyll +0 -1
  171. package/docs/static/typedoc/assets/hierarchy.js +0 -1
  172. package/docs/static/typedoc/assets/highlight.css +0 -78
  173. package/docs/static/typedoc/assets/icons.js +0 -18
  174. package/docs/static/typedoc/assets/icons.svg +0 -1
  175. package/docs/static/typedoc/assets/main.js +0 -60
  176. package/docs/static/typedoc/assets/navigation.js +0 -1
  177. package/docs/static/typedoc/assets/search.js +0 -1
  178. package/docs/static/typedoc/assets/style.css +0 -1633
  179. package/docs/static/typedoc/classes/Location.html +0 -55
  180. package/docs/static/typedoc/classes/LocationProvider.html +0 -20
  181. package/docs/static/typedoc/classes/LogProvider.html +0 -6
  182. package/docs/static/typedoc/classes/PubSub.html +0 -71
  183. package/docs/static/typedoc/classes/PubSubProvider.html +0 -3
  184. package/docs/static/typedoc/classes/TemplateCacheProvider.html +0 -5
  185. package/docs/static/typedoc/hierarchy.html +0 -1
  186. package/docs/static/typedoc/index.html +0 -1
  187. package/docs/static/typedoc/interfaces/ChangesObject.html +0 -6
  188. package/docs/static/typedoc/interfaces/ComponentOptions.html +0 -16
  189. package/docs/static/typedoc/interfaces/Controller.html +0 -12
  190. package/docs/static/typedoc/interfaces/DefaultPorts.html +0 -5
  191. package/docs/static/typedoc/interfaces/Directive.html +0 -37
  192. package/docs/static/typedoc/interfaces/DirectivePrePost.html +0 -4
  193. package/docs/static/typedoc/interfaces/Html5Mode.html +0 -23
  194. package/docs/static/typedoc/interfaces/HttpHeadersGetter.html +0 -1
  195. package/docs/static/typedoc/interfaces/HttpProviderDefaults.html +0 -31
  196. package/docs/static/typedoc/interfaces/HttpRequestConfigHeaders.html +0 -6
  197. package/docs/static/typedoc/interfaces/HttpRequestTransformer.html +0 -1
  198. package/docs/static/typedoc/interfaces/HttpResponse.html +0 -7
  199. package/docs/static/typedoc/interfaces/HttpResponseTransformer.html +0 -1
  200. package/docs/static/typedoc/interfaces/HttpService.html +0 -38
  201. package/docs/static/typedoc/interfaces/LogService.html +0 -12
  202. package/docs/static/typedoc/interfaces/NgModelController.html +0 -30
  203. package/docs/static/typedoc/interfaces/NgModelOptions.html +0 -16
  204. package/docs/static/typedoc/interfaces/Provider.html +0 -34
  205. package/docs/static/typedoc/interfaces/RequestConfig.html +0 -48
  206. package/docs/static/typedoc/interfaces/RequestShortcutConfig.html +0 -38
  207. package/docs/static/typedoc/interfaces/ServiceProvider.html +0 -5
  208. package/docs/static/typedoc/interfaces/TemplateCache.html +0 -7
  209. package/docs/static/typedoc/interfaces/TranscludeFunctionObject.html +0 -8
  210. package/docs/static/typedoc/interfaces/UrlParts.html +0 -9
  211. package/docs/static/typedoc/types/AnnotatedDirectiveFactory.html +0 -1
  212. package/docs/static/typedoc/types/AnnotatedFactory.html +0 -8
  213. package/docs/static/typedoc/types/CloneAttachFunction.html +0 -2
  214. package/docs/static/typedoc/types/ControllerConstructor.html +0 -2
  215. package/docs/static/typedoc/types/DirectiveCompileFn.html +0 -2
  216. package/docs/static/typedoc/types/DirectiveController.html +0 -2
  217. package/docs/static/typedoc/types/DirectiveFactory.html +0 -1
  218. package/docs/static/typedoc/types/DirectiveFactoryFn.html +0 -1
  219. package/docs/static/typedoc/types/DirectiveLinkFn.html +0 -2
  220. package/docs/static/typedoc/types/ExpandoStore.html +0 -2
  221. package/docs/static/typedoc/types/Expression.html +0 -6
  222. package/docs/static/typedoc/types/FilterFactory.html +0 -2
  223. package/docs/static/typedoc/types/FilterFn.html +0 -2
  224. package/docs/static/typedoc/types/HttpPromise.html +0 -1
  225. package/docs/static/typedoc/types/HttpResponseStatus.html +0 -1
  226. package/docs/static/typedoc/types/Injectable.html +0 -4
  227. package/docs/static/typedoc/types/InjectableClass.html +0 -1
  228. package/docs/static/typedoc/types/InjectableFactory.html +0 -1
  229. package/docs/static/typedoc/types/LogCall.html +0 -2
  230. package/docs/static/typedoc/types/LogServiceFactory.html +0 -2
  231. package/docs/static/typedoc/types/OnChangesObject.html +0 -2
  232. package/docs/static/typedoc/types/SwapModeType.html +0 -2
  233. package/docs/static/typedoc/types/TController.html +0 -2
  234. package/docs/static/typedoc/types/UrlChangeListener.html +0 -5
  235. package/docs/static/typedoc/variables/EventBus.html +0 -1
  236. package/docs/static/typedoc/variables/SwapMode.html +0 -11
  237. package/docs/static/version.js +0 -13
  238. package/docs/test-results/.last-run.json +0 -4
  239. package/docs/test-results/static-examples-counter-counter-counter-example/error-context.md +0 -50
  240. package/eslint.config.js +0 -26
  241. package/images/android-chrome-192x192.png +0 -0
  242. package/images/android-chrome-512x512.png +0 -0
  243. package/images/apple-touch-icon.png +0 -0
  244. package/images/favicon-16x16.png +0 -0
  245. package/images/favicon-32x32.png +0 -0
  246. package/images/favicon.ico +0 -0
  247. package/images/site.webmanifest +0 -19
  248. package/index.html +0 -86
  249. package/legacy.d.ts +0 -2599
  250. package/playwright.config.ts +0 -81
  251. package/public/jasmine/boot0.js +0 -66
  252. package/public/jasmine/boot1.js +0 -134
  253. package/public/jasmine/jasmine-html.js +0 -970
  254. package/public/jasmine/jasmine.css +0 -323
  255. package/public/jasmine/jasmine.js +0 -11406
  256. package/public/public/README.md +0 -1
  257. package/public/public/circle.html +0 -1
  258. package/public/public/jasmine-helper.css +0 -9
  259. package/public/public/my_child_directive.html +0 -1
  260. package/public/public/my_directive.html +0 -1
  261. package/public/public/my_other_directive.html +0 -1
  262. package/public/public/test.html +0 -1
  263. package/rollup.config.js +0 -51
  264. package/src/angular.js +0 -293
  265. package/src/angular.spec.js +0 -1191
  266. package/src/animations/animate-cache.js +0 -80
  267. package/src/animations/animate-children-directive.js +0 -32
  268. package/src/animations/animate-children-directive.md +0 -80
  269. package/src/animations/animate-css-driver.js +0 -284
  270. package/src/animations/animate-css.html +0 -58
  271. package/src/animations/animate-css.js +0 -915
  272. package/src/animations/animate-css.md +0 -263
  273. package/src/animations/animate-js-driver.js +0 -60
  274. package/src/animations/animate-js.html +0 -47
  275. package/src/animations/animate-js.js +0 -371
  276. package/src/animations/animate-queue.js +0 -859
  277. package/src/animations/animate-runner.js +0 -193
  278. package/src/animations/animate-swap.js +0 -33
  279. package/src/animations/animate-swap.md +0 -88
  280. package/src/animations/animate.html +0 -19
  281. package/src/animations/animate.js +0 -546
  282. package/src/animations/animate.md +0 -933
  283. package/src/animations/animate.spec.js +0 -490
  284. package/src/animations/animation.js +0 -519
  285. package/src/animations/animations.test.js +0 -10
  286. package/src/animations/interface.ts +0 -19
  287. package/src/animations/raf-scheduler.html +0 -19
  288. package/src/animations/raf-scheduler.js +0 -92
  289. package/src/animations/raf-scheduler.spec.js +0 -98
  290. package/src/animations/shared.js +0 -341
  291. package/src/binding.html +0 -19
  292. package/src/binding.spec.js +0 -474
  293. package/src/binding.test.js +0 -10
  294. package/src/core/compile/attributes.js +0 -337
  295. package/src/core/compile/compile.html +0 -19
  296. package/src/core/compile/compile.js +0 -3270
  297. package/src/core/compile/compile.md +0 -1128
  298. package/src/core/compile/compile.spec.js +0 -15574
  299. package/src/core/compile/compile.test.js +0 -12
  300. package/src/core/controller/controller.html +0 -22
  301. package/src/core/controller/controller.js +0 -189
  302. package/src/core/controller/controller.spec.js +0 -334
  303. package/src/core/controller/controller.test.js +0 -12
  304. package/src/core/core.html +0 -20
  305. package/src/core/core.test.js +0 -12
  306. package/src/core/di/injector.html +0 -19
  307. package/src/core/di/injector.js +0 -307
  308. package/src/core/di/injector.md +0 -740
  309. package/src/core/di/injector.spec.js +0 -2310
  310. package/src/core/di/injector.test.js +0 -12
  311. package/src/core/di/internal-injector.js +0 -284
  312. package/src/core/di/ng-module.html +0 -19
  313. package/src/core/di/ng-module.js +0 -226
  314. package/src/core/di/ng-module.spec.js +0 -263
  315. package/src/core/di/ng-module.test.js +0 -12
  316. package/src/core/filter/filter.html +0 -19
  317. package/src/core/filter/filter.js +0 -55
  318. package/src/core/filter/filter.md +0 -132
  319. package/src/core/filter/filter.spec.js +0 -149
  320. package/src/core/filter/filter.test.js +0 -12
  321. package/src/core/interpolate/interpolate.html +0 -22
  322. package/src/core/interpolate/interpolate.js +0 -408
  323. package/src/core/interpolate/interpolate.spec.js +0 -601
  324. package/src/core/interpolate/interpolate.test.js +0 -12
  325. package/src/core/parse/ast/ast-node.ts +0 -81
  326. package/src/core/parse/ast/ast.html +0 -19
  327. package/src/core/parse/ast/ast.js +0 -574
  328. package/src/core/parse/ast/ast.spec.js +0 -1453
  329. package/src/core/parse/ast/ast.test.js +0 -10
  330. package/src/core/parse/ast-type.js +0 -23
  331. package/src/core/parse/interface.ts +0 -84
  332. package/src/core/parse/interpreter.js +0 -915
  333. package/src/core/parse/lexer/lexer.html +0 -19
  334. package/src/core/parse/lexer/lexer.js +0 -338
  335. package/src/core/parse/lexer/lexer.spec.js +0 -303
  336. package/src/core/parse/lexer/lexer.test.js +0 -10
  337. package/src/core/parse/lexer/token.ts +0 -22
  338. package/src/core/parse/parse.html +0 -19
  339. package/src/core/parse/parse.js +0 -337
  340. package/src/core/parse/parse.md +0 -57
  341. package/src/core/parse/parse.spec.js +0 -2107
  342. package/src/core/parse/parse.test.js +0 -10
  343. package/src/core/parse/parser/parser.html +0 -19
  344. package/src/core/parse/parser/parser.js +0 -64
  345. package/src/core/parse/parser/parser.spec.js +0 -8
  346. package/src/core/parse/parser/parser.test.js +0 -10
  347. package/src/core/prop.spec.js +0 -775
  348. package/src/core/root-element.spec.js +0 -14
  349. package/src/core/sanitize/interface.ts +0 -10
  350. package/src/core/sanitize/sanitize-uri.js +0 -75
  351. package/src/core/sanitize/sanitize-uri.spec.js +0 -249
  352. package/src/core/sanitize/sanitize-uri.test.js +0 -12
  353. package/src/core/sanitize/sanitize.html +0 -22
  354. package/src/core/scope/scope.html +0 -19
  355. package/src/core/scope/scope.js +0 -1249
  356. package/src/core/scope/scope.spec.js +0 -3000
  357. package/src/core/scope/scope.test.js +0 -12
  358. package/src/directive/aria/aria.html +0 -19
  359. package/src/directive/aria/aria.js +0 -382
  360. package/src/directive/aria/aria.md +0 -145
  361. package/src/directive/aria/aria.spec.js +0 -1241
  362. package/src/directive/aria/aria.test.js +0 -12
  363. package/src/directive/attrs/attrs.html +0 -19
  364. package/src/directive/attrs/attrs.js +0 -106
  365. package/src/directive/attrs/attrs.md +0 -224
  366. package/src/directive/attrs/attrs.spec.js +0 -71
  367. package/src/directive/attrs/attrs.test.js +0 -12
  368. package/src/directive/attrs/boolean.html +0 -19
  369. package/src/directive/attrs/boolean.spec.js +0 -137
  370. package/src/directive/attrs/boolean.test.js +0 -12
  371. package/src/directive/attrs/element-style.html +0 -22
  372. package/src/directive/attrs/element-style.spec.js +0 -85
  373. package/src/directive/attrs/element-style.test.js +0 -12
  374. package/src/directive/attrs/src.html +0 -19
  375. package/src/directive/attrs/src.spec.js +0 -163
  376. package/src/directive/attrs/src.test.js +0 -12
  377. package/src/directive/bind/bind-html.spec.js +0 -36
  378. package/src/directive/bind/bind.html +0 -20
  379. package/src/directive/bind/bind.js +0 -78
  380. package/src/directive/bind/bind.md +0 -142
  381. package/src/directive/bind/bind.spec.js +0 -314
  382. package/src/directive/bind/bind.test.js +0 -12
  383. package/src/directive/channel/channel.html +0 -19
  384. package/src/directive/channel/channel.js +0 -30
  385. package/src/directive/channel/channel.spec.js +0 -67
  386. package/src/directive/channel/channel.test.js +0 -10
  387. package/src/directive/class/class-test.html +0 -23
  388. package/src/directive/class/class.html +0 -19
  389. package/src/directive/class/class.js +0 -184
  390. package/src/directive/class/class.spec.js +0 -704
  391. package/src/directive/class/class.test.js +0 -12
  392. package/src/directive/cloak/cloak.html +0 -19
  393. package/src/directive/cloak/cloak.js +0 -11
  394. package/src/directive/cloak/cloak.spec.js +0 -44
  395. package/src/directive/cloak/cloak.test.js +0 -12
  396. package/src/directive/controller/controller.html +0 -22
  397. package/src/directive/controller/controller.js +0 -11
  398. package/src/directive/controller/controller.md +0 -46
  399. package/src/directive/controller/controller.spec.js +0 -175
  400. package/src/directive/controller/controller.test.js +0 -12
  401. package/src/directive/events/click.spec.js +0 -35
  402. package/src/directive/events/event.spec.js +0 -267
  403. package/src/directive/events/events-test.html +0 -36
  404. package/src/directive/events/events.html +0 -20
  405. package/src/directive/events/events.js +0 -65
  406. package/src/directive/events/events.md +0 -125
  407. package/src/directive/events/events.test.js +0 -12
  408. package/src/directive/form/form.html +0 -19
  409. package/src/directive/form/form.js +0 -669
  410. package/src/directive/form/form.spec.js +0 -1515
  411. package/src/directive/form/form.test.js +0 -12
  412. package/src/directive/http/delete.spec.js +0 -26
  413. package/src/directive/http/form-router-test.html +0 -44
  414. package/src/directive/http/form-test.html +0 -18
  415. package/src/directive/http/get.spec.js +0 -488
  416. package/src/directive/http/http.html +0 -22
  417. package/src/directive/http/http.js +0 -342
  418. package/src/directive/http/http.test.js +0 -12
  419. package/src/directive/http/post-example.html +0 -30
  420. package/src/directive/http/post.spec.js +0 -521
  421. package/src/directive/http/put.spec.js +0 -26
  422. package/src/directive/if/if-animate-css.html +0 -57
  423. package/src/directive/if/if-animate-svg.html +0 -25
  424. package/src/directive/if/if.html +0 -19
  425. package/src/directive/if/if.js +0 -72
  426. package/src/directive/if/if.md +0 -76
  427. package/src/directive/if/if.spec.js +0 -293
  428. package/src/directive/if/if.test.js +0 -114
  429. package/src/directive/include/include.html +0 -19
  430. package/src/directive/include/include.js +0 -151
  431. package/src/directive/include/include.md +0 -87
  432. package/src/directive/include/include.spec.js +0 -734
  433. package/src/directive/include/include.test.js +0 -12
  434. package/src/directive/init/init.html +0 -19
  435. package/src/directive/init/init.js +0 -22
  436. package/src/directive/init/init.md +0 -41
  437. package/src/directive/init/init.spec.js +0 -68
  438. package/src/directive/init/init.test.js +0 -12
  439. package/src/directive/input/input-example.html +0 -15
  440. package/src/directive/input/input.html +0 -19
  441. package/src/directive/input/input.js +0 -1078
  442. package/src/directive/input/input.md +0 -706
  443. package/src/directive/input/input.spec.js +0 -3700
  444. package/src/directive/input/input.test.js +0 -12
  445. package/src/directive/messages/messages.html +0 -22
  446. package/src/directive/messages/messages.js +0 -349
  447. package/src/directive/messages/messages.md +0 -543
  448. package/src/directive/messages/messages.spec.js +0 -1083
  449. package/src/directive/messages/messages.test.js +0 -12
  450. package/src/directive/model/change.md +0 -25
  451. package/src/directive/model/model.html +0 -19
  452. package/src/directive/model/model.js +0 -1170
  453. package/src/directive/model/model.spec.js +0 -1976
  454. package/src/directive/model/model.test.js +0 -12
  455. package/src/directive/model-options/model-option.test.js +0 -12
  456. package/src/directive/model-options/model-options.html +0 -22
  457. package/src/directive/model-options/model-options.js +0 -142
  458. package/src/directive/model-options/model-options.md +0 -407
  459. package/src/directive/model-options/model-options.spec.js +0 -1022
  460. package/src/directive/non-bindable/non-bindable.html +0 -22
  461. package/src/directive/non-bindable/non-bindable.js +0 -9
  462. package/src/directive/non-bindable/non-bindable.spec.js +0 -59
  463. package/src/directive/non-bindable/non-bindable.test.js +0 -12
  464. package/src/directive/observe/observe-demo.html +0 -184
  465. package/src/directive/observe/observe.html +0 -19
  466. package/src/directive/observe/observe.js +0 -41
  467. package/src/directive/observe/observe.spec.js +0 -106
  468. package/src/directive/observe/observe.test.js +0 -10
  469. package/src/directive/on/on.html +0 -19
  470. package/src/directive/on/on.spec.js +0 -215
  471. package/src/directive/on/on.test.js +0 -12
  472. package/src/directive/options/options-example.html +0 -17
  473. package/src/directive/options/options.html +0 -22
  474. package/src/directive/options/options.js +0 -542
  475. package/src/directive/options/options.md +0 -179
  476. package/src/directive/options/options.spec.js +0 -3554
  477. package/src/directive/options/options.test.js +0 -12
  478. package/src/directive/ref/href.html +0 -19
  479. package/src/directive/ref/href.spec.js +0 -141
  480. package/src/directive/ref/href.test.js +0 -19
  481. package/src/directive/ref/ref.html +0 -19
  482. package/src/directive/ref/ref.js +0 -89
  483. package/src/directive/ref/ref.spec.js +0 -546
  484. package/src/directive/repeat/repeat.html +0 -19
  485. package/src/directive/repeat/repeat.js +0 -333
  486. package/src/directive/repeat/repeat.md +0 -330
  487. package/src/directive/repeat/repeat.spec.js +0 -1209
  488. package/src/directive/repeat/repeat.test.js +0 -12
  489. package/src/directive/script/script.html +0 -19
  490. package/src/directive/script/script.js +0 -17
  491. package/src/directive/script/script.md +0 -11
  492. package/src/directive/script/script.spec.js +0 -47
  493. package/src/directive/script/script.test.js +0 -12
  494. package/src/directive/select/select.html +0 -19
  495. package/src/directive/select/select.js +0 -594
  496. package/src/directive/select/select.md +0 -74
  497. package/src/directive/select/select.spec.js +0 -2566
  498. package/src/directive/select/select.test.js +0 -12
  499. package/src/directive/setter/setter.html +0 -19
  500. package/src/directive/setter/setter.js +0 -59
  501. package/src/directive/setter/setter.spec.js +0 -100
  502. package/src/directive/setter/setter.test.js +0 -12
  503. package/src/directive/show-hide/show-hide.html +0 -22
  504. package/src/directive/show-hide/show-hide.js +0 -65
  505. package/src/directive/show-hide/show-hide.md +0 -255
  506. package/src/directive/show-hide/show-hide.spec.js +0 -268
  507. package/src/directive/show-hide/show-hide.test.js +0 -12
  508. package/src/directive/style/style.html +0 -19
  509. package/src/directive/style/style.js +0 -27
  510. package/src/directive/style/style.md +0 -23
  511. package/src/directive/style/style.spec.js +0 -183
  512. package/src/directive/style/style.test.js +0 -12
  513. package/src/directive/switch/switch.html +0 -19
  514. package/src/directive/switch/switch.js +0 -133
  515. package/src/directive/switch/switch.md +0 -66
  516. package/src/directive/switch/switch.spec.js +0 -509
  517. package/src/directive/switch/switch.test.js +0 -12
  518. package/src/directive/transclude/transclude.js +0 -122
  519. package/src/directive/validators/validators.html +0 -22
  520. package/src/directive/validators/validators.js +0 -346
  521. package/src/directive/validators/validators.spec.js +0 -740
  522. package/src/directive/validators/validators.test.js +0 -12
  523. package/src/filters/filter.js +0 -213
  524. package/src/filters/filter.md +0 -69
  525. package/src/filters/filter.spec.js +0 -719
  526. package/src/filters/filters.html +0 -22
  527. package/src/filters/filters.js +0 -239
  528. package/src/filters/filters.spec.js +0 -36
  529. package/src/filters/filters.test.js +0 -12
  530. package/src/filters/json.md +0 -16
  531. package/src/filters/limit-to.js +0 -55
  532. package/src/filters/limit-to.md +0 -19
  533. package/src/filters/limit-to.spec.js +0 -252
  534. package/src/filters/order-by.js +0 -181
  535. package/src/filters/order-by.md +0 -83
  536. package/src/filters/order-by.spec.js +0 -883
  537. package/src/index.js +0 -6
  538. package/src/index.spec.js +0 -11
  539. package/src/injection-tokens.js +0 -78
  540. package/src/interface.ts +0 -421
  541. package/src/ng.js +0 -289
  542. package/src/ng.spec.js +0 -33
  543. package/src/router/common/trace.js +0 -240
  544. package/src/router/directives/component-example.html +0 -37
  545. package/src/router/directives/state-directives.html +0 -22
  546. package/src/router/directives/state-directives.js +0 -393
  547. package/src/router/directives/state-directives.md +0 -435
  548. package/src/router/directives/state-directives.spec.js +0 -1091
  549. package/src/router/directives/state-directives.test.js +0 -10
  550. package/src/router/directives/view-directive.js +0 -489
  551. package/src/router/directives/view-directive.spec.js +0 -1937
  552. package/src/router/directives/view-directive.test.js +0 -10
  553. package/src/router/directives/view-directives.html +0 -22
  554. package/src/router/glob/glob.html +0 -19
  555. package/src/router/glob/glob.js +0 -102
  556. package/src/router/glob/glob.spec.js +0 -108
  557. package/src/router/glob/glob.test.js +0 -12
  558. package/src/router/hooks/core-resolvables.js +0 -38
  559. package/src/router/hooks/ignored-transition.js +0 -25
  560. package/src/router/hooks/invalid-transition.js +0 -14
  561. package/src/router/hooks/lazy-load.js +0 -104
  562. package/src/router/hooks/on-enter-exit-retain.js +0 -55
  563. package/src/router/hooks/redirect-to.js +0 -38
  564. package/src/router/hooks/resolve.js +0 -57
  565. package/src/router/hooks/update-globals.js +0 -34
  566. package/src/router/hooks/url.js +0 -34
  567. package/src/router/hooks/views.js +0 -41
  568. package/src/router/params/interface.ts +0 -626
  569. package/src/router/params/param-factory.js +0 -23
  570. package/src/router/params/param-type.js +0 -133
  571. package/src/router/params/param-types.js +0 -153
  572. package/src/router/params/param.js +0 -243
  573. package/src/router/params/state-params.js +0 -36
  574. package/src/router/path/path-node.js +0 -78
  575. package/src/router/path/path-utils.js +0 -207
  576. package/src/router/resolve/interface.ts +0 -208
  577. package/src/router/resolve/resolvable.js +0 -123
  578. package/src/router/resolve/resolve-context.js +0 -190
  579. package/src/router/router-test-hashbang.html +0 -45
  580. package/src/router/router-test.html +0 -41
  581. package/src/router/router.html +0 -22
  582. package/src/router/router.js +0 -54
  583. package/src/router/router.test.js +0 -12
  584. package/src/router/services.spec.js +0 -52
  585. package/src/router/state/README.md +0 -21
  586. package/src/router/state/interface.ts +0 -1007
  587. package/src/router/state/state-builder.js +0 -376
  588. package/src/router/state/state-builder.spec.js +0 -86
  589. package/src/router/state/state-matcher.js +0 -64
  590. package/src/router/state/state-object.js +0 -118
  591. package/src/router/state/state-queue-manager.js +0 -95
  592. package/src/router/state/state-registry.js +0 -257
  593. package/src/router/state/state-service.js +0 -699
  594. package/src/router/state/state.html +0 -23
  595. package/src/router/state/state.spec.js +0 -1002
  596. package/src/router/state/state.test.js +0 -12
  597. package/src/router/state/target-state.js +0 -162
  598. package/src/router/state/views.js +0 -195
  599. package/src/router/state-filter.spec.js +0 -139
  600. package/src/router/state-filters.js +0 -46
  601. package/src/router/template-factory.html +0 -19
  602. package/src/router/template-factory.js +0 -249
  603. package/src/router/template-factory.spec.js +0 -155
  604. package/src/router/template-factory.test.js +0 -12
  605. package/src/router/transition/hook-builder.js +0 -133
  606. package/src/router/transition/hook-registry.js +0 -172
  607. package/src/router/transition/interface.js +0 -18
  608. package/src/router/transition/interface.ts +0 -922
  609. package/src/router/transition/reject-factory.js +0 -122
  610. package/src/router/transition/transition-event-type.js +0 -26
  611. package/src/router/transition/transition-hook.js +0 -199
  612. package/src/router/transition/transition-service.js +0 -302
  613. package/src/router/transition/transition.js +0 -652
  614. package/src/router/url/url-config.js +0 -155
  615. package/src/router/url/url-matcher.js +0 -532
  616. package/src/router/url/url-rule.js +0 -231
  617. package/src/router/url/url-rules.js +0 -350
  618. package/src/router/url/url-service.js +0 -446
  619. package/src/router/url/url-service.spec.js +0 -1288
  620. package/src/router/url/url.html +0 -19
  621. package/src/router/url/url.test.js +0 -12
  622. package/src/router/view/interface.ts +0 -51
  623. package/src/router/view/view.html +0 -19
  624. package/src/router/view/view.js +0 -274
  625. package/src/router/view/view.spec.js +0 -100
  626. package/src/router/view/view.test.js +0 -12
  627. package/src/router/view-hook.spec.js +0 -215
  628. package/src/router/view-scroll.js +0 -33
  629. package/src/router/view-scroll.spec.js +0 -72
  630. package/src/services/anchor-scroll.html +0 -76
  631. package/src/services/anchor-scroll.js +0 -147
  632. package/src/services/cookie-reader.js +0 -48
  633. package/src/services/exception/exception-handler.js +0 -75
  634. package/src/services/exception/interface.ts +0 -7
  635. package/src/services/http/http.html +0 -23
  636. package/src/services/http/http.js +0 -922
  637. package/src/services/http/http.md +0 -413
  638. package/src/services/http/http.spec.js +0 -3941
  639. package/src/services/http/http.test.js +0 -11
  640. package/src/services/http/interface.ts +0 -243
  641. package/src/services/http/template-request.spec.js +0 -220
  642. package/src/services/http-backend/http-backend.html +0 -22
  643. package/src/services/http-backend/http-backend.js +0 -158
  644. package/src/services/http-backend/http-backend.spec.js +0 -389
  645. package/src/services/http-backend/http-backend.test.js +0 -12
  646. package/src/services/location/interface.ts +0 -70
  647. package/src/services/location/location.html +0 -22
  648. package/src/services/location/location.js +0 -1006
  649. package/src/services/location/location.spec.js +0 -3792
  650. package/src/services/location/location.test.js +0 -12
  651. package/src/services/log/interface.ts +0 -39
  652. package/src/services/log/log.html +0 -19
  653. package/src/services/log/log.js +0 -74
  654. package/src/services/log/log.spec.js +0 -64
  655. package/src/services/log/log.test.js +0 -12
  656. package/src/services/pubsub/pubsub.html +0 -19
  657. package/src/services/pubsub/pubsub.js +0 -349
  658. package/src/services/pubsub/pubsub.spec.js +0 -400
  659. package/src/services/pubsub/pubsub.test.js +0 -12
  660. package/src/services/sce/sce.html +0 -19
  661. package/src/services/sce/sce.js +0 -847
  662. package/src/services/sce/sce.md +0 -300
  663. package/src/services/sce/sce.spec.js +0 -617
  664. package/src/services/sce/sce.test.js +0 -12
  665. package/src/services/template-cache/interface.ts +0 -10
  666. package/src/services/template-cache/template-cache.html +0 -22
  667. package/src/services/template-cache/template-cache.js +0 -15
  668. package/src/services/template-cache/template-cache.spec.js +0 -134
  669. package/src/services/template-cache/template-cache.test.js +0 -12
  670. package/src/services/template-request.js +0 -142
  671. package/src/shared/cache.js +0 -7
  672. package/src/shared/common.js +0 -438
  673. package/src/shared/common.spec.js +0 -294
  674. package/src/shared/constants.js +0 -21
  675. package/src/shared/dom.js +0 -716
  676. package/src/shared/hof.js +0 -151
  677. package/src/shared/hof.spec.js +0 -60
  678. package/src/shared/interface.ts +0 -21
  679. package/src/shared/min-err.spec.js +0 -178
  680. package/src/shared/noderef.js +0 -225
  681. package/src/shared/predicates.js +0 -34
  682. package/src/shared/queue.js +0 -105
  683. package/src/shared/queue.spec.js +0 -80
  684. package/src/shared/shared.html +0 -24
  685. package/src/shared/shared.test.js +0 -12
  686. package/src/shared/strings.js +0 -142
  687. package/src/shared/strings.spec.js +0 -40
  688. package/src/shared/test-utils.js +0 -47
  689. package/src/shared/url-utils/interface.ts +0 -54
  690. package/src/shared/url-utils/url-utils.html +0 -22
  691. package/src/shared/url-utils/url-utils.js +0 -122
  692. package/src/shared/url-utils/url-utils.spec.js +0 -148
  693. package/src/shared/url-utils/url-utils.test.js +0 -12
  694. package/src/shared/utils.js +0 -1255
  695. package/src/shared/utils.spec.js +0 -178
  696. package/src/src.html +0 -21
  697. package/src/src.test.js +0 -10
  698. package/tsconfig.json +0 -19
  699. package/tsconfig.types.json +0 -14
  700. package/typedoc.json +0 -8
  701. package/utils/express.js +0 -203
  702. package/utils/version.cjs +0 -23
  703. package/vite.config.js +0 -14
@@ -1,3000 +0,0 @@
1
- import { wait } from "../../shared/test-utils.js";
2
- import { $postUpdateQueue, createScope } from "./scope.js";
3
- import { Angular } from "../../angular.js";
4
- import { createInjector } from "../di/injector.js";
5
- import { isDefined, isProxy, sliceArgs } from "../../shared/utils.js";
6
-
7
- describe("Scope", () => {
8
- let scope;
9
- let $parse;
10
- let logs;
11
- let $rootScope;
12
- let injector;
13
- let count;
14
-
15
- beforeEach(() => {
16
- logs = [];
17
- count = 0;
18
- delete window.angular;
19
- window.angular = new Angular();
20
- window.angular
21
- .module("myModule", ["ng"])
22
- .decorator("$exceptionHandler", function () {
23
- return (exception, cause) => {
24
- logs.push(exception);
25
- console.error(exception, cause);
26
- };
27
- });
28
-
29
- injector = createInjector(["myModule"]);
30
- $parse = injector.get("$parse");
31
- $rootScope = injector.get("$rootScope");
32
- scope = $rootScope;
33
- });
34
-
35
- it("can be instantiated without parameters", () => {
36
- scope = createScope();
37
- expect(scope).toBeDefined();
38
-
39
- scope.a = 1;
40
- expect(scope.a).toEqual(1);
41
- });
42
-
43
- it("can be instantiated with plain object", () => {
44
- scope = createScope({ a: 1, b: { c: 2 } });
45
- expect(scope).toBeDefined();
46
- expect(scope.a).toEqual(1);
47
- expect(scope.b.c).toEqual(2);
48
- scope.a = 2;
49
- expect(scope.a).toEqual(2);
50
- scope.d = 3;
51
- expect(scope.d).toEqual(3);
52
- });
53
-
54
- class Demo {
55
- a = "test";
56
-
57
- check() {
58
- return this.a + "!";
59
- }
60
- }
61
-
62
- it("can be instantiated from a class instance", () => {
63
- scope = createScope(new Demo());
64
- expect(scope.a).toEqual("test");
65
- expect(scope.check()).toEqual("test!");
66
- });
67
-
68
- it("can be instantiated from a class instance as a property", () => {
69
- scope.test = createScope(new Demo());
70
- expect(scope.test.a).toEqual("test");
71
- expect(scope.test.check()).toEqual("test!");
72
- });
73
-
74
- describe("$id", () => {
75
- it("should have a unique id", () => {
76
- expect(scope.$id < scope.$new().$id).toBeTruthy();
77
-
78
- const res = createScope(new Demo());
79
- expect(res.$id).toBeDefined();
80
- });
81
- });
82
-
83
- describe("$target", () => {
84
- it("should have a $target property", () => {
85
- scope = createScope({ a: 1 });
86
- expect(scope.$target).toBeDefined();
87
- });
88
-
89
- it("should make its properties available for getters", () => {
90
- scope = createScope({ a: 1, b: { test: "test" } });
91
- expect(scope.$target).toBeDefined();
92
- expect(scope.a).toEqual(1);
93
- expect(scope.$target.a).toEqual(1);
94
- expect(scope.a).toBe(scope.$target.a);
95
- expect(scope.b).toBe(scope.$target.b);
96
- });
97
-
98
- it("should make its properties available for setters", () => {
99
- scope = createScope({ a: 1, b: { test: "test" } });
100
- expect(scope.$target).toBeDefined();
101
- expect(scope.a).toEqual(1);
102
- scope.a = 2;
103
- expect(scope.$target.a).toEqual(2);
104
- scope.b = 2;
105
- expect(scope.$target.b).toEqual(2);
106
- });
107
- });
108
-
109
- describe("$nonscope", () => {
110
- it("should ignore objects with $nonscope property", () => {
111
- const res = createScope({ $nonscope: true });
112
- expect(res.$id).toBeUndefined();
113
- });
114
-
115
- it("should ignore instances from classes with $nonscope property", () => {
116
- Demo.$nonscope = true;
117
- const res = createScope(new Demo());
118
- expect(res.$id).toBeUndefined();
119
-
120
- Demo.$nonscope = undefined;
121
- });
122
-
123
- it("should ignore classes with static $nonscope property", () => {
124
- class NonScope {
125
- static $nonscope = true;
126
- }
127
- const res = createScope(new NonScope());
128
- expect(res.$id).toBeUndefined();
129
- });
130
-
131
- it("should ignore properties marked as $nonscope array", () => {
132
- class ExcludePropertyScope {
133
- constructor() {
134
- this.a = {};
135
- this.b = [];
136
- }
137
- }
138
- let res = createScope(new ExcludePropertyScope());
139
- expect(res.$id).toBeDefined();
140
- expect(res.a.$id).toBeDefined();
141
- expect(isProxy(res.a)).toBeTrue();
142
-
143
- ExcludePropertyScope.$nonscope = ["a"];
144
- res = createScope(new ExcludePropertyScope());
145
- expect(res.$id).toBeDefined();
146
- expect(res.a.$id).toBeUndefined();
147
- expect(isProxy(res.a)).toBeFalse();
148
- expect(isProxy(res.b)).toBeTrue();
149
-
150
- ExcludePropertyScope.$nonscope = ["a", "b"];
151
- res = createScope(new ExcludePropertyScope());
152
- expect(res.$id).toBeDefined();
153
- expect(res.a.$id).toBeUndefined();
154
- expect(isProxy(res.a)).toBeFalse();
155
- expect(isProxy(res.b)).toBeFalse();
156
-
157
- res = createScope({
158
- a: {},
159
- b: [],
160
- });
161
- expect(res.$id).toBeDefined();
162
- expect(res.a.$id).toBeDefined();
163
- expect(res.b.$id).toBeDefined();
164
- expect(isProxy(res.a)).toBeTrue();
165
- expect(isProxy(res.b)).toBeTrue();
166
-
167
- res = createScope({
168
- a: {},
169
- b: [],
170
- $nonscope: ["a", "b"],
171
- });
172
- expect(res.$id).toBeDefined();
173
- expect(res.a.$id).toBeUndefined();
174
- expect(res.b.$id).toBeUndefined();
175
- expect(isProxy(res.a)).toBeFalse();
176
- expect(isProxy(res.b)).toBeFalse();
177
- });
178
- });
179
-
180
- describe("inheritance", () => {
181
- it("can be constructed and used as an object", () => {
182
- const scope = createScope();
183
- scope.aProperty = 1;
184
-
185
- expect(scope.aProperty).toBe(1);
186
- });
187
-
188
- it("constructs a root scope by default while all children non-root", () => {
189
- const scope = createScope();
190
- expect(scope.$isRoot()).toBe(true);
191
-
192
- const child = scope.$new();
193
- expect(child.$isRoot()).toBe(false);
194
- });
195
-
196
- it("inherits the parents properties", () => {
197
- scope.aValue = [1, 2, 3];
198
-
199
- const child = scope.$new();
200
- expect(child.aValue).toEqual([1, 2, 3]);
201
-
202
- scope.bValue = 2;
203
- expect(child.bValue).toEqual(2);
204
- });
205
-
206
- it("does not cause a parent to inherit its properties", () => {
207
- const child = scope.$new();
208
- child.aValue = [1, 2, 3];
209
-
210
- expect(scope.aValue).toBeUndefined();
211
- });
212
-
213
- it("inherits the parents properties whenever they are defined", () => {
214
- const child = scope.$new();
215
-
216
- scope.aValue = [1, 2, 3];
217
-
218
- expect(child.aValue).toEqual([1, 2, 3]);
219
- });
220
-
221
- it("can create a scope from an existing object", () => {
222
- let instance = { bValue: "child" };
223
- const child = scope.$new(instance);
224
-
225
- scope.aValue = [1, 2, 3];
226
-
227
- expect(child.aValue).toEqual([1, 2, 3]);
228
- expect(child.bValue).toEqual("child");
229
- });
230
-
231
- it("can be nested at any depth", () => {
232
- const a = scope;
233
- const aa = a.$new();
234
- const aaa = aa.$new();
235
- const aab = aa.$new();
236
- const ab = a.$new();
237
- const abb = ab.$new();
238
-
239
- a.value = 1;
240
-
241
- expect(aa.value).toBe(1);
242
- expect(aaa.value).toBe(1);
243
- expect(aab.value).toBe(1);
244
- expect(ab.value).toBe(1);
245
- expect(abb.value).toBe(1);
246
-
247
- ab.anotherValue = 2;
248
-
249
- expect(abb.anotherValue).toBe(2);
250
- expect(aa.anotherValue).toBeUndefined();
251
- expect(aaa.anotherValue).toBeUndefined();
252
- });
253
-
254
- it("can manipulate a parent scopes property", () => {
255
- const child = scope.$new();
256
-
257
- scope.aValue = [1, 2, 3];
258
- child.aValue.push(4);
259
-
260
- expect(child.aValue).toEqual([1, 2, 3, 4]);
261
- expect(scope.aValue).toEqual([1, 2, 3, 4]);
262
- expect(child.aValue).toEqual(scope.aValue);
263
- });
264
-
265
- it("can manipulate a parent scopes property with functions", () => {
266
- class Demo {
267
- test() {
268
- return "Test";
269
- }
270
- increase() {
271
- this.counter++;
272
- }
273
- }
274
-
275
- let instance = new Demo();
276
- expect(instance.test()).toEqual("Test");
277
- const child = scope.$new(instance);
278
-
279
- scope.counter = 0;
280
-
281
- expect(child.counter).toEqual(0);
282
- expect(child.test()).toEqual("Test");
283
-
284
- child.increase();
285
- expect(child.counter).toEqual(1);
286
-
287
- child.increase();
288
- expect(child.counter).toEqual(2);
289
- });
290
-
291
- it("cannot override a parent scopes property", () => {
292
- const child = scope.$new();
293
- scope.aValue = [1, 2, 3];
294
- child.aValue = [1, 2, 3, 4];
295
- scope.bValue = { a: 1 };
296
- child.bValue = { b: 2 };
297
- scope.cValue = 1;
298
- child.cValue = 2;
299
- expect(scope.aValue).toEqual([1, 2, 3]);
300
- expect(child.aValue).toEqual([1, 2, 3, 4]);
301
- expect(scope.bValue).toEqual({ a: 1 });
302
- expect(child.bValue).toEqual({ b: 2 });
303
- expect(scope.cValue).toEqual(1);
304
- expect(child.cValue).toEqual(2);
305
- });
306
-
307
- it("inherits the parents listeners", () => {
308
- const child = scope.$new();
309
-
310
- expect(child.$$listeners).toBe(scope.$$listeners);
311
- });
312
- });
313
-
314
- describe("$new()", () => {
315
- it("should create a child scope", () => {
316
- const child = scope.$new();
317
- scope.a = 123;
318
- expect(child.a).toEqual(123);
319
- });
320
-
321
- it("should create a non prototypically inherited child scope", () => {
322
- const child = scope.$newIsolate();
323
- scope.a = 123;
324
- expect(child.a).toBeUndefined();
325
- expect(child.$parent).toBe(scope.$root);
326
- expect(child.$new).toBeDefined();
327
- expect(child.$root).toEqual(scope.$root);
328
- });
329
-
330
- it("should attach the child scope to a specified parent", () => {
331
- const isolated = scope.$newIsolate();
332
- const trans = scope.$transcluded(isolated);
333
- scope.a = 123;
334
- expect(isolated.a).toBeUndefined();
335
- expect(trans.a).toEqual(123);
336
- expect(trans.$root.$id).toBeDefined();
337
- expect(trans.$root.$id).toEqual(scope.$root.$id);
338
- expect(trans.$parent.$id).toEqual(isolated.$id);
339
- });
340
- });
341
-
342
- describe("$root", () => {
343
- it("should point to itself", () => {
344
- expect(scope.$root.$id).toEqual(scope.$id);
345
- expect(scope.$root).toEqual(scope.$root.$root);
346
- });
347
-
348
- it("should expose the constructor", () => {
349
- expect(Object.getPrototypeOf(scope)).toBe(scope.constructor.prototype);
350
- });
351
-
352
- it("should not have $root on children, but should inherit", () => {
353
- const child = scope.$new();
354
- expect(child.$root).toEqual(scope.$root);
355
- });
356
- });
357
-
358
- describe("$parent", () => {
359
- it("should point to parent", () => {
360
- const child = scope.$new();
361
-
362
- expect(scope.$parent).toEqual(null);
363
- expect(child.$parent.$id).toEqual(scope.$id);
364
- expect(child.$parent).toEqual(scope.$handler);
365
- expect(child.$new().$parent).toEqual(child.$handler);
366
- });
367
-
368
- it("should keep track of its children", () => {
369
- const child = scope.$new();
370
- expect(scope.$children).toEqual([child]);
371
-
372
- const child2 = scope.$new();
373
- expect(scope.$children).toEqual([child, child2]);
374
-
375
- const child3 = child2.$new();
376
- expect(scope.$children).toEqual([child, child2]);
377
- expect(child2.$children).toEqual([child3]);
378
- });
379
-
380
- it("should can get children by id", () => {
381
- const child = scope.$new();
382
- const child2 = scope.$new();
383
- const child3 = child2.$new();
384
- const child4 = child3.$transcluded();
385
-
386
- expect(scope.$getById(child.$id).$id).toEqual(child.$id);
387
- expect(scope.$getById(child2.$id).$id).toEqual(child2.$id);
388
- expect(scope.$getById(child3.$id).$id).toEqual(child3.$id);
389
- expect(scope.$getById(child4.$id).$id).toEqual(child4.$id);
390
- });
391
- });
392
-
393
- describe("this", () => {
394
- it("should evaluate 'this' to be the scope", () => {
395
- const child = scope.$new();
396
- expect(scope.$eval("this")).toEqual(scope.$target);
397
- expect(child.$eval("this")).toEqual(child.$target);
398
- });
399
-
400
- it("'this' should not be recursive", () => {
401
- expect(scope.$eval("this.this")).toBeUndefined();
402
- expect(scope.$eval("$parent.this")).toBeUndefined();
403
- });
404
-
405
- it("should not be able to overwrite the 'this' keyword", () => {
406
- scope.this = 123;
407
- expect(scope.$eval("this")).toEqual(scope);
408
- });
409
-
410
- it("should be able to access a constant variable named 'this'", () => {
411
- scope.this = 42;
412
- expect(scope.$eval("this['this']")).toBe(42);
413
- });
414
- });
415
-
416
- describe("$watch", () => {
417
- it("needs an expression to designate a watched property", async () => {
418
- expect(() => scope.$watch()).toThrowError();
419
- });
420
-
421
- it("does not need a listener function", async () => {
422
- expect(() => scope.$watch("1")).not.toThrowError();
423
- });
424
-
425
- it("can register listeners via watch", async () => {
426
- const listenerFn = jasmine.createSpy();
427
- scope.$watch("a", listenerFn);
428
- scope.a = 1;
429
- await wait();
430
- expect(listenerFn).toHaveBeenCalled();
431
- });
432
-
433
- it("can calls a listener upon registration", async () => {
434
- const listenerFn = jasmine.createSpy();
435
- scope.$watch("a", listenerFn);
436
- await wait();
437
- expect(listenerFn).toHaveBeenCalled();
438
- });
439
-
440
- it("should return a deregistration function watch", () => {
441
- let fn = scope.$watch("a", () => {});
442
- expect(fn).toBeDefined();
443
- expect(typeof fn).toEqual("function");
444
- });
445
-
446
- it("should manipulate the $watcher count", () => {
447
- let fn = scope.$watch("a", () => {});
448
- expect(scope.$$watchersCount).toBeDefined();
449
- expect(scope.$$watchersCount).toEqual(1);
450
-
451
- fn();
452
- expect(scope.$$watchersCount).toEqual(0);
453
- });
454
-
455
- it("should not expose the `inner working of watch", async () => {
456
- let get, listen;
457
- function Listener() {
458
- listen = this;
459
- }
460
- scope.$watch("foo", Listener);
461
-
462
- scope.a = 1;
463
- await wait();
464
-
465
- expect(get).toBeUndefined();
466
- expect(listen).toBeUndefined();
467
- });
468
-
469
- it("can trigger watch from a class", async () => {
470
- let called = false;
471
- class Demo {
472
- constructor() {
473
- this.counter = 0;
474
- }
475
- test() {
476
- this.counter++;
477
- }
478
- }
479
-
480
- scope = createScope(new Demo());
481
-
482
- scope.$watch("counter", () => {
483
- called = true;
484
- });
485
-
486
- expect(scope.counter).toEqual(0);
487
- expect(called).toBeFalse();
488
-
489
- scope.test();
490
- await wait();
491
-
492
- expect(scope.counter).toEqual(1);
493
- expect(called).toBeTrue();
494
- });
495
-
496
- it("can trigger watch from a constuctor function", async () => {
497
- let called = false;
498
- function Demo() {
499
- this.counter = 0;
500
- this.test = function () {
501
- this.counter++;
502
- };
503
- }
504
-
505
- scope = createScope(new Demo());
506
-
507
- scope.$watch("counter", () => {
508
- called = true;
509
- });
510
-
511
- expect(scope.counter).toEqual(0);
512
- expect(called).toBeFalse();
513
-
514
- scope.test();
515
- await wait();
516
-
517
- expect(scope.counter).toEqual(1);
518
- expect(called).toBeTrue();
519
- });
520
-
521
- it("can trigger watch from an POJO object ", async () => {
522
- let called = false;
523
- const demo = {
524
- counter: 0,
525
- test: function () {
526
- this.counter++;
527
- },
528
- };
529
-
530
- scope = createScope(demo);
531
-
532
- scope.$watch("counter", () => {
533
- called = true;
534
- });
535
-
536
- expect(scope.counter).toEqual(0);
537
- expect(called).toBeFalse();
538
-
539
- scope.test();
540
- await wait();
541
-
542
- expect(scope.counter).toEqual(1);
543
- expect(called).toBeTrue();
544
- });
545
-
546
- it("calls the listener function when the watched value is initialized", async () => {
547
- scope.counter = 0;
548
- scope.someValue = "b";
549
- scope.$watch("someValue", () => scope.counter++);
550
- expect(scope.counter).toBe(0);
551
-
552
- await wait();
553
- expect(scope.counter).toBe(1);
554
-
555
- scope.someValue = "b";
556
- await wait();
557
- expect(scope.counter).toBe(1);
558
-
559
- scope.someValue = "c";
560
- await wait();
561
- expect(scope.counter).toBe(2);
562
- });
563
-
564
- it("calls the listener function when the watched value is destroyed", async () => {
565
- scope.counter = 0;
566
- scope.someValue = "b";
567
- expect(scope.counter).toBe(0);
568
-
569
- scope.$watch("someValue", () => scope.counter++);
570
- await wait();
571
- expect(scope.counter).toBe(1);
572
-
573
- delete scope.someValue;
574
- await wait();
575
- expect(scope.counter).toBe(2);
576
- });
577
-
578
- it("can call multiple the listener functions when the watched value changes", async () => {
579
- scope.someValue = "a";
580
- scope.counter = 0;
581
-
582
- scope.$watch("someValue", () => {
583
- scope.counter++;
584
- });
585
-
586
- scope.$watch("someValue", () => scope.counter++);
587
- await wait();
588
- expect(scope.counter).toBe(2);
589
-
590
- scope.someValue = "b";
591
- await wait();
592
- expect(scope.counter).toBe(4);
593
- });
594
-
595
- it("calls only the listeners registerred at the moment the watched value changes", async () => {
596
- scope.someValue = "a";
597
- scope.counter = 0;
598
-
599
- scope.$watch("someValue", () => scope.counter++);
600
- await wait();
601
- expect(scope.counter).toBe(1);
602
-
603
- scope.someValue = "b";
604
- await wait();
605
- expect(scope.counter).toBe(2);
606
-
607
- scope.$watch("someValue", () => {
608
- scope.counter++;
609
- });
610
- await wait();
611
- expect(scope.counter).toBe(3);
612
-
613
- scope.someValue = "b";
614
- await wait();
615
- expect(scope.counter).toBe(3);
616
-
617
- scope.someValue = "c";
618
- await wait();
619
- expect(scope.counter).toBe(5);
620
- });
621
-
622
- it("correctly handles NaNs", async () => {
623
- scope.counter = 0;
624
- scope.$watch("number", function (newValue, scope) {
625
- scope.counter++;
626
- });
627
- scope.number = 0 / 0;
628
- await wait();
629
- expect(scope.number).toBeNaN();
630
- expect(scope.counter).toBe(2);
631
-
632
- scope.number = NaN;
633
- await wait();
634
- expect(scope.number).toBeNaN();
635
- expect(scope.counter).toBe(2);
636
- });
637
-
638
- it("calls listener with undefined old value the first time", async () => {
639
- let newValueGiven;
640
- scope.$watch("someValue", function (newValue, scope) {
641
- newValueGiven = newValue;
642
- });
643
- scope.someValue = 123;
644
- await wait();
645
- expect(newValueGiven).toBe(123);
646
- });
647
-
648
- it("calls listener with new value and old value the first time if defined", async () => {
649
- let newValueGiven;
650
- scope.someValue = 123;
651
-
652
- scope.$watch("someValue", function (newValue) {
653
- newValueGiven = newValue;
654
- });
655
- scope.someValue = 321;
656
- await wait();
657
-
658
- expect(newValueGiven).toBe(321);
659
- });
660
-
661
- it("calls listener with with the instance of a scope as 2nd argument", async () => {
662
- let scopeInstance;
663
- scope.someValue = 123;
664
-
665
- scope.$watch("someValue", function (_1, m) {
666
- scopeInstance = m;
667
- });
668
- scope.someValue = 321;
669
- await wait();
670
-
671
- expect(scopeInstance).toBeDefined();
672
- expect(scopeInstance).toEqual(scope);
673
- });
674
-
675
- it("triggers chained watchers in the same scope change", async () => {
676
- scope.$watch("nameUpper", function (newValue) {
677
- if (newValue) {
678
- scope.initial = newValue.substring(0, 1) + ".";
679
- }
680
- });
681
- scope.$watch("name", function (newValue) {
682
- if (newValue) {
683
- scope.nameUpper = newValue.toUpperCase();
684
- }
685
- });
686
- scope.name = "Jane";
687
- await wait();
688
- expect(scope.initial).toBe("J.");
689
-
690
- scope.name = "Bob";
691
- await wait();
692
- expect(scope.initial).toBe("B.");
693
- });
694
-
695
- it("can register nested watches", async () => {
696
- scope.counter = 0;
697
- scope.aValue = "abc";
698
- scope.$watch("aValue", () => {
699
- scope.$watch("bValue", () => {
700
- scope.counter++;
701
- });
702
- });
703
- scope.aValue = "2";
704
- await wait();
705
- expect(scope.counter).toBe(2);
706
-
707
- scope.bValue = "3";
708
- await wait();
709
- expect(scope.counter).toBe(4);
710
-
711
- scope.aValue = "6";
712
- await wait();
713
- expect(scope.counter).toBe(5);
714
- });
715
-
716
- it("should delegate exceptions", async () => {
717
- scope.$watch("a", () => {
718
- throw new Error("abc");
719
- });
720
- scope.a = 1;
721
- await wait();
722
- expect(logs[0]).toMatch(/abc/);
723
- });
724
-
725
- it("should fire watches in order of addition", async () => {
726
- // this is not an external guarantee, just our own sanity
727
- logs = "";
728
- scope.$watch("a", () => {
729
- logs += "a";
730
- });
731
- scope.$watch("b", () => {
732
- logs += "b";
733
- });
734
- // constant expressions have slightly different handling as they are executed in priority
735
- scope.$watch("1", () => {
736
- logs += "1";
737
- });
738
- scope.$watch("c", () => {
739
- logs += "c";
740
- });
741
- scope.$watch("2", () => {
742
- logs += "2";
743
- });
744
- scope.a = 1;
745
- scope.b = 1;
746
- scope.c = 1;
747
- await wait();
748
- expect(logs).toEqual("ab1c2abc");
749
- });
750
-
751
- it("should repeat watch cycle while scope changes are identified", async () => {
752
- logs = "";
753
- scope.$watch("c", (v) => {
754
- scope.d = v;
755
- logs += "c";
756
- });
757
- scope.$watch("b", (v) => {
758
- scope.c = v;
759
- logs += "b";
760
- });
761
- scope.$watch("a", (v) => {
762
- scope.b = v;
763
- logs += "a";
764
- });
765
- await wait();
766
- expect(logs).toEqual("cba");
767
- logs = "";
768
- scope.a = 1;
769
- await wait();
770
- expect(scope.a).toEqual(1);
771
- expect(scope.b).toEqual(1);
772
- expect(scope.c).toEqual(1);
773
- expect(scope.d).toEqual(1);
774
- expect(logs).toEqual("abc");
775
- });
776
-
777
- describe("constants", () => {
778
- it("does not watch constants", async () => {
779
- scope.$watch("1", () => {});
780
- expect(scope.$$watchersCount).toBe(0);
781
- await wait();
782
- expect(scope.$$watchersCount).toBe(0);
783
- });
784
-
785
- const cases = [
786
- { expression: "1", expected: 1 },
787
- { expression: "'a'", expected: "a" },
788
- { expression: "[1,2,3]", expected: [1, 2, 3] },
789
- { expression: "false", expected: false },
790
- { expression: "null", expected: null },
791
- { expression: '{x: 1}["x"]', expected: 1 },
792
- { expression: "2 + 2", expected: 4 },
793
- { expression: "2 / 0", expected: Infinity },
794
- { expression: "false || 2", expected: 2 },
795
- { expression: "false && 2", expected: false },
796
- ];
797
-
798
- for (const { expression, expected } of cases) {
799
- it("passes constants to listener cb " + expression, async () => {
800
- let res;
801
- scope.$watch(expression, (val) => {
802
- res = val;
803
- });
804
-
805
- await wait();
806
- expect(res).toEqual(expected);
807
- });
808
- }
809
- });
810
-
811
- describe("expressions", () => {
812
- it("its should increase the count of watchers", async () => {
813
- logs = "";
814
- scope.a = 1;
815
- scope.$watch("a", () => {
816
- logs += "a";
817
- });
818
- scope.$watch("b", () => {
819
- logs += "b";
820
- });
821
-
822
- expect(scope.$handler.watchers.size).toEqual(2);
823
- expect(scope.$$watchersCount).toEqual(scope.$handler.watchers.size);
824
- });
825
-
826
- it("should fire upon $watch registration on initial registeration", async () => {
827
- logs = "";
828
- scope.a = 1;
829
- scope.$watch("a", () => {
830
- logs += "a";
831
- });
832
- scope.$watch("b", () => {
833
- logs += "b";
834
- });
835
- await wait();
836
- expect(logs).toEqual("ab");
837
- });
838
-
839
- it("invokes a callback on property change", async () => {
840
- let newV, target;
841
- scope.$watch("foo", (a, b) => {
842
- newV = a;
843
- target = b;
844
- });
845
-
846
- scope.foo = 1;
847
- await wait();
848
- expect(newV).toEqual(1);
849
- expect(target).toEqual(scope.$target);
850
-
851
- scope.foo = 2;
852
- await wait();
853
- expect(newV).toEqual(2);
854
- expect(target).toEqual(scope.$target);
855
-
856
- scope.foo = [];
857
- await wait();
858
- expect(newV).toEqual([]);
859
- expect(target).toEqual(scope.$target);
860
- });
861
-
862
- it("calls the listener function when the watched value changes", async () => {
863
- scope.counter = 0;
864
- scope.$watch("someValue", function (newValue, scope) {
865
- scope.counter++;
866
- });
867
- await wait();
868
- expect(scope.counter).toBe(1);
869
-
870
- scope.someValue = "1";
871
- await wait();
872
- expect(scope.counter).toBe(2);
873
-
874
- scope.someValue = "2";
875
- await wait();
876
- expect(scope.counter).toBe(3);
877
- });
878
-
879
- it("should watch and fire on simple property change", async () => {
880
- const spy = jasmine.createSpy();
881
- scope.$watch("name", spy);
882
-
883
- spy.calls.reset();
884
-
885
- expect(spy).not.toHaveBeenCalled();
886
- scope.name = "misko";
887
- await wait();
888
- expect(spy).toHaveBeenCalledWith("misko", scope);
889
- });
890
-
891
- it("should watch and fire on correct expression change", async () => {
892
- const spy = jasmine.createSpy();
893
- scope.$watch("name.first", spy);
894
- await wait();
895
- expect(spy).toHaveBeenCalled();
896
-
897
- spy.calls.reset();
898
- scope.name = {};
899
- await wait();
900
- expect(spy).not.toHaveBeenCalled();
901
-
902
- spy.calls.reset();
903
- scope.first = "bruno";
904
- await wait();
905
- expect(spy).not.toHaveBeenCalled();
906
-
907
- spy.calls.reset();
908
- scope.name.first = "misko";
909
- await wait();
910
- expect(spy).toHaveBeenCalled();
911
-
912
- spy.calls.reset();
913
- scope.first = "misko";
914
- await wait();
915
- expect(spy).not.toHaveBeenCalled();
916
- });
917
- });
918
-
919
- describe("array expressions", () => {
920
- it("adds watches for array expressions", async () => {
921
- expect(scope.$$watchersCount).toBe(0);
922
- scope.$watch("foo[0]", () => {});
923
-
924
- await wait();
925
- expect(scope.$$watchersCount).toBe(1);
926
- });
927
-
928
- it("adds watches for array expressions", async () => {
929
- expect(scope.$$watchersCount).toBe(0);
930
- let res;
931
-
932
- scope.$watch("foo[0]", (val) => {
933
- res = val;
934
- });
935
-
936
- scope.foo = [];
937
- await wait();
938
- expect(scope.$$watchersCount).toBe(1);
939
-
940
- scope.foo = [1];
941
- await wait();
942
- expect(res).toEqual(1);
943
-
944
- scope.foo = [2];
945
- await wait();
946
- expect(res).toEqual(2);
947
- });
948
- });
949
-
950
- describe("apply expression", () => {
951
- it("adds watches for expressions", async () => {
952
- expect(scope.$$watchersCount).toBe(0);
953
- scope.$watch("foo = 1", () => {});
954
-
955
- await wait();
956
- expect(scope.$$watchersCount).toBe(1);
957
- });
958
-
959
- it("applies a property change and continues watching the scopes", async () => {
960
- expect(scope.$$watchersCount).toBe(0);
961
- scope.$watch("foo = 2", () => {});
962
-
963
- await wait();
964
- expect(scope.$$watchersCount).toBe(1);
965
- expect(scope.$handler.watchers.has("foo")).toBeTrue();
966
- expect(scope.foo).toBe(2);
967
-
968
- scope.$watch("boo = 3", () => {});
969
-
970
- await wait();
971
- expect(scope.$$watchersCount).toBe(2);
972
- expect(scope.boo).toBe(3);
973
- });
974
-
975
- it("should apply a change and not increase watchers if no listener function", async () => {
976
- expect(scope.$$watchersCount).toBe(0);
977
- scope.$watch("foo = 2");
978
-
979
- await wait();
980
- expect(scope.$$watchersCount).toBe(0);
981
- expect(scope.foo).toBe(2);
982
-
983
- scope.$watch("foo = 3");
984
-
985
- await wait();
986
- expect(scope.$$watchersCount).toBe(0);
987
- expect(scope.foo).toBe(3);
988
- });
989
- });
990
-
991
- describe("filters", () => {
992
- it("applies filters to constants", async () => {
993
- expect(scope.$$watchersCount).toBe(0);
994
- let res;
995
- scope.$watch("'abcd'|limitTo:3", (val) => {
996
- res = val;
997
- });
998
- await wait();
999
- expect(res).toEqual("abc");
1000
-
1001
- scope.$watch("'abcd'|limitTo:3|limitTo:2", (val) => {
1002
- res = val;
1003
- });
1004
-
1005
- await wait();
1006
- expect(res).toEqual("ab");
1007
-
1008
- scope.$watch("'abcd'|limitTo:3|limitTo:2|limitTo:1", (val) => {
1009
- res = val;
1010
- });
1011
-
1012
- await wait();
1013
- expect(res).toEqual("a");
1014
- });
1015
- });
1016
-
1017
- describe("$watch on constants", () => {
1018
- beforeEach(() => (logs = []));
1019
- it("should not $watch constant literals ", () => {
1020
- scope.$watch("[]", () => {});
1021
- scope.$watch("{}", () => {});
1022
- scope.$watch("1", () => {});
1023
- scope.$watch('"foo"', () => {});
1024
- expect(scope.$$watchersCount).toEqual(0);
1025
- });
1026
-
1027
- it("should not $watch filtered literals", () => {
1028
- scope.$watch('[1] | filter:"x"', () => {});
1029
- scope.$watch("1 | limitTo:2", () => {});
1030
- expect(scope.$$watchersCount).toEqual(0);
1031
- });
1032
-
1033
- it("should ignore $watch of constant expressions", () => {
1034
- scope.$watch("1 + 1", () => {});
1035
- scope.$watch('"a" + "b"', () => {});
1036
- scope.$watch('"ab".length', () => {});
1037
- scope.$watch("[].length", () => {});
1038
- scope.$watch("(1 + 1) | limitTo:2", () => {});
1039
- expect(scope.$$watchersCount).toEqual(0);
1040
- });
1041
- });
1042
-
1043
- describe("watching objects", () => {
1044
- it("should watch objects", async () => {
1045
- scope.a = { c: 2 };
1046
- scope.$watch("a", (value) => {
1047
- logs += "success";
1048
- expect(value).toEqual(scope.a);
1049
- });
1050
- await wait();
1051
- logs = "";
1052
- scope.a.c = "1";
1053
-
1054
- await wait();
1055
- expect(logs).toEqual("success");
1056
- });
1057
-
1058
- it("calls the listener function registered via function when a value is created as an object", async () => {
1059
- scope.counter = 0;
1060
-
1061
- scope.$watch("someValue", () => {
1062
- scope.counter++;
1063
- });
1064
- await wait();
1065
-
1066
- expect(scope.counter).toBe(1);
1067
-
1068
- scope.someValue = {};
1069
- await wait();
1070
-
1071
- expect(scope.counter).toBe(2);
1072
-
1073
- scope.someValue = { a: 3 };
1074
- await wait();
1075
-
1076
- expect(scope.counter).toBe(3);
1077
-
1078
- // Should not trigger as we are updating the inner object and we are not listening on its property
1079
- scope.someValue.a = 4;
1080
- await wait();
1081
-
1082
- expect(scope.counter).toBe(3);
1083
- });
1084
-
1085
- it("calls the listener function registered via expression when a value is created as an object", async () => {
1086
- scope.counter = 0;
1087
-
1088
- scope.$watch("someValue", () => {
1089
- scope.counter++;
1090
- });
1091
- await wait();
1092
-
1093
- expect(scope.counter).toBe(1);
1094
-
1095
- scope.someValue = {};
1096
- await wait();
1097
-
1098
- expect(scope.counter).toBe(2);
1099
- });
1100
-
1101
- it("calls the listener function registered via function when a value is created on a nested object", async () => {
1102
- scope.counter = 0;
1103
- scope.a = { someValue: 1 };
1104
- scope.$watch("a.someValue", () => {
1105
- scope.counter++;
1106
- });
1107
- await wait();
1108
- expect(scope.counter).toBe(1);
1109
-
1110
- scope.a.someValue = 2;
1111
-
1112
- await wait();
1113
- expect(scope.counter).toBe(2);
1114
-
1115
- scope.a.someValue = 3;
1116
- await wait();
1117
- expect(scope.counter).toBe(3);
1118
- });
1119
-
1120
- it("calls the listener function registered via expression when a value is created on a nested object", async () => {
1121
- scope.counter = 0;
1122
- scope.a = { someValue: 1 };
1123
-
1124
- scope.$watch("a.someValue", () => {
1125
- scope.counter++;
1126
- });
1127
-
1128
- await wait();
1129
- expect(scope.counter).toBe(1);
1130
-
1131
- scope.a.someValue = 2;
1132
-
1133
- await wait();
1134
- expect(scope.counter).toBe(2);
1135
-
1136
- scope.a.someValue = 3;
1137
- await wait();
1138
- expect(scope.counter).toBe(3);
1139
- });
1140
-
1141
- it("calls the listener function when a nested value is created on an empty wrapper object", async () => {
1142
- scope.counter = 0;
1143
- scope.someValue = {};
1144
-
1145
- scope.$watch("someValue.b", () => {
1146
- scope.counter++;
1147
- });
1148
- await wait();
1149
-
1150
- expect(scope.counter).toBe(1);
1151
- scope.someValue = { b: 2 };
1152
- await wait();
1153
-
1154
- expect(scope.counter).toBe(2);
1155
- });
1156
-
1157
- it("calls the listener function when a nested value is created on an undefined wrapper object", async () => {
1158
- scope.counter = 0;
1159
- scope.someValue = undefined;
1160
-
1161
- scope.$watch("someValue.b", async () => {
1162
- scope.counter++;
1163
- });
1164
- await wait();
1165
-
1166
- expect(scope.counter).toBe(1);
1167
-
1168
- scope.someValue = { b: 2 };
1169
- await wait();
1170
-
1171
- expect(scope.counter).toBe(2);
1172
-
1173
- scope.someValue.b = 3;
1174
- await wait();
1175
-
1176
- expect(scope.counter).toBe(3);
1177
- });
1178
-
1179
- it("calls the listener function when a nested value is created from a wrapper object", async () => {
1180
- scope.someValue = { b: 1 };
1181
- scope.counter = 0;
1182
-
1183
- scope.$watch("someValue.b", () => scope.counter++);
1184
- await wait();
1185
- expect(scope.counter).toBe(1);
1186
-
1187
- scope.someValue = { b: 2 };
1188
- await wait();
1189
- expect(scope.counter).toBe(2);
1190
-
1191
- scope.someValue = { c: 2 };
1192
- await wait();
1193
- expect(scope.counter).toBe(3);
1194
-
1195
- scope.someValue = { b: 2 };
1196
- await wait();
1197
- expect(scope.counter).toBe(4);
1198
-
1199
- scope.someValue = undefined;
1200
- await wait();
1201
- expect(scope.counter).toBe(5);
1202
- });
1203
-
1204
- it("call the listener function when a nested value is created from an instance", async () => {
1205
- let ctrl = createScope({ scope: { name: "John" } });
1206
- let count = 0;
1207
- expect(ctrl.scope.name).toEqual("John");
1208
-
1209
- ctrl.$watch("scope.name", () => {
1210
- count++;
1211
- });
1212
- await wait();
1213
- expect(count).toEqual(1);
1214
-
1215
- ctrl.scope.name = "Bob";
1216
- await wait();
1217
- expect(count).toEqual(2);
1218
-
1219
- ctrl.scope.name = "John";
1220
- await wait();
1221
- expect(count).toEqual(3);
1222
-
1223
- ctrl.scope.lastName = "NaN";
1224
- await wait();
1225
-
1226
- expect(count).toEqual(3);
1227
- });
1228
-
1229
- it("calls the listener function when a deeply nested watched value changes", async () => {
1230
- scope.counter = 0;
1231
- scope.someValue = { b: { c: { d: 1 } } };
1232
-
1233
- scope.$watch("someValue.b.c.d", function (newValue, scope) {
1234
- scope.counter++;
1235
- });
1236
- await wait();
1237
- expect(scope.counter).toBe(1);
1238
-
1239
- scope.someValue.b.c.d = 2;
1240
- await wait();
1241
- expect(scope.counter).toBe(2);
1242
-
1243
- scope.someValue = { b: { c: { d: 3 } } };
1244
- await wait();
1245
-
1246
- expect(scope.counter).toBe(3);
1247
- });
1248
-
1249
- it("call the listener function on correct listener", async () => {
1250
- scope.counter = 0;
1251
- scope.someValue = { b: { c: 1 } };
1252
-
1253
- scope.$watch("someValue.b.c", function (newValue, scope) {
1254
- scope.counter++;
1255
- });
1256
- await wait();
1257
- expect(scope.counter).toBe(1);
1258
-
1259
- scope.c = 5;
1260
- await wait();
1261
- expect(scope.counter).toBe(1);
1262
- });
1263
-
1264
- it("calls the listener function when a deeply nested watched value is initially undefined", async () => {
1265
- scope.counter = 0;
1266
- scope.someValue = { b: { c: undefined } };
1267
-
1268
- scope.$watch("someValue.b.c.d", function (newValue, scope) {
1269
- scope.counter++;
1270
- });
1271
- await wait();
1272
- expect(scope.counter).toBe(1);
1273
-
1274
- scope.someValue = { b: { c: { d: 2 } } };
1275
- await wait();
1276
- expect(scope.counter).toBe(2);
1277
-
1278
- scope.someValue.b.c.d = 3;
1279
- await wait();
1280
- expect(scope.counter).toBe(3);
1281
- });
1282
- });
1283
-
1284
- describe("inherited $watch", () => {
1285
- it("should decrement the watcherCount when destroying a child scope", () => {
1286
- const child1 = scope.$new();
1287
- const child2 = scope.$new();
1288
-
1289
- expect(scope.$$watchersCount).toBe(0);
1290
- expect(child1.$$watchersCount).toBe(0);
1291
- expect(child1.$$watchersCount).toBe(0);
1292
-
1293
- const grandChild1 = child1.$new();
1294
- const grandChild2 = child2.$new();
1295
- child1.$watch("a", () => {});
1296
- expect(scope.$$watchersCount).toBe(1);
1297
- expect(child1.$$watchersCount).toBe(1);
1298
-
1299
- child2.$watch("a", () => {});
1300
- expect(scope.$$watchersCount).toBe(2);
1301
- expect(child2.$$watchersCount).toBe(1);
1302
-
1303
- grandChild1.$watch("a", () => {});
1304
- expect(grandChild1.$$watchersCount).toBe(1);
1305
- expect(child1.$$watchersCount).toBe(2);
1306
-
1307
- grandChild2.$watch("a", () => {});
1308
- expect(grandChild2.$$watchersCount).toBe(1);
1309
- expect(child2.$$watchersCount).toBe(2);
1310
-
1311
- // a watcher is shared by all
1312
- expect(scope.$$watchersCount).toBe(4);
1313
- expect(child1.$$watchersCount).toBe(2);
1314
- expect(grandChild1.$$watchersCount).toBe(1);
1315
- expect(child2.$$watchersCount).toBe(2);
1316
- expect(grandChild1.$$watchersCount).toBe(1);
1317
- expect(grandChild2.$$watchersCount).toBe(1);
1318
- grandChild2.$destroy();
1319
-
1320
- expect(child2.$$watchersCount).toBe(1);
1321
- expect(scope.$$watchersCount).toBe(3);
1322
-
1323
- child1.$destroy();
1324
- expect(child1.$$watchersCount).toBe(1);
1325
- expect(scope.$$watchersCount).toBe(1);
1326
- });
1327
-
1328
- it("should decrement the watcherCount when calling the remove function", () => {
1329
- const child1 = scope.$new();
1330
- const child2 = scope.$new();
1331
- const grandChild1 = child1.$new();
1332
- const grandChild2 = child2.$new();
1333
- let remove1 = child1.$watch("a", () => {});
1334
- child2.$watch("a", () => {});
1335
- grandChild1.$watch("a", () => {});
1336
- let remove2 = grandChild2.$watch("a", () => {});
1337
-
1338
- expect(grandChild2.$$watchersCount).toBe(1);
1339
- expect(child2.$$watchersCount).toBe(2);
1340
- expect(scope.$$watchersCount).toBe(4);
1341
-
1342
- expect(remove2()).toBeTrue();
1343
- expect(grandChild2.$$watchersCount).toBe(0);
1344
- expect(child2.$$watchersCount).toBe(1);
1345
- expect(scope.$$watchersCount).toBe(3);
1346
-
1347
- expect(grandChild1.$$watchersCount).toBe(1);
1348
- expect(child1.$$watchersCount).toBe(2);
1349
-
1350
- expect(remove1()).toBeTrue();
1351
- expect(grandChild1.$$watchersCount).toBe(1);
1352
- expect(child1.$$watchersCount).toBe(1);
1353
- expect(scope.$$watchersCount).toBe(2);
1354
-
1355
- // Execute everything a second time to be sure that calling the remove function
1356
- // several times, it only decrements the counter once
1357
- remove2();
1358
- expect(child2.$$watchersCount).toBe(1);
1359
- expect(scope.$$watchersCount).toBe(2);
1360
- remove1();
1361
- expect(child1.$$watchersCount).toBe(1);
1362
- expect(scope.$$watchersCount).toBe(2);
1363
- });
1364
-
1365
- it("should call child $watchers in addition order", async () => {
1366
- logs = "";
1367
- const childA = scope.$new();
1368
- childA.$watch("a", () => {
1369
- logs += "a";
1370
- });
1371
- childA.$watch("a", () => {
1372
- logs += "b";
1373
- });
1374
- childA.$watch("a", () => {
1375
- logs += "c";
1376
- });
1377
- await wait();
1378
- logs = "";
1379
- childA.a = 1;
1380
- await wait();
1381
- expect(logs).toEqual("abc");
1382
- });
1383
-
1384
- it("should share listeners with parent", async () => {
1385
- logs = "";
1386
- const childA = scope.$new();
1387
- const childB = scope.$new();
1388
-
1389
- scope.$watch("a", () => {
1390
- logs += "r";
1391
- });
1392
-
1393
- childA.$watch("a", () => {
1394
- logs += "a";
1395
- });
1396
- childB.$watch("a", () => {
1397
- logs += "b";
1398
- });
1399
- await wait();
1400
- logs = "";
1401
-
1402
- // init
1403
- scope.a = 1;
1404
- await wait();
1405
- expect(logs).toBe("rab");
1406
-
1407
- logs = "";
1408
- childA.a = 3;
1409
- await wait();
1410
- expect(logs).toBe("rab");
1411
-
1412
- logs = "";
1413
- childA.a = 4;
1414
- await wait();
1415
- expect(logs).toBe("rab");
1416
- });
1417
-
1418
- it("should repeat watch cycle from the root element", async () => {
1419
- logs = "";
1420
- const child = scope.$new();
1421
- scope.$watch("c", () => {
1422
- logs += "a";
1423
- });
1424
- child.$watch("c", () => {
1425
- logs += "b";
1426
- });
1427
- await wait();
1428
- logs = "";
1429
- scope.c = 1;
1430
- child.c = 2;
1431
- await wait();
1432
- expect(logs).toEqual("abab");
1433
- });
1434
- });
1435
-
1436
- it("should watch functions", async () => {
1437
- scope.$watch("fn", (fn) => {
1438
- logs.push(fn);
1439
- });
1440
- await wait();
1441
- logs = [];
1442
- scope.fn = function () {
1443
- return "a";
1444
- };
1445
- await wait();
1446
- expect(logs).toEqual(["a"]);
1447
- scope.fn = function () {
1448
- return "b";
1449
- };
1450
- await wait();
1451
- expect(logs).toEqual(["a", "b"]);
1452
- });
1453
-
1454
- it("should allow a watch to be added while in a digest", async () => {
1455
- const watch1 = jasmine.createSpy("watch1");
1456
- const watch2 = jasmine.createSpy("watch2");
1457
- scope.$watch("foo", () => {
1458
- scope.$watch("foo", watch1);
1459
- scope.$watch("foo", watch2);
1460
- });
1461
-
1462
- scope.$apply("foo = true");
1463
- await wait();
1464
- expect(watch1).toHaveBeenCalled();
1465
- expect(watch2).toHaveBeenCalled();
1466
- });
1467
-
1468
- it("should not skip watchers when adding new watchers during digest", async () => {
1469
- const watch1 = jasmine.createSpy("watch1");
1470
- const watch2 = jasmine.createSpy("watch2");
1471
- scope.$watch("foo", () => {
1472
- scope.$watch("foo", watch1);
1473
- scope.$watch("foo", watch2);
1474
- });
1475
- scope.foo = "a";
1476
- await wait();
1477
- expect(watch1).toHaveBeenCalled();
1478
- expect(watch2).toHaveBeenCalled();
1479
- });
1480
-
1481
- it("should not skip watchers when adding new watchers during property update", async () => {
1482
- const watch1 = jasmine.createSpy("watch1");
1483
- const watch2 = jasmine.createSpy("watch2");
1484
- scope.$watch("foo", () => {
1485
- scope.$watch("foo", watch1);
1486
- scope.$watch("foo", watch2);
1487
- });
1488
- scope.foo = 2;
1489
- await wait();
1490
- expect(watch1).toHaveBeenCalled();
1491
- expect(watch2).toHaveBeenCalled();
1492
- });
1493
-
1494
- describe("$watch deregistration", () => {
1495
- beforeEach(() => (logs = []));
1496
- it("should return a function that allows listeners to be deregistered", async () => {
1497
- const listener = jasmine.createSpy("watch listener");
1498
- let listenerRemove;
1499
-
1500
- listenerRemove = scope.$watch("foo", listener);
1501
-
1502
- expect(listener).not.toHaveBeenCalled();
1503
- expect(listenerRemove).toBeDefined();
1504
-
1505
- scope.foo = "bar";
1506
- await wait();
1507
- expect(listener).toHaveBeenCalled();
1508
-
1509
- listener.calls.reset();
1510
- listenerRemove();
1511
- scope.foo = "baz";
1512
- await wait();
1513
- expect(listener).not.toHaveBeenCalled();
1514
- });
1515
-
1516
- it("should allow a watch to be deregistered while in a digest", async () => {
1517
- let remove1;
1518
- let remove2;
1519
- scope.$watch("remove", () => {
1520
- remove1();
1521
- remove2();
1522
- });
1523
- remove1 = scope.$watch("thing", () => {});
1524
- remove2 = scope.$watch("thing", () => {});
1525
- expect(async () => {
1526
- scope.$apply("remove = true");
1527
- await wait();
1528
- }).not.toThrow();
1529
- });
1530
- });
1531
-
1532
- describe("watching arrays", () => {
1533
- it("can watch arrays", async () => {
1534
- scope.aValue = [1, 2, 3];
1535
- scope.counter = 0;
1536
- scope.$watch("aValue", function (newValue, m) {
1537
- m.counter++;
1538
- });
1539
- await wait();
1540
- expect(scope.counter).toBe(1);
1541
-
1542
- scope.aValue.push(4);
1543
- await wait();
1544
- expect(scope.counter).toBe(2);
1545
-
1546
- scope.aValue.pop();
1547
- await wait();
1548
- expect(scope.counter).toBe(3);
1549
-
1550
- scope.aValue.unshift(4);
1551
- await wait();
1552
- expect(scope.counter).toBe(4);
1553
- });
1554
-
1555
- it("can pass the new value of the array as well as the previous value of the dropped item", async () => {
1556
- scope.aValue = [];
1557
- let newValueGiven;
1558
- scope.$watch("aValue", function (newValue) {
1559
- newValueGiven = newValue;
1560
- });
1561
-
1562
- scope.aValue.push(4);
1563
- await wait();
1564
- expect(newValueGiven).toEqual(scope.aValue);
1565
-
1566
- scope.aValue.push(5);
1567
- await wait();
1568
- expect(newValueGiven).toEqual([4, 5]);
1569
-
1570
- scope.aValue[1] = 2;
1571
- await wait();
1572
- expect(newValueGiven).toEqual([4, 2]);
1573
-
1574
- scope.aValue[0] = 2;
1575
- await wait();
1576
- expect(newValueGiven).toEqual([2, 2]);
1577
- });
1578
-
1579
- it("can detect removal of items", async () => {
1580
- scope.aValue = [2, 3];
1581
- let newValueGiven;
1582
- scope.$watch("aValue", function (newValue) {
1583
- newValueGiven = newValue;
1584
- });
1585
-
1586
- scope.aValue.pop();
1587
- await wait();
1588
- expect(newValueGiven).toEqual([2]);
1589
- });
1590
-
1591
- it("should return oldCollection === newCollection only on the first listener call", async () => {
1592
- // first time should be identical
1593
- scope.aValue = ["a", "b"];
1594
- scope.counter = 0;
1595
- let newValueGiven;
1596
- scope.$watch("aValue", function (newValue, m) {
1597
- newValueGiven = newValue;
1598
- m.counter++;
1599
- });
1600
- await wait();
1601
- expect(scope.counter).toBe(1);
1602
-
1603
- scope.aValue[1] = "c";
1604
- await wait();
1605
- expect(newValueGiven).toEqual(["a", "c"]);
1606
- expect(scope.counter).toBe(2);
1607
- });
1608
-
1609
- it("should trigger when property changes into array", async () => {
1610
- scope.aValue = "test";
1611
- scope.counter = 0;
1612
- let newValue;
1613
- scope.$watch("aValue", function (newV, m) {
1614
- m.counter++;
1615
- newValue = newV;
1616
- });
1617
-
1618
- scope.aValue = [];
1619
- await wait();
1620
- expect(scope.counter).toBe(2);
1621
- expect(newValue).toEqual([]);
1622
-
1623
- scope.aValue = {};
1624
- await wait();
1625
- expect(scope.counter).toBe(3);
1626
- expect(newValue).toEqual({});
1627
-
1628
- scope.aValue = [];
1629
- await wait();
1630
- expect(scope.counter).toBe(4);
1631
- expect(newValue).toEqual([]);
1632
-
1633
- scope.aValue = {};
1634
- await wait();
1635
- expect(scope.counter).toBe(5);
1636
-
1637
- scope.aValue = undefined;
1638
- await wait();
1639
- expect(scope.counter).toBe(6);
1640
- expect(newValue).toEqual(undefined);
1641
- });
1642
-
1643
- it("should allow deregistration", async () => {
1644
- scope.obj = [];
1645
- count = 0;
1646
- let deregister = scope.$watch("obj", (newVal) => {
1647
- logs.push(newVal);
1648
- count++;
1649
- });
1650
-
1651
- scope.obj.push("a");
1652
- await wait();
1653
- expect(logs.length).toBe(2);
1654
- expect(count).toEqual(2);
1655
-
1656
- scope.obj.push("a");
1657
- await wait();
1658
- expect(logs.length).toBe(3);
1659
- expect(count).toEqual(3);
1660
-
1661
- deregister();
1662
- scope.obj.push("a");
1663
- await wait();
1664
- expect(logs.length).toBe(3);
1665
- expect(count).toEqual(3);
1666
- });
1667
-
1668
- it("should not trigger change when object in collection changes", async () => {
1669
- scope.$watch("obj", function () {
1670
- count++;
1671
- });
1672
- scope.obj = [{}];
1673
- await wait();
1674
- expect(count).toEqual(2);
1675
-
1676
- scope.obj[0].name = "foo";
1677
- await wait();
1678
- expect(count).toEqual(2);
1679
- });
1680
-
1681
- it("should watch array properties", async () => {
1682
- let counter = 0;
1683
- scope.obj = [];
1684
- scope.$watch("obj", function () {
1685
- counter++;
1686
- });
1687
- await wait();
1688
- expect(counter).toEqual(1);
1689
-
1690
- scope.obj.push("a");
1691
-
1692
- await wait();
1693
- expect(counter).toEqual(2);
1694
-
1695
- scope.obj[0] = "b";
1696
- await wait();
1697
- expect(counter).toEqual(3);
1698
-
1699
- scope.obj.push([]);
1700
- scope.obj.push({});
1701
- expect(scope.obj.length).toBe(3);
1702
- await wait();
1703
- expect(counter).toEqual(5);
1704
-
1705
- scope.obj.shift();
1706
- await wait();
1707
- expect(counter).toEqual(6);
1708
-
1709
- scope.obj[0] = "c";
1710
- await wait();
1711
- expect(counter).toEqual(7);
1712
-
1713
- scope.obj.pop();
1714
- await wait();
1715
- expect(counter).toEqual(8);
1716
- });
1717
-
1718
- it("should watch array-like objects like arrays", async () => {
1719
- let counter = 0;
1720
- scope.$watch("obj", function () {
1721
- counter++;
1722
- });
1723
- scope.obj = document.getElementsByTagName("src");
1724
- await wait();
1725
- expect(counter).toEqual(2);
1726
- });
1727
- });
1728
-
1729
- describe("watching other proxies", () => {
1730
- it("should register a foreign proxies ", async () => {
1731
- let scope1 = createScope();
1732
- scope1.service = createScope({ b: 2 });
1733
- expect(scope1.$handler.foreignProxies.size).toEqual(1);
1734
- });
1735
-
1736
- it("should detect changes on another proxy", async () => {
1737
- let scope1 = createScope();
1738
- let scope2 = createScope({ b: 2 });
1739
- let count = 0;
1740
-
1741
- scope1.service = scope2;
1742
- scope1.$watch("service.b", () => {
1743
- count++;
1744
- });
1745
-
1746
- scope2.$watch("b", () => {
1747
- count++;
1748
- });
1749
-
1750
- scope2.b = 1;
1751
- await wait();
1752
-
1753
- expect(count).toBe(4);
1754
- });
1755
- });
1756
-
1757
- describe("$watch", () => {
1758
- describe("constiable", () => {
1759
- let deregister;
1760
- beforeEach(async () => {
1761
- logs = [];
1762
-
1763
- deregister = scope.$watch("obj", (newVal) => {
1764
- const msg = { newVal };
1765
- logs.push(msg);
1766
- });
1767
-
1768
- await wait();
1769
- logs = [];
1770
- });
1771
-
1772
- describe("object", () => {
1773
- it("should return undefined for old value the first listener call", async () => {
1774
- scope.obj = { a: "b" };
1775
- await wait();
1776
- expect(logs).toEqual([{ newVal: { a: "b" } }]);
1777
- logs = [];
1778
-
1779
- scope.obj.a = "c";
1780
- await wait();
1781
- expect(logs).toEqual([{ newVal: { a: "c" } }]);
1782
- });
1783
-
1784
- it("should trigger when property changes into object", async () => {
1785
- scope.obj = "test";
1786
- await wait();
1787
- expect(logs).toEqual([{ newVal: "test" }]);
1788
-
1789
- logs = [];
1790
- scope.obj = {};
1791
- await wait();
1792
- expect(logs).toEqual([{ newVal: {} }]);
1793
- });
1794
-
1795
- it("should not trigger change when object in collection changes", async () => {
1796
- scope.obj = { name: {} };
1797
-
1798
- await wait();
1799
-
1800
- expect(logs).toEqual([{ newVal: { name: {} } }]);
1801
- logs = [];
1802
-
1803
- scope.obj.name.bar = "foo";
1804
-
1805
- expect(logs).toEqual([]);
1806
- });
1807
-
1808
- it("should watch object properties", async () => {
1809
- scope.obj = {};
1810
-
1811
- await wait();
1812
- expect(logs).toEqual([{ newVal: {} }]);
1813
-
1814
- logs = [];
1815
-
1816
- scope.obj.a = "A";
1817
- await wait();
1818
-
1819
- expect(logs).toEqual([{ newVal: { a: "A" } }]);
1820
-
1821
- logs = [];
1822
- scope.obj.a = "B";
1823
- await wait();
1824
-
1825
- expect(logs).toEqual([{ newVal: { a: "B" } }]);
1826
-
1827
- logs = [];
1828
-
1829
- scope.obj.b = [];
1830
- await wait();
1831
- expect(logs).toEqual([{ newVal: scope.obj }]);
1832
-
1833
- logs = [];
1834
- scope.obj.c = {};
1835
-
1836
- await wait();
1837
- expect(logs).toEqual([{ newVal: scope.obj }]);
1838
- });
1839
-
1840
- it("should not infinitely digest when current value is NaN", async () => {
1841
- scope.obj = { a: NaN };
1842
- await wait();
1843
- expect(() => {}).not.toThrow();
1844
- });
1845
-
1846
- it("should handle objects created using `Object.create(null)`", async () => {
1847
- scope.obj = Object.create(null);
1848
- scope.obj.a = "a";
1849
- scope.obj.b = "b";
1850
-
1851
- await wait();
1852
- expect(logs[0].newVal).toEqual(scope.obj);
1853
-
1854
- delete scope.obj.b;
1855
-
1856
- await wait();
1857
- expect(logs[0].newVal).toEqual(scope.obj);
1858
- });
1859
- });
1860
- });
1861
-
1862
- describe("literal", () => {
1863
- describe("array", () => {
1864
- beforeEach(async () => {
1865
- logs = [];
1866
- scope.$watch("[obj]", (newVal) => {
1867
- const msg = { newVal };
1868
-
1869
- logs.push(msg);
1870
- });
1871
- await wait();
1872
- logs = [];
1873
- });
1874
-
1875
- it("should trigger when item in array changes", async () => {
1876
- // first time should be identical
1877
- scope.obj = "a";
1878
- await wait();
1879
- expect(logs[0].newVal).toEqual(["a"]);
1880
-
1881
- // second time should be different
1882
- logs = [];
1883
- scope.obj = "b";
1884
- await wait();
1885
- expect(logs[0].newVal).toEqual(["b"]);
1886
- });
1887
-
1888
- it("should trigger when property changes into array", async () => {
1889
- scope.obj = "test";
1890
- await wait();
1891
-
1892
- expect(logs).toEqual([{ newVal: ["test"] }]);
1893
-
1894
- logs = [];
1895
- scope.obj = [];
1896
- await wait();
1897
- expect(logs).toEqual([{ newVal: [[]] }]);
1898
-
1899
- logs = [];
1900
- scope.obj = {};
1901
- await wait();
1902
- expect(logs).toEqual([{ newVal: [{}] }]);
1903
-
1904
- logs = [];
1905
- scope.obj = [];
1906
- await wait();
1907
- expect(logs).toEqual([{ newVal: [[]] }]);
1908
-
1909
- logs = [];
1910
-
1911
- scope.obj = undefined;
1912
- await wait();
1913
- expect(logs).toEqual([{ newVal: [undefined] }]);
1914
- });
1915
-
1916
- it("should not trigger change when object in collection changes", async () => {
1917
- scope.obj = {};
1918
- await wait();
1919
- expect(logs).toEqual([{ newVal: [{}] }]);
1920
-
1921
- logs = [];
1922
- scope.obj.name = "foo";
1923
- await wait();
1924
- expect(logs).toEqual([{ newVal: [{ name: "foo" }] }]);
1925
- });
1926
-
1927
- it("should not infinitely digest when current value is NaN", async () => {
1928
- scope.obj = NaN;
1929
- await wait();
1930
- expect(() => {}).not.toThrow();
1931
- });
1932
- });
1933
-
1934
- describe("object", () => {
1935
- beforeEach(() => {
1936
- logs = [];
1937
- scope.$watch("{a: obj}", (newVal) => {
1938
- const msg = { newVal };
1939
-
1940
- logs.push(msg);
1941
- });
1942
- });
1943
-
1944
- it("should trigger when property changes into object", async () => {
1945
- logs = [];
1946
- scope.obj = {};
1947
- await wait();
1948
- expect(logs[0]).toEqual({ newVal: { a: {} } });
1949
- });
1950
-
1951
- it("should trigger change when deeply nested property in object changes", async () => {
1952
- scope.obj = { name: "foo" };
1953
- await wait();
1954
- expect(logs[0]).toEqual({
1955
- newVal: { a: { name: "foo" } },
1956
- });
1957
-
1958
- logs = [];
1959
- scope.obj.name = "bar";
1960
- await wait();
1961
- expect(logs[0]).toEqual({
1962
- newVal: { a: { name: "bar" } },
1963
- });
1964
- });
1965
-
1966
- it("should not infinitely digest when current value is NaN", async () => {
1967
- scope.obj = NaN;
1968
- await wait();
1969
- expect(() => {}).not.toThrow();
1970
- });
1971
- });
1972
-
1973
- describe("object computed property", () => {
1974
- beforeEach(async () => {
1975
- logs = [];
1976
- scope.$watch("{[key]: obj}", (newVal) => {
1977
- const msg = { newVal };
1978
-
1979
- logs.push(msg);
1980
- });
1981
-
1982
- await wait();
1983
- logs = [];
1984
- });
1985
-
1986
- it("should not trigger when key absent", async () => {
1987
- scope.obj = "test";
1988
- await wait();
1989
- expect(logs).toEqual([]);
1990
- });
1991
-
1992
- it("should trigger when key changes", async () => {
1993
- scope.key = "a";
1994
- scope.obj = "test";
1995
- await wait();
1996
- expect(logs).toEqual([{ newVal: { a: "test" } }]);
1997
-
1998
- logs = [];
1999
- scope.key = "b";
2000
- await wait();
2001
- expect(logs).toEqual([{ newVal: { b: "test" } }]);
2002
-
2003
- logs = [];
2004
- scope.key = true;
2005
- await wait();
2006
- expect(logs).toEqual([{ newVal: { true: "test" } }]);
2007
- });
2008
-
2009
- it("should not trigger change when object in collection changes", async () => {
2010
- scope.key = "a";
2011
- scope.obj = { name: "foo" };
2012
- await wait();
2013
- expect(logs).toEqual([
2014
- {
2015
- newVal: { a: { name: "foo" } },
2016
- },
2017
- ]);
2018
- logs = [];
2019
-
2020
- scope.obj.name = "bar";
2021
- await wait();
2022
- expect(logs).toEqual([]);
2023
- });
2024
-
2025
- it("should not infinitely digest when key value is NaN", () => {
2026
- scope.key = NaN;
2027
- scope.obj = NaN;
2028
- expect(() => {}).not.toThrow();
2029
- });
2030
- });
2031
- });
2032
- });
2033
-
2034
- logs = [];
2035
- function setupWatches(scope, log) {
2036
- scope.$watch(() => {
2037
- logs.push("w1");
2038
- return scope.w1;
2039
- }, log("w1action"));
2040
- scope.$watch(() => {
2041
- logs.push("w2");
2042
- return scope.w2;
2043
- }, log("w2action"));
2044
- scope.$watch(() => {
2045
- logs.push("w3");
2046
- return scope.w3;
2047
- }, log("w3action"));
2048
- console.error(logs.length);
2049
- logs = [];
2050
- }
2051
- });
2052
-
2053
- describe("$eval", () => {
2054
- it("should eval an expression and modify the scope", () => {
2055
- expect(scope.$eval("a=1")).toEqual(1);
2056
- expect(scope.a).toEqual(1);
2057
-
2058
- scope.$eval((self) => {
2059
- self.$proxy.b = 2;
2060
- });
2061
- expect(scope.b).toEqual(2);
2062
- });
2063
-
2064
- it("executes $eval'ed function and returns result", function () {
2065
- scope.aValue = 42;
2066
- const result = scope.$eval(function (scope) {
2067
- return scope.$proxy.aValue;
2068
- });
2069
- expect(result).toBe(42);
2070
- });
2071
-
2072
- it("passes the second $eval argument straight through", function () {
2073
- scope.aValue = 42;
2074
- const result = scope.$eval(function (scope, arg) {
2075
- return scope.$proxy.aValue + arg;
2076
- }, 2);
2077
- expect(result).toBe(44);
2078
- });
2079
-
2080
- it("should allow passing locals to the expression", () => {
2081
- expect(scope.$eval("a+1", { a: 2 })).toBe(3);
2082
-
2083
- scope.$eval(
2084
- (scope, locals) => {
2085
- scope.$proxy.c = locals.b + 4;
2086
- },
2087
- { b: 3 },
2088
- );
2089
- expect(scope.c).toBe(7);
2090
- });
2091
- });
2092
-
2093
- describe("$apply", () => {
2094
- beforeEach(() => (logs = []));
2095
-
2096
- it("should eval an expression, modify the scope and trigger the watches", async () => {
2097
- let counter = 0;
2098
- scope.$watch("a", () => {
2099
- counter++;
2100
- });
2101
- await wait();
2102
- expect(counter).toEqual(1);
2103
-
2104
- scope.$apply("a=1");
2105
- await wait();
2106
- expect(counter).toEqual(2);
2107
- });
2108
-
2109
- it("should update the scope and add values", async () => {
2110
- scope.$apply("a=1");
2111
- await wait();
2112
- expect(scope.a).toEqual(1);
2113
- });
2114
-
2115
- it("should update the scope and remove values", async () => {
2116
- scope.a = 2;
2117
- scope.$apply("a=null");
2118
- await wait();
2119
- expect(scope.a).toBeNull();
2120
- });
2121
-
2122
- it("should update the scope and modify objects", async () => {
2123
- scope.$apply("a={b: 2}");
2124
- await wait();
2125
- expect(scope.a.b).toEqual(2);
2126
-
2127
- scope.$apply("a.b = 3");
2128
- await wait();
2129
- expect(scope.a.b).toEqual(3);
2130
-
2131
- scope.$apply("a={c: 2}");
2132
- await wait();
2133
- expect(scope.a.c).toEqual(2);
2134
- expect(scope.a.b).toBeUndefined();
2135
- });
2136
-
2137
- it("should update arrays", async () => {
2138
- scope.a = [];
2139
- scope.$watch("a", () => count++);
2140
-
2141
- scope.$apply("a.push(1)");
2142
-
2143
- await wait();
2144
- expect(scope.a).toEqual([1]);
2145
- expect(count).toEqual(2);
2146
-
2147
- scope.$apply("a.push(2)");
2148
-
2149
- await wait();
2150
- expect(scope.a).toEqual([1, 2]);
2151
- expect(count).toEqual(3);
2152
- });
2153
-
2154
- it("executes $apply'ed function and starts the digest", async () => {
2155
- scope.aValue = "someValue";
2156
- scope.counter = 0;
2157
- scope.$watch("aValue", () => scope.counter++);
2158
- await wait();
2159
- expect(scope.counter).toBe(1);
2160
-
2161
- scope.$apply(function (scope) {
2162
- scope.aValue = "someOtherValue";
2163
- });
2164
- await wait();
2165
- expect(scope.counter).toBe(2);
2166
- });
2167
-
2168
- it("should apply expression with full lifecycle", async () => {
2169
- let log = "";
2170
- const child = scope.$new();
2171
- scope.$watch("a", (a) => {
2172
- log += "1";
2173
- });
2174
-
2175
- child.$apply("a = 0");
2176
- await wait();
2177
- expect(log).toEqual("11");
2178
- });
2179
-
2180
- it("should catch exceptions", async () => {
2181
- let log = "";
2182
- const child = scope.$new();
2183
- scope.$watch("a", (a) => {
2184
- log += "1";
2185
- });
2186
- scope.a = 0;
2187
- await wait();
2188
- child.$apply(() => {
2189
- throw new Error("MyError");
2190
- });
2191
- await wait();
2192
- expect(log).toEqual("11");
2193
- expect(logs[0].message).toEqual("MyError");
2194
- });
2195
- });
2196
-
2197
- // describe("$applyAsync", () => {
2198
- // beforeEach(() => (logs = []));
2199
- // it("should evaluate in the context of specific $scope", () => {
2200
- // const scope = scope.$new();
2201
- // let id = scope.$applyAsync('x = "CODE ORANGE"');
2202
-
2203
- // $browser.cancel(id);
2204
- // setTimeout(() => {
2205
- // expect(scope.x).toBe("CODE ORANGE");
2206
- // expect(scope.x).toBeUndefined();
2207
- // });
2208
-
2209
- // expect(scope.x).toBeUndefined();
2210
- // });
2211
-
2212
- // it("should evaluate queued expressions in order", () => {
2213
- // scope.x = [];
2214
- // let id1 = scope.$applyAsync('x.push("expr1")');
2215
- // let id2 = scope.$applyAsync('x.push("expr2")');
2216
-
2217
- // $browser.cancel(id1);
2218
- // $browser.cancel(id2);
2219
- // setTimeout(() => {
2220
- // expect(scope.x).toEqual(["expr1", "expr2"]);
2221
- // });
2222
- // expect(scope.x).toEqual([]);
2223
- // });
2224
-
2225
- // it("should evaluate subsequently queued items in same turn", () => {
2226
- // scope.x = [];
2227
- // let id = scope.$applyAsync(() => {
2228
- // scope.x.push("expr1");
2229
- // scope.$applyAsync('x.push("expr2")');
2230
- // expect($browser.deferredFns.length).toBe(0);
2231
- // });
2232
-
2233
- // $browser.cancel(id);
2234
- // setTimeout(() => {
2235
- // expect(scope.x).toEqual(["expr1", "expr2"]);
2236
- // });
2237
- // expect(scope.x).toEqual([]);
2238
- // });
2239
-
2240
- // it("should pass thrown exceptions to $exceptionHandler", () => {
2241
- // let id = scope.$applyAsync(() => {
2242
- // throw "OOPS";
2243
- // });
2244
-
2245
- // $browser.cancel(id);
2246
- // expect(logs).toEqual([]);
2247
- // setTimeout(() => expect(logs[0]).toEqual("OOPS"));
2248
- // });
2249
-
2250
- // it("should evaluate subsequent expressions after an exception is thrown", () => {
2251
- // let id = scope.$applyAsync(() => {
2252
- // throw "OOPS";
2253
- // });
2254
- // let id2 = scope.$applyAsync('x = "All good!"');
2255
-
2256
- // $browser.cancel(id);
2257
- // $browser.cancel(id2);
2258
- // setTimeout(() => expect(scope.x).toBe("All good!"));
2259
- // expect(scope.x).toBeUndefined();
2260
- // });
2261
-
2262
- // it("should be cancelled if a scope digest occurs before the next tick", () => {
2263
- // const cancel = spyOn($browser, "cancel").and.callThrough();
2264
- // const expression = jasmine.createSpy("expr");
2265
-
2266
- // scope.$applyAsync(expression);
2267
-
2268
- // expect(expression).toHaveBeenCalled();
2269
- // expect(cancel).toHaveBeenCalled();
2270
- // expression.calls.reset();
2271
- // cancel.calls.reset();
2272
-
2273
- // // assert that another digest won't call the function again
2274
-
2275
- // expect(expression).not.toHaveBeenCalled();
2276
- // expect(cancel).not.toHaveBeenCalled();
2277
- // });
2278
- // });
2279
-
2280
- describe("$postUpdate", () => {
2281
- beforeEach(() => (logs = []));
2282
- it("should process callbacks as a queue (FIFO) when the scope is digested", async () => {
2283
- let signature = "";
2284
-
2285
- scope.$postUpdate(() => {
2286
- signature += "A";
2287
- scope.$postUpdate(() => {
2288
- signature += "D";
2289
- });
2290
- });
2291
-
2292
- scope.$postUpdate(() => {
2293
- signature += "B";
2294
- });
2295
-
2296
- scope.$postUpdate(() => {
2297
- signature += "C";
2298
- });
2299
-
2300
- expect(signature).toBe("");
2301
- expect($postUpdateQueue.length).toBe(3);
2302
-
2303
- scope.$watch("a", () => {});
2304
- scope.a = 1;
2305
-
2306
- await wait();
2307
-
2308
- expect(signature).toBe("ABCD");
2309
- });
2310
-
2311
- it("should support $apply calls nested in $postUpdate callbacks", async () => {
2312
- let signature = "";
2313
-
2314
- scope.$postUpdate(() => {
2315
- signature += "A";
2316
- });
2317
-
2318
- scope.$postUpdate(() => {
2319
- signature += "B";
2320
- scope.$postUpdate(() => {
2321
- signature += "D";
2322
- });
2323
- scope.$apply("a = 2");
2324
- });
2325
-
2326
- scope.$postUpdate(() => {
2327
- signature += "C";
2328
- });
2329
- expect(signature).toBe("");
2330
-
2331
- scope.$watch("a", () => {});
2332
- scope.a = 1;
2333
- await wait();
2334
-
2335
- expect(signature).toBe("ABCD");
2336
- });
2337
-
2338
- it("should run a $postUpdate call on all child scopes when a parent scope is digested", async () => {
2339
- const parent = scope.$new();
2340
- const child = parent.$new();
2341
- let count = 0;
2342
-
2343
- scope.$postUpdate(() => {
2344
- count++;
2345
- });
2346
-
2347
- parent.$postUpdate(() => {
2348
- count++;
2349
- });
2350
-
2351
- child.$postUpdate(() => {
2352
- count++;
2353
- });
2354
-
2355
- expect(count).toBe(0);
2356
-
2357
- scope.$watch("a", () => {});
2358
- scope.a = 1;
2359
- await wait();
2360
-
2361
- expect(count).toBe(3);
2362
- });
2363
-
2364
- it("should run a $postUpdate call even if the child scope is isolated", async () => {
2365
- const parent = scope.$new();
2366
- const child = parent.$newIsolate();
2367
- let signature = "";
2368
-
2369
- parent.$postUpdate(() => {
2370
- signature += "A";
2371
- });
2372
-
2373
- child.$postUpdate(() => {
2374
- signature += "B";
2375
- });
2376
-
2377
- expect(signature).toBe("");
2378
- scope.$watch("a", () => {});
2379
- scope.a = 1;
2380
- await wait();
2381
- expect(signature).toBe("AB");
2382
- });
2383
- });
2384
-
2385
- describe("events", () => {
2386
- describe("$on", () => {
2387
- it("should add listener to list of listerner", () => {
2388
- const child = scope.$new();
2389
- function eventFn() {}
2390
- child.$on("abc", eventFn);
2391
- expect(child.$handler.$$listeners.get("abc").length).toEqual(1);
2392
-
2393
- child.$on("abc", eventFn);
2394
- expect(child.$handler.$$listeners.get("abc").length).toEqual(2);
2395
- });
2396
-
2397
- it("should return a deregistration function", () => {
2398
- const child = scope.$new();
2399
- function eventFn() {}
2400
- let res = child.$on("abc", eventFn);
2401
- expect(isDefined(res)).toBeDefined();
2402
- });
2403
-
2404
- it("should return a deregistration function that removes a listener", () => {
2405
- const child = scope.$new();
2406
- function eventFn() {}
2407
- let res = child.$on("abc", eventFn);
2408
- expect(isDefined(res)).toBeDefined();
2409
- expect(child.$handler.$$listeners.get("abc").length).toEqual(1);
2410
- let res2 = child.$on("abc", eventFn);
2411
- expect(child.$handler.$$listeners.get("abc").length).toEqual(2);
2412
- res();
2413
- expect(child.$handler.$$listeners.get("abc").length).toEqual(1);
2414
- res2();
2415
- expect(child.$handler.$$listeners.has("abc")).toBeFalse();
2416
- });
2417
-
2418
- it("should add listener for both $emit and $broadcast events", () => {
2419
- logs = "";
2420
- const child = scope.$new();
2421
- function eventFn() {
2422
- logs += "X";
2423
- }
2424
-
2425
- child.$on("abc", eventFn);
2426
- expect(logs).toEqual("");
2427
-
2428
- child.$emit("abc");
2429
- expect(logs).toEqual("X");
2430
-
2431
- child.$broadcast("abc");
2432
- expect(logs).toEqual("XX");
2433
- });
2434
-
2435
- describe("deregistration", () => {
2436
- it("should return a function that deregisters the listener", () => {
2437
- let log = "";
2438
- const child = scope.$new();
2439
- let listenerRemove;
2440
-
2441
- function eventFn() {
2442
- log += "X";
2443
- }
2444
-
2445
- listenerRemove = child.$on("abc", eventFn);
2446
- expect(log).toEqual("");
2447
- expect(listenerRemove).toBeDefined();
2448
-
2449
- child.$emit("abc");
2450
- child.$broadcast("abc");
2451
- expect(log).toEqual("XX");
2452
-
2453
- expect(child.$handler.$$listeners.get("abc").length).toBe(1);
2454
-
2455
- log = "";
2456
- listenerRemove();
2457
- child.$emit("abc");
2458
- child.$broadcast("abc");
2459
- expect(log).toEqual("");
2460
- expect(scope.$handler.$$listeners.get("abc")).toBeUndefined();
2461
- });
2462
-
2463
- it("should deallocate the listener array entry", () => {
2464
- const remove1 = scope.$on("abc", () => {});
2465
- scope.$on("abc", () => {});
2466
-
2467
- expect(scope.$handler.$$listeners.get("abc").length).toBe(2);
2468
-
2469
- remove1();
2470
-
2471
- expect(scope.$handler.$$listeners.get("abc").length).toBe(1);
2472
- });
2473
-
2474
- it("should call next listener after removing the current listener via its own handler", () => {
2475
- const listener1 = jasmine.createSpy("listener1").and.callFake(() => {
2476
- remove1();
2477
- });
2478
- let remove1 = scope.$on("abc", listener1);
2479
-
2480
- const listener2 = jasmine.createSpy("listener2");
2481
- const remove2 = scope.$on("abc", listener2);
2482
-
2483
- const listener3 = jasmine.createSpy("listener3");
2484
- const remove3 = scope.$on("abc", listener3);
2485
-
2486
- scope.$broadcast("abc");
2487
- expect(listener1).toHaveBeenCalled();
2488
- expect(listener2).toHaveBeenCalled();
2489
- expect(listener3).toHaveBeenCalled();
2490
-
2491
- listener1.calls.reset();
2492
- listener2.calls.reset();
2493
- listener3.calls.reset();
2494
-
2495
- scope.$broadcast("abc");
2496
- expect(listener1).not.toHaveBeenCalled();
2497
- expect(listener2).toHaveBeenCalled();
2498
- expect(listener3).toHaveBeenCalled();
2499
- });
2500
-
2501
- it("should call all subsequent listeners when a previous listener is removed via a handler", () => {
2502
- const listener1 = jasmine.createSpy();
2503
- const remove1 = scope.$on("abc", listener1);
2504
-
2505
- const listener2 = jasmine.createSpy().and.callFake(remove1);
2506
- const remove2 = scope.$on("abc", listener2);
2507
-
2508
- const listener3 = jasmine.createSpy();
2509
- const remove3 = scope.$on("abc", listener3);
2510
-
2511
- scope.$broadcast("abc");
2512
- expect(listener1).toHaveBeenCalled();
2513
- expect(listener2).toHaveBeenCalled();
2514
- expect(listener3).toHaveBeenCalled();
2515
-
2516
- listener1.calls.reset();
2517
- listener2.calls.reset();
2518
- listener3.calls.reset();
2519
-
2520
- scope.$broadcast("abc");
2521
- expect(listener1).not.toHaveBeenCalled();
2522
- expect(listener2).toHaveBeenCalled();
2523
- expect(listener3).toHaveBeenCalled();
2524
- });
2525
-
2526
- it("should not call listener when removed by previous", () => {
2527
- const listener1 = jasmine.createSpy("listener1");
2528
- const remove1 = scope.$on("abc", listener1);
2529
-
2530
- const listener2 = jasmine.createSpy("listener2").and.callFake(() => {
2531
- remove3();
2532
- });
2533
- const remove2 = scope.$on("abc", listener2);
2534
-
2535
- const listener3 = jasmine.createSpy("listener3");
2536
- let remove3 = scope.$on("abc", listener3);
2537
-
2538
- const listener4 = jasmine.createSpy("listener4");
2539
- const remove4 = scope.$on("abc", listener4);
2540
-
2541
- scope.$broadcast("abc");
2542
- expect(listener1).toHaveBeenCalled();
2543
- expect(listener2).toHaveBeenCalled();
2544
- expect(listener3).not.toHaveBeenCalled();
2545
- expect(listener4).toHaveBeenCalled();
2546
-
2547
- listener1.calls.reset();
2548
- listener2.calls.reset();
2549
- listener3.calls.reset();
2550
- listener4.calls.reset();
2551
-
2552
- scope.$broadcast("abc");
2553
- expect(listener1).toHaveBeenCalled();
2554
- expect(listener2).toHaveBeenCalled();
2555
- expect(listener3).not.toHaveBeenCalled();
2556
- expect(listener4).toHaveBeenCalled();
2557
- });
2558
- });
2559
- });
2560
-
2561
- describe("$emit", () => {
2562
- let log;
2563
- let child;
2564
- let grandChild;
2565
- let greatGrandChild;
2566
-
2567
- function logger(event) {
2568
- log += `${event.currentScope.$id}>`;
2569
- }
2570
-
2571
- beforeEach(() => {
2572
- log = "";
2573
- logs = [];
2574
- child = scope.$new();
2575
- grandChild = child.$new();
2576
- greatGrandChild = grandChild.$new();
2577
-
2578
- scope.$id = 0;
2579
- child.$id = 1;
2580
- grandChild.$id = 2;
2581
- greatGrandChild.$id = 3;
2582
-
2583
- scope.$on("myEvent", logger);
2584
- child.$on("myEvent", logger);
2585
- grandChild.$on("myEvent", logger);
2586
- greatGrandChild.$on("myEvent", logger);
2587
- });
2588
-
2589
- it("should do nothing on empty listener", () => {
2590
- logs = "";
2591
- const child = scope.$new();
2592
-
2593
- function eventFn() {
2594
- logs += "X";
2595
- }
2596
-
2597
- child.$on("abc", eventFn);
2598
- expect(logs).toEqual("");
2599
-
2600
- child.$emit("none");
2601
- expect(logs).toEqual("");
2602
- });
2603
-
2604
- it("should bubble event up to the root scope", () => {
2605
- grandChild.$emit("myEvent");
2606
- expect(log).toEqual("2>1>0>");
2607
- });
2608
-
2609
- it("should allow all events on the same scope to run even if stopPropagation is called", () => {
2610
- child.$on("myEvent", logger);
2611
- grandChild.$on("myEvent", (e) => {
2612
- e.stopPropagation();
2613
- });
2614
- grandChild.$on("myEvent", logger);
2615
- grandChild.$on("myEvent", logger);
2616
- grandChild.$emit("myEvent");
2617
- expect(log).toEqual("2>2>2>");
2618
- });
2619
-
2620
- it("should dispatch exceptions to the $exceptionHandler", () => {
2621
- child.$on("myEvent", () => {
2622
- throw "bubbleException";
2623
- });
2624
- grandChild.$emit("myEvent");
2625
- expect(log).toEqual("2>1>0>");
2626
- expect(logs).toEqual(["bubbleException"]);
2627
- });
2628
-
2629
- it("should allow stopping event propagation", () => {
2630
- child.$on("myEvent", (event) => {
2631
- event.stopPropagation();
2632
- });
2633
- grandChild.$emit("myEvent");
2634
- expect(log).toEqual("2>1>");
2635
- });
2636
-
2637
- it("should forward method arguments", () => {
2638
- child.$on("abc", (event, arg1, arg2) => {
2639
- expect(event.name).toBe("abc");
2640
- expect(arg1).toBe("arg1");
2641
- expect(arg2).toBe("arg2");
2642
- });
2643
- child.$emit("abc", "arg1", "arg2");
2644
- });
2645
-
2646
- it("should allow removing event listener inside a listener on $emit", () => {
2647
- const spy1 = jasmine.createSpy("1st listener");
2648
- const spy2 = jasmine.createSpy("2nd listener");
2649
- const spy3 = jasmine.createSpy("3rd listener");
2650
-
2651
- const remove1 = child.$on("evt", spy1);
2652
- const remove2 = child.$on("evt", spy2);
2653
- const remove3 = child.$on("evt", spy3);
2654
-
2655
- spy1.and.callFake(remove1);
2656
-
2657
- expect(child.$handler.$$listeners.get("evt").length).toBe(3);
2658
-
2659
- // should call all listeners and remove 1st
2660
- child.$emit("evt");
2661
- expect(spy1).toHaveBeenCalled();
2662
- expect(spy2).toHaveBeenCalled();
2663
- expect(spy3).toHaveBeenCalled();
2664
- expect(child.$handler.$$listeners.get("evt").length).toBe(2);
2665
-
2666
- spy1.calls.reset();
2667
- spy2.calls.reset();
2668
- spy3.calls.reset();
2669
-
2670
- // // should call only 2nd because 1st was already removed and 2nd removes 3rd
2671
- spy2.and.callFake(remove3);
2672
- child.$emit("evt");
2673
- expect(spy1).not.toHaveBeenCalled();
2674
- expect(spy2).toHaveBeenCalled();
2675
- expect(spy3).not.toHaveBeenCalled();
2676
- expect(child.$handler.$$listeners.get("evt").length).toBe(1);
2677
- });
2678
-
2679
- it("should allow removing event listener inside a listener on $broadcast", () => {
2680
- const spy1 = jasmine.createSpy("1st listener");
2681
- const spy2 = jasmine.createSpy("2nd listener");
2682
- const spy3 = jasmine.createSpy("3rd listener");
2683
-
2684
- const remove1 = child.$on("evt", spy1);
2685
- const remove2 = child.$on("evt", spy2);
2686
- const remove3 = child.$on("evt", spy3);
2687
-
2688
- spy1.and.callFake(remove1);
2689
-
2690
- expect(child.$handler.$$listeners.get("evt").length).toBe(3);
2691
-
2692
- // should call all listeners and remove 1st
2693
- child.$broadcast("evt");
2694
- expect(spy1).toHaveBeenCalled();
2695
- expect(spy2).toHaveBeenCalled();
2696
- expect(spy3).toHaveBeenCalled();
2697
- expect(child.$handler.$$listeners.get("evt").length).toBe(2);
2698
-
2699
- spy1.calls.reset();
2700
- spy2.calls.reset();
2701
- spy3.calls.reset();
2702
-
2703
- // should call only 2nd because 1st was already removed and 2nd removes 3rd
2704
- spy2.and.callFake(remove3);
2705
- child.$broadcast("evt");
2706
- expect(spy1).not.toHaveBeenCalled();
2707
- expect(spy2).toHaveBeenCalled();
2708
- expect(spy3).not.toHaveBeenCalled();
2709
- expect(child.$handler.$$listeners.get("evt").length).toBe(1);
2710
- });
2711
-
2712
- describe("event object", () => {
2713
- it("should have methods/properties", () => {
2714
- let eventFired = false;
2715
-
2716
- child.$on("myEvent", (e) => {
2717
- expect(e.targetScope).toBe(grandChild.$handler.$target);
2718
- expect(e.currentScope).toBe(child.$handler.$target);
2719
- expect(e.name).toBe("myEvent");
2720
- eventFired = true;
2721
- });
2722
- grandChild.$emit("myEvent");
2723
- expect(eventFired).toBe(true);
2724
- });
2725
-
2726
- it("should have its `currentScope` property set to null after emit", () => {
2727
- let event;
2728
-
2729
- child.$on("myEvent", (e) => {
2730
- event = e;
2731
- });
2732
- grandChild.$emit("myEvent");
2733
-
2734
- expect(event.currentScope).toBe(null);
2735
- expect(event.targetScope).toBe(grandChild.$target);
2736
- expect(event.name).toBe("myEvent");
2737
- });
2738
-
2739
- it("should have preventDefault method and defaultPrevented property", () => {
2740
- let event = grandChild.$emit("myEvent");
2741
- expect(event.defaultPrevented).toBe(false);
2742
-
2743
- child.$on("myEvent", (event) => {
2744
- event.preventDefault();
2745
- });
2746
- event = grandChild.$emit("myEvent");
2747
- expect(event.defaultPrevented).toBe(true);
2748
- expect(event.currentScope).toBe(null);
2749
- });
2750
- });
2751
- });
2752
-
2753
- describe("$broadcast", () => {
2754
- describe("event propagation", () => {
2755
- let log;
2756
- let child1;
2757
- let child2;
2758
- let child3;
2759
- let grandChild11;
2760
- let grandChild21;
2761
- let grandChild22;
2762
- let grandChild23;
2763
- let greatGrandChild211;
2764
-
2765
- function logger(event) {
2766
- log += `${event.currentScope.$id}>`;
2767
- }
2768
-
2769
- beforeEach(() => {
2770
- log = "";
2771
- child1 = scope.$new();
2772
- child2 = scope.$new();
2773
- child3 = scope.$new();
2774
- grandChild11 = child1.$new();
2775
- grandChild21 = child2.$new();
2776
- grandChild22 = child2.$new();
2777
- grandChild23 = child2.$new();
2778
- greatGrandChild211 = grandChild21.$new();
2779
-
2780
- scope.$id = 0;
2781
- child1.$id = 1;
2782
- child2.$id = 2;
2783
- child3.$id = 3;
2784
- grandChild11.$id = 11;
2785
- grandChild21.$id = 21;
2786
- grandChild22.$id = 22;
2787
- grandChild23.$id = 23;
2788
- greatGrandChild211.$id = 211;
2789
-
2790
- scope.$on("myEvent", logger);
2791
- child1.$on("myEvent", logger);
2792
- child2.$on("myEvent", logger);
2793
- child3.$on("myEvent", logger);
2794
- grandChild11.$on("myEvent", logger);
2795
- grandChild21.$on("myEvent", logger);
2796
- grandChild22.$on("myEvent", logger);
2797
- grandChild23.$on("myEvent", logger);
2798
- greatGrandChild211.$on("myEvent", logger);
2799
-
2800
- // R
2801
- // / | \
2802
- // 1 2 3
2803
- // / / | \
2804
- // 11 21 22 23
2805
- // |
2806
- // 211
2807
- });
2808
-
2809
- it("should broadcast an event from the root scope", () => {
2810
- scope.$broadcast("myEvent");
2811
- expect(log).toBe("0>1>11>2>21>211>22>23>3>");
2812
- });
2813
-
2814
- it("should broadcast an event from a child scope", () => {
2815
- child2.$broadcast("myEvent");
2816
- expect(log).toBe("2>21>211>22>23>");
2817
- });
2818
-
2819
- it("should broadcast an event from a leaf scope with a sibling", () => {
2820
- grandChild22.$broadcast("myEvent");
2821
- expect(log).toBe("22>");
2822
- });
2823
-
2824
- it("should broadcast an event from a leaf scope without a sibling", () => {
2825
- grandChild23.$broadcast("myEvent");
2826
- expect(log).toBe("23>");
2827
- });
2828
-
2829
- it("should not not fire any listeners for other events", () => {
2830
- scope.$broadcast("fooEvent");
2831
- expect(log).toBe("");
2832
- });
2833
-
2834
- it("should return event object", () => {
2835
- const result = child1.$broadcast("some");
2836
-
2837
- expect(result).toBeDefined();
2838
- expect(result.name).toBe("some");
2839
- expect(result.targetScope).toBe(child1.$target);
2840
- });
2841
- });
2842
-
2843
- describe("listener", () => {
2844
- it("should receive event object", () => {
2845
- const child = scope.$new();
2846
- let eventFired = false;
2847
-
2848
- child.$on("fooEvent", (event) => {
2849
- eventFired = true;
2850
- expect(event.name).toBe("fooEvent");
2851
- expect(event.targetScope).toBe(scope.$target);
2852
- expect(event.currentScope).toBe(child.$target);
2853
- });
2854
- scope.$broadcast("fooEvent");
2855
-
2856
- expect(eventFired).toBe(true);
2857
- });
2858
-
2859
- it("should have the event's `currentScope` property set to null after broadcast", () => {
2860
- const child = scope.$new();
2861
- let event;
2862
-
2863
- child.$on("fooEvent", (e) => {
2864
- event = e;
2865
- });
2866
- scope.$broadcast("fooEvent");
2867
-
2868
- expect(event.name).toBe("fooEvent");
2869
- expect(event.targetScope).toBe(scope.$target);
2870
- expect(event.currentScope).toBe(null);
2871
- });
2872
-
2873
- it("should support passing messages as constargs", () => {
2874
- const child = scope.$new();
2875
- let args;
2876
-
2877
- child.$on("fooEvent", function () {
2878
- args = arguments;
2879
- });
2880
- scope.$broadcast("fooEvent", "do", "re", "me", "fa");
2881
-
2882
- expect(args.length).toBe(5);
2883
- expect(sliceArgs(args, 1)).toEqual(["do", "re", "me", "fa"]);
2884
- });
2885
- });
2886
- });
2887
-
2888
- it("should allow recursive $emit/$broadcast", () => {
2889
- let callCount = 0;
2890
- scope.$on("evt", ($event, arg0) => {
2891
- callCount++;
2892
- if (arg0 !== 1234) {
2893
- scope.$emit("evt", 1234);
2894
- scope.$broadcast("evt", 1234);
2895
- }
2896
- });
2897
-
2898
- scope.$emit("evt");
2899
- scope.$broadcast("evt");
2900
- expect(callCount).toBe(6);
2901
- });
2902
-
2903
- it("should allow recursive $emit/$broadcast between parent/child", () => {
2904
- const child = scope.$new();
2905
- let calls = "";
2906
-
2907
- scope.$on("evt", ($event, arg0) => {
2908
- calls += "r"; // For "root".
2909
- if (arg0 === "fromChild") {
2910
- scope.$broadcast("evt", "fromRoot2");
2911
- }
2912
- });
2913
-
2914
- child.$on("evt", ($event, arg0) => {
2915
- calls += "c"; // For "child".
2916
- if (arg0 === "fromRoot1") {
2917
- child.$emit("evt", "fromChild");
2918
- }
2919
- });
2920
-
2921
- scope.$broadcast("evt", "fromRoot1");
2922
- expect(calls).toBe("rccrrc");
2923
- });
2924
- });
2925
-
2926
- describe("$destroy", () => {
2927
- it("should clean up all listeners for root", () => {
2928
- const scope = createScope();
2929
- scope.$on("test", () => {});
2930
- expect(scope.$handler.$$listeners.size).toEqual(1);
2931
-
2932
- scope.$destroy();
2933
- expect(scope.$handler.$$listeners.size).toEqual(0);
2934
- });
2935
-
2936
- it("should clean up all watchers for root", () => {
2937
- const scope = createScope();
2938
- scope.$watch("a", () => {});
2939
- expect(scope.$handler.watchers.size).toEqual(1);
2940
-
2941
- scope.$destroy();
2942
- expect(scope.$handler.watchers.size).toEqual(0);
2943
- });
2944
-
2945
- it("should remove children from parent scopes", async () => {
2946
- const scope = createScope();
2947
- const child = scope.$new();
2948
- expect(scope.$children.length).toEqual(1);
2949
- child.$destroy();
2950
- expect(scope.$children.length).toEqual(0);
2951
- });
2952
-
2953
- it("should clean up all watchers for child", async () => {
2954
- const scope = createScope();
2955
-
2956
- scope.$watch("test", () => {});
2957
- const child = scope.$new();
2958
- child.$watch("test", () => {});
2959
-
2960
- expect(scope.$handler.watchers.size).toEqual(1);
2961
- expect(scope.$handler.watchers.get("test").length).toEqual(2);
2962
- expect(child.$handler.watchers.size).toEqual(1);
2963
- expect(child.$handler.watchers.get("test").length).toEqual(2);
2964
-
2965
- child.$destroy();
2966
- expect(scope.$handler.watchers.get("test").length).toEqual(1);
2967
- });
2968
-
2969
- // it("should clean up all watchers for child", () => {
2970
- // const scope = createScope();
2971
- // scope.$watch("a", () => {});
2972
- // expect(scope.$handler.watchers.size).toEqual(1);
2973
- //
2974
- // scope.$destroy();
2975
- // expect(scope.$handler.watchers.size).toEqual(0);
2976
- // })
2977
- });
2978
-
2979
- describe("doc examples", () => {
2980
- it("should properly fire off watch listeners upon scope changes", async () => {
2981
- // <docs tag="docs1">
2982
- const $scope = scope.$new();
2983
- $scope.salutation = "Hello";
2984
- $scope.name = "World";
2985
- await wait();
2986
- expect($scope.greeting).toEqual(undefined);
2987
-
2988
- $scope.$watch("name", () => {
2989
- $scope.greeting = `${$scope.salutation} ${$scope.name}!`;
2990
- });
2991
-
2992
- expect($scope.greeting).toEqual(undefined);
2993
- expect($scope.greeting).toEqual(undefined);
2994
-
2995
- $scope.name = "Misko";
2996
- await wait();
2997
- expect($scope.greeting).toEqual("Hello Misko!");
2998
- });
2999
- });
3000
- });