@angular-wave/angular.ts 0.9.4 → 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.
- package/@types/index.d.ts +1 -84
- package/{src/index.ts → @types/namespace.d.ts} +4 -24
- package/@types/router/template-factory.d.ts +2 -2
- package/dist/angular-ts.esm.js +3 -3
- package/dist/angular-ts.umd.js +3 -3
- package/dist/angular-ts.umd.min.js +1 -1
- package/package.json +8 -1
- package/.github/workflows/ci.yml +0 -104
- package/.github/workflows/gh-pages.yml +0 -75
- package/.husky/pre-commit +0 -5
- package/.prettierignore +0 -9
- package/CHANGELOG.md +0 -17667
- package/CODE_OF_CONDUCT.md +0 -3
- package/CONTRIBUTING.md +0 -247
- package/DEVELOPERS.md +0 -499
- package/Makefile +0 -60
- package/RELEASE.md +0 -86
- package/TRIAGING.md +0 -127
- package/docs/.cspell.yml +0 -8
- package/docs/.github/dependabot.yml +0 -14
- package/docs/.nvmrc +0 -1
- package/docs/CONTRIBUTING.md +0 -28
- package/docs/Dockerfile +0 -4
- package/docs/LICENSE +0 -201
- package/docs/README.md +0 -217
- package/docs/assets/icons/logo.svg +0 -1
- package/docs/assets/scss/_variables_project.scss +0 -12
- package/docs/assets/scss/_variables_project_after_bs.scss +0 -8
- package/docs/assets/scss/index.scss +0 -48
- package/docs/config.yaml +0 -15
- package/docs/content/_index.md +0 -28
- package/docs/content/docs/_index.md +0 -61
- package/docs/content/docs/directive/_index.md +0 -4
- package/docs/content/docs/directive/app.md +0 -11
- package/docs/content/docs/directive/aria.md +0 -0
- package/docs/content/docs/directive/bind.md +0 -72
- package/docs/content/docs/directive/blur.md +0 -38
- package/docs/content/docs/directive/channel.md +0 -37
- package/docs/content/docs/directive/class-even.md +0 -47
- package/docs/content/docs/directive/class-odd.md +0 -48
- package/docs/content/docs/directive/class.md +0 -64
- package/docs/content/docs/directive/click.md +0 -41
- package/docs/content/docs/directive/cloak.md +0 -74
- package/docs/content/docs/directive/copy.md +0 -38
- package/docs/content/docs/directive/cut.md +0 -40
- package/docs/content/docs/directive/dblclick.md +0 -41
- package/docs/content/docs/directive/focus.md +0 -38
- package/docs/content/docs/directive/get.md +0 -203
- package/docs/content/docs/directive/include.md +0 -7
- package/docs/content/docs/directive/keydown.md +0 -38
- package/docs/content/docs/directive/keyup.md +0 -38
- package/docs/content/docs/directive/load.md +0 -43
- package/docs/content/docs/directive/mousedown.md +0 -38
- package/docs/content/docs/directive/mouseenter.md +0 -38
- package/docs/content/docs/directive/mouseleave.md +0 -38
- package/docs/content/docs/directive/mousemove.md +0 -38
- package/docs/content/docs/directive/mouseout.md +0 -38
- package/docs/content/docs/directive/mouseover.md +0 -38
- package/docs/content/docs/directive/mouseup.md +0 -38
- package/docs/content/docs/directive/non-bindable.md +0 -28
- package/docs/content/docs/filter/_index.md +0 -4
- package/docs/content/docs/filter/filter.md +0 -78
- package/docs/content/docs/filter/json.md +0 -19
- package/docs/content/docs/filter/limit-to.md +0 -30
- package/docs/content/docs/filter/order-by.md +0 -123
- package/docs/content/docs/provider/_index.md +0 -4
- package/docs/content/docs/provider/eventBusProvider.md +0 -35
- package/docs/content/docs/provider/locationProvider.md +0 -26
- package/docs/content/docs/provider/logProvider.md +0 -59
- package/docs/content/docs/provider/sceProvider.md +0 -194
- package/docs/content/docs/provider/templateCacheProvider.md +0 -100
- package/docs/content/docs/provider/templateRequestProvider.md +0 -5
- package/docs/content/docs/service/_index.md +0 -4
- package/docs/content/docs/service/compile.md +0 -5
- package/docs/content/docs/service/controller.md +0 -5
- package/docs/content/docs/service/eventBus.md +0 -56
- package/docs/content/docs/service/http.md +0 -161
- package/docs/content/docs/service/interpolation.md +0 -5
- package/docs/content/docs/service/location.md +0 -57
- package/docs/content/docs/service/log.md +0 -113
- package/docs/content/docs/service/parse.md +0 -5
- package/docs/content/docs/service/rootElement.md +0 -5
- package/docs/content/docs/service/rootScope.md +0 -5
- package/docs/content/docs/service/sce.md +0 -194
- package/docs/content/docs/service/templateCache.md +0 -64
- package/docs/content/docs/service/templateRequest.md +0 -5
- package/docs/content/docs/service/url.md +0 -5
- package/docs/content/docs/values/_index.md +0 -4
- package/docs/content/docs/values/document.md +0 -29
- package/docs/content/docs/values/window.md +0 -29
- package/docs/docker-compose.yaml +0 -12
- package/docs/docsy.work +0 -5
- package/docs/docsy.work.sum +0 -0
- package/docs/go.mod +0 -5
- package/docs/go.sum +0 -6
- package/docs/hugo-disabled.toml +0 -220
- package/docs/hugo.yaml +0 -200
- package/docs/layouts/404.html +0 -13
- package/docs/layouts/_markup/render-heading.html +0 -1
- package/docs/layouts/partials/hooks/head-end.html +0 -3
- package/docs/layouts/shortcodes/showcss.html +0 -2
- package/docs/layouts/shortcodes/showhtml.html +0 -2
- package/docs/layouts/shortcodes/showjs.html +0 -2
- package/docs/layouts/shortcodes/showraw.html +0 -1
- package/docs/layouts/shortcodes/version.html +0 -1
- package/docs/package-lock.json +0 -2293
- package/docs/package.json +0 -53
- package/docs/static/examples/counter/counter-test.html +0 -13
- package/docs/static/examples/counter/counter.html +0 -5
- package/docs/static/examples/counter/counter.test.js +0 -28
- package/docs/static/examples/document/document.html +0 -3
- package/docs/static/examples/eventbus/eventbus-test.html +0 -15
- package/docs/static/examples/eventbus/eventbus.html +0 -13
- package/docs/static/examples/eventbus/eventbus.js +0 -15
- package/docs/static/examples/eventbus/eventbus.test.js +0 -19
- package/docs/static/examples/i18n/i18n.html +0 -77
- package/docs/static/examples/ng-bind/ng-bind.html +0 -9
- package/docs/static/examples/ng-blur/ng-blur.html +0 -9
- package/docs/static/examples/ng-channel/ng-channel-test.html +0 -17
- package/docs/static/examples/ng-channel/ng-channel.html +0 -24
- package/docs/static/examples/ng-channel/ng-channel.test.js +0 -31
- package/docs/static/examples/ng-class/ng-class.html +0 -71
- package/docs/static/examples/ng-class-even/ng-class-even.html +0 -8
- package/docs/static/examples/ng-class-odd/ng-class-odd.html +0 -8
- package/docs/static/examples/ng-click/ng-click.html +0 -6
- package/docs/static/examples/ng-copy/ng-copy.html +0 -6
- package/docs/static/examples/ng-cut/ng-cut.html +0 -6
- package/docs/static/examples/ng-dblclick/ng-dblclick.html +0 -10
- package/docs/static/examples/ng-focus/ng-focus.html +0 -9
- package/docs/static/examples/ng-keydown/ng-keydown.html +0 -9
- package/docs/static/examples/ng-keyup/ng-keyup.html +0 -9
- package/docs/static/examples/ng-load/ng-load.html +0 -8
- package/docs/static/examples/ng-mousedown/ng-mousedown.html +0 -6
- package/docs/static/examples/ng-mouseenter/ng-mouseenter.html +0 -4
- package/docs/static/examples/ng-mouseleave/ng-mouseleave.html +0 -4
- package/docs/static/examples/ng-mousemove/ng-mousemove.html +0 -4
- package/docs/static/examples/ng-mouseout/ng-mouseout.html +0 -4
- package/docs/static/examples/ng-mouseover/ng-mouseover.html +0 -4
- package/docs/static/examples/ng-mouseup/ng-mouseup.html +0 -4
- package/docs/static/examples/ng-non-bindable/ng-non-bindable-test.html +0 -13
- package/docs/static/examples/ng-non-bindable/ng-non-bindable.html +0 -3
- package/docs/static/examples/ng-non-bindable/ng-non-bindable.test.js +0 -11
- package/docs/static/examples/window/window.html +0 -4
- package/docs/static/typedoc/.nojekyll +0 -1
- package/docs/static/typedoc/assets/hierarchy.js +0 -1
- package/docs/static/typedoc/assets/highlight.css +0 -29
- package/docs/static/typedoc/assets/icons.js +0 -18
- package/docs/static/typedoc/assets/icons.svg +0 -1
- package/docs/static/typedoc/assets/main.js +0 -60
- package/docs/static/typedoc/assets/navigation.js +0 -1
- package/docs/static/typedoc/assets/search.js +0 -1
- package/docs/static/typedoc/assets/style.css +0 -1633
- package/docs/static/typedoc/classes/Location.html +0 -55
- package/docs/static/typedoc/classes/LocationProvider.html +0 -20
- package/docs/static/typedoc/classes/LogProvider.html +0 -6
- package/docs/static/typedoc/classes/PubSub.html +0 -71
- package/docs/static/typedoc/classes/PubSubProvider.html +0 -4
- package/docs/static/typedoc/classes/TemplateCacheProvider.html +0 -5
- package/docs/static/typedoc/hierarchy.html +0 -1
- package/docs/static/typedoc/index.html +0 -1
- package/docs/static/typedoc/interfaces/DefaultPorts.html +0 -5
- package/docs/static/typedoc/interfaces/Html5Mode.html +0 -23
- package/docs/static/typedoc/interfaces/HttpHeadersGetter.html +0 -1
- package/docs/static/typedoc/interfaces/HttpProviderDefaults.html +0 -31
- package/docs/static/typedoc/interfaces/HttpRequestConfigHeaders.html +0 -6
- package/docs/static/typedoc/interfaces/HttpRequestTransformer.html +0 -1
- package/docs/static/typedoc/interfaces/HttpResponse.html +0 -7
- package/docs/static/typedoc/interfaces/HttpResponseTransformer.html +0 -1
- package/docs/static/typedoc/interfaces/HttpService.html +0 -38
- package/docs/static/typedoc/interfaces/LogService.html +0 -12
- package/docs/static/typedoc/interfaces/RequestConfig.html +0 -48
- package/docs/static/typedoc/interfaces/RequestShortcutConfig.html +0 -38
- package/docs/static/typedoc/interfaces/ServiceProvider.html +0 -5
- package/docs/static/typedoc/interfaces/UrlParts.html +0 -9
- package/docs/static/typedoc/types/HttpParamSerializer.html +0 -2
- package/docs/static/typedoc/types/HttpParams.html +0 -2
- package/docs/static/typedoc/types/HttpPromise.html +0 -1
- package/docs/static/typedoc/types/HttpResponseStatus.html +0 -1
- package/docs/static/typedoc/types/LogCall.html +0 -2
- package/docs/static/typedoc/types/LogServiceFactory.html +0 -2
- package/docs/static/typedoc/types/UrlChangeListener.html +0 -5
- package/docs/static/typedoc/variables/EventBus.html +0 -1
- package/docs/static/version.js +0 -13
- package/docs/test-results/.last-run.json +0 -4
- package/docs/test-results/static-examples-counter-counter-counter-example/error-context.md +0 -50
- package/eslint.config.js +0 -26
- package/images/android-chrome-192x192.png +0 -0
- package/images/android-chrome-512x512.png +0 -0
- package/images/apple-touch-icon.png +0 -0
- package/images/favicon-16x16.png +0 -0
- package/images/favicon-32x32.png +0 -0
- package/images/favicon.ico +0 -0
- package/images/site.webmanifest +0 -19
- package/index.html +0 -86
- package/legacy.d.ts +0 -1678
- package/playwright.config.ts +0 -81
- package/public/jasmine/boot0.js +0 -66
- package/public/jasmine/boot1.js +0 -134
- package/public/jasmine/jasmine-html.js +0 -970
- package/public/jasmine/jasmine.css +0 -323
- package/public/jasmine/jasmine.js +0 -11406
- package/public/public/README.md +0 -1
- package/public/public/circle.html +0 -1
- package/public/public/jasmine-helper.css +0 -9
- package/public/public/my_child_directive.html +0 -1
- package/public/public/my_directive.html +0 -1
- package/public/public/my_other_directive.html +0 -1
- package/public/public/test.html +0 -1
- package/rollup.config.js +0 -51
- package/src/angular.js +0 -286
- package/src/angular.spec.js +0 -1191
- package/src/animations/animate-cache.js +0 -80
- package/src/animations/animate-children-directive.js +0 -32
- package/src/animations/animate-children-directive.md +0 -80
- package/src/animations/animate-css-driver.js +0 -284
- package/src/animations/animate-css.html +0 -58
- package/src/animations/animate-css.js +0 -915
- package/src/animations/animate-css.md +0 -263
- package/src/animations/animate-js-driver.js +0 -60
- package/src/animations/animate-js.html +0 -47
- package/src/animations/animate-js.js +0 -371
- package/src/animations/animate-queue.js +0 -859
- package/src/animations/animate-runner.js +0 -193
- package/src/animations/animate-swap.js +0 -33
- package/src/animations/animate-swap.md +0 -88
- package/src/animations/animate.html +0 -19
- package/src/animations/animate.js +0 -546
- package/src/animations/animate.md +0 -933
- package/src/animations/animate.spec.js +0 -490
- package/src/animations/animation.js +0 -519
- package/src/animations/animations.test.js +0 -10
- package/src/animations/interface.ts +0 -19
- package/src/animations/raf-scheduler.html +0 -19
- package/src/animations/raf-scheduler.js +0 -92
- package/src/animations/raf-scheduler.spec.js +0 -98
- package/src/animations/shared.js +0 -341
- package/src/binding.html +0 -19
- package/src/binding.spec.js +0 -474
- package/src/binding.test.js +0 -10
- package/src/core/compile/attributes.js +0 -337
- package/src/core/compile/compile.html +0 -19
- package/src/core/compile/compile.js +0 -3271
- package/src/core/compile/compile.md +0 -1128
- package/src/core/compile/compile.spec.js +0 -15574
- package/src/core/compile/compile.test.js +0 -12
- package/src/core/controller/controller.html +0 -22
- package/src/core/controller/controller.js +0 -193
- package/src/core/controller/controller.spec.js +0 -334
- package/src/core/controller/controller.test.js +0 -12
- package/src/core/controller/interface.ts +0 -6
- package/src/core/core.html +0 -20
- package/src/core/core.test.js +0 -12
- package/src/core/di/injector.html +0 -19
- package/src/core/di/injector.js +0 -307
- package/src/core/di/injector.md +0 -740
- package/src/core/di/injector.spec.js +0 -2310
- package/src/core/di/injector.test.js +0 -12
- package/src/core/di/internal-injector.js +0 -286
- package/src/core/di/ng-module.html +0 -19
- package/src/core/di/ng-module.js +0 -229
- package/src/core/di/ng-module.spec.js +0 -263
- package/src/core/di/ng-module.test.js +0 -12
- package/src/core/filter/filter.html +0 -19
- package/src/core/filter/filter.js +0 -55
- package/src/core/filter/filter.md +0 -132
- package/src/core/filter/filter.spec.js +0 -149
- package/src/core/filter/filter.test.js +0 -12
- package/src/core/interpolate/interface.ts +0 -14
- package/src/core/interpolate/interpolate.html +0 -22
- package/src/core/interpolate/interpolate.js +0 -410
- package/src/core/interpolate/interpolate.spec.js +0 -601
- package/src/core/interpolate/interpolate.test.js +0 -12
- package/src/core/parse/ast/ast-node.ts +0 -81
- package/src/core/parse/ast/ast.html +0 -19
- package/src/core/parse/ast/ast.js +0 -574
- package/src/core/parse/ast/ast.spec.js +0 -1453
- package/src/core/parse/ast/ast.test.js +0 -10
- package/src/core/parse/ast-type.js +0 -23
- package/src/core/parse/interface.ts +0 -84
- package/src/core/parse/interpreter.js +0 -915
- package/src/core/parse/lexer/lexer.html +0 -19
- package/src/core/parse/lexer/lexer.js +0 -338
- package/src/core/parse/lexer/lexer.spec.js +0 -303
- package/src/core/parse/lexer/lexer.test.js +0 -10
- package/src/core/parse/lexer/token.ts +0 -22
- package/src/core/parse/parse.html +0 -19
- package/src/core/parse/parse.js +0 -337
- package/src/core/parse/parse.md +0 -57
- package/src/core/parse/parse.spec.js +0 -2107
- package/src/core/parse/parse.test.js +0 -10
- package/src/core/parse/parser/parser.html +0 -19
- package/src/core/parse/parser/parser.js +0 -64
- package/src/core/parse/parser/parser.spec.js +0 -8
- package/src/core/parse/parser/parser.test.js +0 -10
- package/src/core/prop.spec.js +0 -775
- package/src/core/root-element.spec.js +0 -14
- package/src/core/sanitize/interface.ts +0 -10
- package/src/core/sanitize/sanitize-uri.js +0 -75
- package/src/core/sanitize/sanitize-uri.spec.js +0 -249
- package/src/core/sanitize/sanitize-uri.test.js +0 -12
- package/src/core/sanitize/sanitize.html +0 -22
- package/src/core/scope/scope.html +0 -19
- package/src/core/scope/scope.js +0 -1252
- package/src/core/scope/scope.spec.js +0 -3000
- package/src/core/scope/scope.test.js +0 -12
- package/src/directive/aria/aria.html +0 -19
- package/src/directive/aria/aria.js +0 -382
- package/src/directive/aria/aria.md +0 -145
- package/src/directive/aria/aria.spec.js +0 -1241
- package/src/directive/aria/aria.test.js +0 -12
- package/src/directive/attrs/attrs.html +0 -19
- package/src/directive/attrs/attrs.js +0 -106
- package/src/directive/attrs/attrs.md +0 -224
- package/src/directive/attrs/attrs.spec.js +0 -71
- package/src/directive/attrs/attrs.test.js +0 -12
- package/src/directive/attrs/boolean.html +0 -19
- package/src/directive/attrs/boolean.spec.js +0 -137
- package/src/directive/attrs/boolean.test.js +0 -12
- package/src/directive/attrs/element-style.html +0 -22
- package/src/directive/attrs/element-style.spec.js +0 -85
- package/src/directive/attrs/element-style.test.js +0 -12
- package/src/directive/attrs/src.html +0 -19
- package/src/directive/attrs/src.spec.js +0 -163
- package/src/directive/attrs/src.test.js +0 -12
- package/src/directive/bind/bind-html.spec.js +0 -36
- package/src/directive/bind/bind.html +0 -20
- package/src/directive/bind/bind.js +0 -78
- package/src/directive/bind/bind.md +0 -142
- package/src/directive/bind/bind.spec.js +0 -314
- package/src/directive/bind/bind.test.js +0 -12
- package/src/directive/channel/channel.html +0 -19
- package/src/directive/channel/channel.js +0 -30
- package/src/directive/channel/channel.spec.js +0 -67
- package/src/directive/channel/channel.test.js +0 -10
- package/src/directive/class/class-test.html +0 -23
- package/src/directive/class/class.html +0 -19
- package/src/directive/class/class.js +0 -184
- package/src/directive/class/class.spec.js +0 -704
- package/src/directive/class/class.test.js +0 -12
- package/src/directive/cloak/cloak.html +0 -19
- package/src/directive/cloak/cloak.js +0 -11
- package/src/directive/cloak/cloak.spec.js +0 -44
- package/src/directive/cloak/cloak.test.js +0 -12
- package/src/directive/controller/controller.html +0 -22
- package/src/directive/controller/controller.js +0 -11
- package/src/directive/controller/controller.md +0 -46
- package/src/directive/controller/controller.spec.js +0 -175
- package/src/directive/controller/controller.test.js +0 -12
- package/src/directive/events/click.spec.js +0 -35
- package/src/directive/events/event.spec.js +0 -267
- package/src/directive/events/events-test.html +0 -36
- package/src/directive/events/events.html +0 -20
- package/src/directive/events/events.js +0 -65
- package/src/directive/events/events.md +0 -125
- package/src/directive/events/events.test.js +0 -12
- package/src/directive/form/form.html +0 -19
- package/src/directive/form/form.js +0 -669
- package/src/directive/form/form.spec.js +0 -1515
- package/src/directive/form/form.test.js +0 -12
- package/src/directive/http/delete.spec.js +0 -23
- package/src/directive/http/form-router-test.html +0 -44
- package/src/directive/http/form-test.html +0 -18
- package/src/directive/http/get.spec.js +0 -488
- package/src/directive/http/http.html +0 -22
- package/src/directive/http/http.js +0 -342
- package/src/directive/http/http.test.js +0 -12
- package/src/directive/http/interface.ts +0 -36
- package/src/directive/http/post-example.html +0 -30
- package/src/directive/http/post.spec.js +0 -521
- package/src/directive/http/put.spec.js +0 -23
- package/src/directive/if/if-animate-css.html +0 -57
- package/src/directive/if/if-animate-svg.html +0 -25
- package/src/directive/if/if.html +0 -19
- package/src/directive/if/if.js +0 -72
- package/src/directive/if/if.md +0 -76
- package/src/directive/if/if.spec.js +0 -293
- package/src/directive/if/if.test.js +0 -114
- package/src/directive/include/include.html +0 -19
- package/src/directive/include/include.js +0 -151
- package/src/directive/include/include.md +0 -87
- package/src/directive/include/include.spec.js +0 -734
- package/src/directive/include/include.test.js +0 -12
- package/src/directive/init/init.html +0 -19
- package/src/directive/init/init.js +0 -22
- package/src/directive/init/init.md +0 -41
- package/src/directive/init/init.spec.js +0 -68
- package/src/directive/init/init.test.js +0 -12
- package/src/directive/inject/inject.html +0 -19
- package/src/directive/inject/inject.js +0 -35
- package/src/directive/inject/inject.spec.js +0 -108
- package/src/directive/inject/inject.test.js +0 -12
- package/src/directive/input/input-example.html +0 -15
- package/src/directive/input/input.html +0 -19
- package/src/directive/input/input.js +0 -1078
- package/src/directive/input/input.md +0 -706
- package/src/directive/input/input.spec.js +0 -3700
- package/src/directive/input/input.test.js +0 -12
- package/src/directive/messages/messages.html +0 -22
- package/src/directive/messages/messages.js +0 -349
- package/src/directive/messages/messages.md +0 -543
- package/src/directive/messages/messages.spec.js +0 -1083
- package/src/directive/messages/messages.test.js +0 -12
- package/src/directive/model/change.md +0 -25
- package/src/directive/model/model.html +0 -19
- package/src/directive/model/model.js +0 -1170
- package/src/directive/model/model.spec.js +0 -1976
- package/src/directive/model/model.test.js +0 -12
- package/src/directive/model-options/model-option.test.js +0 -12
- package/src/directive/model-options/model-options.html +0 -22
- package/src/directive/model-options/model-options.js +0 -142
- package/src/directive/model-options/model-options.md +0 -407
- package/src/directive/model-options/model-options.spec.js +0 -1022
- package/src/directive/non-bindable/non-bindable.html +0 -22
- package/src/directive/non-bindable/non-bindable.js +0 -9
- package/src/directive/non-bindable/non-bindable.spec.js +0 -59
- package/src/directive/non-bindable/non-bindable.test.js +0 -12
- package/src/directive/observe/observe-demo.html +0 -184
- package/src/directive/observe/observe.html +0 -19
- package/src/directive/observe/observe.js +0 -41
- package/src/directive/observe/observe.spec.js +0 -106
- package/src/directive/observe/observe.test.js +0 -10
- package/src/directive/on/on.html +0 -19
- package/src/directive/on/on.spec.js +0 -215
- package/src/directive/on/on.test.js +0 -12
- package/src/directive/options/options-example.html +0 -17
- package/src/directive/options/options.html +0 -22
- package/src/directive/options/options.js +0 -542
- package/src/directive/options/options.md +0 -179
- package/src/directive/options/options.spec.js +0 -3554
- package/src/directive/options/options.test.js +0 -12
- package/src/directive/ref/href.html +0 -19
- package/src/directive/ref/href.spec.js +0 -141
- package/src/directive/ref/href.test.js +0 -19
- package/src/directive/ref/ref.html +0 -19
- package/src/directive/ref/ref.js +0 -89
- package/src/directive/ref/ref.spec.js +0 -546
- package/src/directive/repeat/repeat.html +0 -19
- package/src/directive/repeat/repeat.js +0 -333
- package/src/directive/repeat/repeat.md +0 -330
- package/src/directive/repeat/repeat.spec.js +0 -1209
- package/src/directive/repeat/repeat.test.js +0 -12
- package/src/directive/script/script.html +0 -19
- package/src/directive/script/script.js +0 -17
- package/src/directive/script/script.md +0 -11
- package/src/directive/script/script.spec.js +0 -47
- package/src/directive/script/script.test.js +0 -12
- package/src/directive/select/select.html +0 -19
- package/src/directive/select/select.js +0 -594
- package/src/directive/select/select.md +0 -74
- package/src/directive/select/select.spec.js +0 -2566
- package/src/directive/select/select.test.js +0 -12
- package/src/directive/setter/setter.html +0 -19
- package/src/directive/setter/setter.js +0 -59
- package/src/directive/setter/setter.spec.js +0 -100
- package/src/directive/setter/setter.test.js +0 -12
- package/src/directive/show-hide/show-hide.html +0 -22
- package/src/directive/show-hide/show-hide.js +0 -65
- package/src/directive/show-hide/show-hide.md +0 -255
- package/src/directive/show-hide/show-hide.spec.js +0 -268
- package/src/directive/show-hide/show-hide.test.js +0 -12
- package/src/directive/style/style.html +0 -19
- package/src/directive/style/style.js +0 -27
- package/src/directive/style/style.md +0 -23
- package/src/directive/style/style.spec.js +0 -183
- package/src/directive/style/style.test.js +0 -12
- package/src/directive/switch/switch.html +0 -19
- package/src/directive/switch/switch.js +0 -133
- package/src/directive/switch/switch.md +0 -66
- package/src/directive/switch/switch.spec.js +0 -509
- package/src/directive/switch/switch.test.js +0 -12
- package/src/directive/transclude/transclude.js +0 -122
- package/src/directive/validators/validators.html +0 -22
- package/src/directive/validators/validators.js +0 -346
- package/src/directive/validators/validators.spec.js +0 -740
- package/src/directive/validators/validators.test.js +0 -12
- package/src/filters/filter.js +0 -213
- package/src/filters/filter.spec.js +0 -719
- package/src/filters/filters.html +0 -22
- package/src/filters/filters.js +0 -239
- package/src/filters/filters.spec.js +0 -36
- package/src/filters/filters.test.js +0 -12
- package/src/filters/interface.ts +0 -9
- package/src/filters/limit-to.js +0 -55
- package/src/filters/limit-to.spec.js +0 -252
- package/src/filters/order-by.js +0 -181
- package/src/filters/order-by.spec.js +0 -883
- package/src/index.js +0 -6
- package/src/index.spec.js +0 -11
- package/src/injection-tokens.js +0 -81
- package/src/interface.ts +0 -430
- package/src/ng.js +0 -291
- package/src/ng.spec.js +0 -45
- package/src/router/common/trace.js +0 -240
- package/src/router/directives/component-example.html +0 -37
- package/src/router/directives/state-directives.html +0 -22
- package/src/router/directives/state-directives.js +0 -393
- package/src/router/directives/state-directives.md +0 -435
- package/src/router/directives/state-directives.spec.js +0 -1091
- package/src/router/directives/state-directives.test.js +0 -10
- package/src/router/directives/view-directive.js +0 -489
- package/src/router/directives/view-directive.spec.js +0 -1921
- package/src/router/directives/view-directive.test.js +0 -10
- package/src/router/directives/view-directives.html +0 -22
- package/src/router/glob/glob.html +0 -19
- package/src/router/glob/glob.js +0 -102
- package/src/router/glob/glob.spec.js +0 -108
- package/src/router/glob/glob.test.js +0 -12
- package/src/router/hooks/core-resolvables.js +0 -38
- package/src/router/hooks/ignored-transition.js +0 -25
- package/src/router/hooks/invalid-transition.js +0 -14
- package/src/router/hooks/lazy-load.js +0 -104
- package/src/router/hooks/on-enter-exit-retain.js +0 -55
- package/src/router/hooks/redirect-to.js +0 -38
- package/src/router/hooks/resolve.js +0 -57
- package/src/router/hooks/update-globals.js +0 -34
- package/src/router/hooks/url.js +0 -34
- package/src/router/hooks/views.js +0 -41
- package/src/router/params/interface.ts +0 -626
- package/src/router/params/param-factory.js +0 -23
- package/src/router/params/param-type.js +0 -133
- package/src/router/params/param-types.js +0 -153
- package/src/router/params/param.js +0 -243
- package/src/router/params/state-params.js +0 -36
- package/src/router/path/path-node.js +0 -78
- package/src/router/path/path-utils.js +0 -207
- package/src/router/resolve/interface.ts +0 -208
- package/src/router/resolve/resolvable.js +0 -123
- package/src/router/resolve/resolve-context.js +0 -190
- package/src/router/router-test-hashbang.html +0 -45
- package/src/router/router-test.html +0 -41
- package/src/router/router.html +0 -22
- package/src/router/router.js +0 -54
- package/src/router/router.test.js +0 -12
- package/src/router/services.spec.js +0 -52
- package/src/router/state/interface.ts +0 -1007
- package/src/router/state/state-builder.js +0 -376
- package/src/router/state/state-builder.spec.js +0 -86
- package/src/router/state/state-matcher.js +0 -64
- package/src/router/state/state-object.js +0 -118
- package/src/router/state/state-queue-manager.js +0 -95
- package/src/router/state/state-registry.js +0 -262
- package/src/router/state/state-service.js +0 -687
- package/src/router/state/state.html +0 -23
- package/src/router/state/state.spec.js +0 -1002
- package/src/router/state/state.test.js +0 -12
- package/src/router/state/target-state.js +0 -162
- package/src/router/state/views.js +0 -195
- package/src/router/state-filter.spec.js +0 -139
- package/src/router/state-filters.js +0 -46
- package/src/router/template-factory.html +0 -19
- package/src/router/template-factory.js +0 -249
- package/src/router/template-factory.spec.js +0 -146
- package/src/router/template-factory.test.js +0 -12
- package/src/router/transition/hook-builder.js +0 -137
- package/src/router/transition/hook-registry.js +0 -181
- package/src/router/transition/interface.js +0 -18
- package/src/router/transition/interface.ts +0 -922
- package/src/router/transition/reject-factory.js +0 -122
- package/src/router/transition/transition-event-type.js +0 -26
- package/src/router/transition/transition-hook.js +0 -199
- package/src/router/transition/transition-service.js +0 -297
- package/src/router/transition/transition.js +0 -653
- package/src/router/url/url-config.js +0 -155
- package/src/router/url/url-matcher.js +0 -532
- package/src/router/url/url-rule.js +0 -231
- package/src/router/url/url-rules.js +0 -350
- package/src/router/url/url-service.js +0 -446
- package/src/router/url/url-service.spec.js +0 -1288
- package/src/router/url/url.html +0 -19
- package/src/router/url/url.test.js +0 -12
- package/src/router/view/interface.ts +0 -51
- package/src/router/view/view.html +0 -19
- package/src/router/view/view.js +0 -262
- package/src/router/view/view.spec.js +0 -100
- package/src/router/view/view.test.js +0 -12
- package/src/router/view-hook.spec.js +0 -215
- package/src/router/view-scroll.js +0 -33
- package/src/router/view-scroll.spec.js +0 -72
- package/src/services/anchor-scroll/anchor-scroll.html +0 -76
- package/src/services/anchor-scroll/anchor-scroll.js +0 -147
- package/src/services/exception/exception-handler.js +0 -75
- package/src/services/exception/interface.ts +0 -7
- package/src/services/http/http.html +0 -23
- package/src/services/http/http.js +0 -1109
- package/src/services/http/http.spec.js +0 -4320
- package/src/services/http/http.test.js +0 -11
- package/src/services/http/interface.ts +0 -256
- package/src/services/http/template-request.spec.js +0 -220
- package/src/services/location/interface.ts +0 -70
- package/src/services/location/location.html +0 -22
- package/src/services/location/location.js +0 -1006
- package/src/services/location/location.spec.js +0 -3792
- package/src/services/location/location.test.js +0 -12
- package/src/services/log/interface.ts +0 -39
- package/src/services/log/log.html +0 -19
- package/src/services/log/log.js +0 -74
- package/src/services/log/log.spec.js +0 -64
- package/src/services/log/log.test.js +0 -12
- package/src/services/pubsub/pubsub.html +0 -19
- package/src/services/pubsub/pubsub.js +0 -349
- package/src/services/pubsub/pubsub.spec.js +0 -400
- package/src/services/pubsub/pubsub.test.js +0 -12
- package/src/services/sce/sce.html +0 -19
- package/src/services/sce/sce.js +0 -852
- package/src/services/sce/sce.spec.js +0 -617
- package/src/services/sce/sce.test.js +0 -12
- package/src/services/template-cache/template-cache.html +0 -22
- package/src/services/template-cache/template-cache.js +0 -15
- package/src/services/template-cache/template-cache.spec.js +0 -134
- package/src/services/template-cache/template-cache.test.js +0 -12
- package/src/services/template-request/interface.ts +0 -23
- package/src/services/template-request/template-request.js +0 -142
- package/src/shared/cache.js +0 -7
- package/src/shared/common.js +0 -365
- package/src/shared/common.spec.js +0 -294
- package/src/shared/constants.js +0 -21
- package/src/shared/dom.js +0 -716
- package/src/shared/hof.js +0 -157
- package/src/shared/hof.spec.js +0 -60
- package/src/shared/interface.ts +0 -21
- package/src/shared/min-err.spec.js +0 -178
- package/src/shared/noderef.js +0 -225
- package/src/shared/predicates.js +0 -34
- package/src/shared/queue.js +0 -105
- package/src/shared/queue.spec.js +0 -80
- package/src/shared/shared.html +0 -24
- package/src/shared/shared.test.js +0 -12
- package/src/shared/strings.js +0 -142
- package/src/shared/strings.spec.js +0 -40
- package/src/shared/test-utils.js +0 -47
- package/src/shared/url-utils/interface.ts +0 -54
- package/src/shared/url-utils/url-utils.html +0 -22
- package/src/shared/url-utils/url-utils.js +0 -122
- package/src/shared/url-utils/url-utils.spec.js +0 -148
- package/src/shared/url-utils/url-utils.test.js +0 -12
- package/src/shared/utils.js +0 -1255
- package/src/shared/utils.spec.js +0 -178
- package/src/src.html +0 -21
- package/src/src.test.js +0 -10
- package/tsconfig.json +0 -19
- package/tsconfig.types.json +0 -14
- package/typedoc.json +0 -8
- package/utils/express.js +0 -203
- package/utils/version.cjs +0 -23
- 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
|
-
});
|