@angular-wave/angular.ts 0.9.3 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (703) hide show
  1. package/@types/angular.d.ts +4 -19
  2. package/@types/animations/animate.d.ts +2 -2
  3. package/@types/animations/animation.d.ts +1 -1
  4. package/@types/core/compile/attributes.d.ts +1 -1
  5. package/@types/core/compile/compile.d.ts +2 -2
  6. package/@types/core/controller/controller.d.ts +1 -1
  7. package/@types/core/controller/interface.d.ts +6 -0
  8. package/@types/core/di/ng-module.d.ts +27 -26
  9. package/@types/core/filter/filter.d.ts +5 -5
  10. package/@types/core/interpolate/interface.d.ts +13 -0
  11. package/@types/core/interpolate/interpolate.d.ts +1 -13
  12. package/@types/core/scope/scope.d.ts +4 -1
  13. package/@types/directive/http/http.d.ts +16 -16
  14. package/@types/directive/http/interface.d.ts +27 -0
  15. package/@types/directive/include/include.d.ts +4 -4
  16. package/@types/directive/inject/inject.d.ts +12 -0
  17. package/@types/directive/model/model.d.ts +1 -1
  18. package/@types/directive/script/script.d.ts +2 -2
  19. package/@types/directive/setter/setter.d.ts +4 -4
  20. package/@types/filters/filter.d.ts +2 -2
  21. package/@types/filters/filters.d.ts +2 -2
  22. package/@types/filters/interface.d.ts +8 -0
  23. package/@types/filters/limit-to.d.ts +2 -2
  24. package/@types/filters/order-by.d.ts +2 -2
  25. package/@types/interface.d.ts +105 -82
  26. package/@types/namespace.d.ts +76 -0
  27. package/@types/router/state/interface.d.ts +8 -8
  28. package/@types/router/state-filters.d.ts +4 -4
  29. package/@types/router/template-factory.d.ts +8 -8
  30. package/@types/router/transition/hook-builder.d.ts +5 -2
  31. package/@types/router/transition/hook-registry.d.ts +11 -2
  32. package/@types/router/transition/transition-service.d.ts +6 -2
  33. package/@types/router/transition/transition.d.ts +2 -2
  34. package/@types/router/view/view.d.ts +1 -8
  35. package/@types/router/view-scroll.d.ts +4 -2
  36. package/@types/services/{anchor-scroll.d.ts → anchor-scroll/anchor-scroll.d.ts} +2 -2
  37. package/@types/services/exception/exception-handler.d.ts +2 -2
  38. package/@types/services/exception/interface.d.ts +1 -1
  39. package/@types/services/http/http.d.ts +40 -2
  40. package/@types/services/http/interface.d.ts +11 -0
  41. package/@types/services/location/location.d.ts +1 -4
  42. package/@types/services/sce/sce.d.ts +3 -4
  43. package/@types/services/template-cache/template-cache.d.ts +4 -4
  44. package/@types/services/template-request/interface.d.ts +22 -0
  45. package/@types/services/{template-request.d.ts → template-request/template-request.d.ts} +4 -7
  46. package/@types/shared/common.d.ts +8 -69
  47. package/@types/shared/hof.d.ts +7 -7
  48. package/dist/angular-ts.esm.js +510 -570
  49. package/dist/angular-ts.umd.js +510 -570
  50. package/dist/angular-ts.umd.min.js +1 -1
  51. package/package.json +8 -1
  52. package/.github/workflows/ci.yml +0 -104
  53. package/.github/workflows/gh-pages.yml +0 -75
  54. package/.husky/pre-commit +0 -5
  55. package/.prettierignore +0 -9
  56. package/@types/services/cookie-reader.d.ts +0 -4
  57. package/@types/services/http-backend/http-backend.d.ts +0 -58
  58. package/@types/services/template-cache/interface.d.ts +0 -10
  59. package/CHANGELOG.md +0 -17667
  60. package/CODE_OF_CONDUCT.md +0 -3
  61. package/CONTRIBUTING.md +0 -247
  62. package/DEVELOPERS.md +0 -499
  63. package/Makefile +0 -60
  64. package/RELEASE.md +0 -86
  65. package/TRIAGING.md +0 -127
  66. package/docs/.cspell.yml +0 -8
  67. package/docs/.github/dependabot.yml +0 -14
  68. package/docs/.nvmrc +0 -1
  69. package/docs/CONTRIBUTING.md +0 -28
  70. package/docs/Dockerfile +0 -4
  71. package/docs/LICENSE +0 -201
  72. package/docs/README.md +0 -217
  73. package/docs/assets/icons/logo.svg +0 -1
  74. package/docs/assets/scss/_variables_project.scss +0 -12
  75. package/docs/assets/scss/_variables_project_after_bs.scss +0 -8
  76. package/docs/assets/scss/index.scss +0 -48
  77. package/docs/config.yaml +0 -15
  78. package/docs/content/_index.md +0 -28
  79. package/docs/content/docs/_index.md +0 -61
  80. package/docs/content/docs/directive/_index.md +0 -4
  81. package/docs/content/docs/directive/app.md +0 -11
  82. package/docs/content/docs/directive/aria.md +0 -0
  83. package/docs/content/docs/directive/bind.md +0 -72
  84. package/docs/content/docs/directive/blur.md +0 -38
  85. package/docs/content/docs/directive/channel.md +0 -37
  86. package/docs/content/docs/directive/class-even.md +0 -47
  87. package/docs/content/docs/directive/class-odd.md +0 -48
  88. package/docs/content/docs/directive/class.md +0 -64
  89. package/docs/content/docs/directive/click.md +0 -41
  90. package/docs/content/docs/directive/cloak.md +0 -74
  91. package/docs/content/docs/directive/copy.md +0 -38
  92. package/docs/content/docs/directive/cut.md +0 -40
  93. package/docs/content/docs/directive/dblclick.md +0 -41
  94. package/docs/content/docs/directive/focus.md +0 -38
  95. package/docs/content/docs/directive/get.md +0 -203
  96. package/docs/content/docs/directive/include.md +0 -7
  97. package/docs/content/docs/directive/keydown.md +0 -38
  98. package/docs/content/docs/directive/keyup.md +0 -38
  99. package/docs/content/docs/directive/load.md +0 -43
  100. package/docs/content/docs/directive/mousedown.md +0 -38
  101. package/docs/content/docs/directive/mouseenter.md +0 -38
  102. package/docs/content/docs/directive/mouseleave.md +0 -38
  103. package/docs/content/docs/directive/mousemove.md +0 -38
  104. package/docs/content/docs/directive/mouseout.md +0 -38
  105. package/docs/content/docs/directive/mouseover.md +0 -38
  106. package/docs/content/docs/directive/mouseup.md +0 -38
  107. package/docs/content/docs/directive/non-bindable.md +0 -28
  108. package/docs/content/docs/filter/_index.md +0 -4
  109. package/docs/content/docs/provider/_index.md +0 -4
  110. package/docs/content/docs/provider/eventBusProvider.md +0 -35
  111. package/docs/content/docs/provider/locationProvider.md +0 -26
  112. package/docs/content/docs/provider/logProvider.md +0 -59
  113. package/docs/content/docs/provider/templateCacheProvider.md +0 -100
  114. package/docs/content/docs/service/_index.md +0 -4
  115. package/docs/content/docs/service/eventBus.md +0 -56
  116. package/docs/content/docs/service/location.md +0 -57
  117. package/docs/content/docs/service/log.md +0 -113
  118. package/docs/content/docs/service/templateCache.md +0 -64
  119. package/docs/content/docs/service/url.md +0 -5
  120. package/docs/docker-compose.yaml +0 -12
  121. package/docs/docsy.work +0 -5
  122. package/docs/docsy.work.sum +0 -0
  123. package/docs/go.mod +0 -5
  124. package/docs/go.sum +0 -6
  125. package/docs/hugo-disabled.toml +0 -220
  126. package/docs/hugo.yaml +0 -200
  127. package/docs/layouts/404.html +0 -13
  128. package/docs/layouts/_markup/render-heading.html +0 -1
  129. package/docs/layouts/partials/hooks/head-end.html +0 -3
  130. package/docs/layouts/shortcodes/showcss.html +0 -2
  131. package/docs/layouts/shortcodes/showhtml.html +0 -2
  132. package/docs/layouts/shortcodes/showjs.html +0 -2
  133. package/docs/layouts/shortcodes/showraw.html +0 -1
  134. package/docs/layouts/shortcodes/version.html +0 -1
  135. package/docs/package-lock.json +0 -2293
  136. package/docs/package.json +0 -53
  137. package/docs/static/examples/counter/counter-test.html +0 -13
  138. package/docs/static/examples/counter/counter.html +0 -5
  139. package/docs/static/examples/counter/counter.test.js +0 -28
  140. package/docs/static/examples/eventbus/eventbus-test.html +0 -15
  141. package/docs/static/examples/eventbus/eventbus.html +0 -13
  142. package/docs/static/examples/eventbus/eventbus.js +0 -15
  143. package/docs/static/examples/eventbus/eventbus.test.js +0 -19
  144. package/docs/static/examples/ng-bind/ng-bind.html +0 -9
  145. package/docs/static/examples/ng-blur/ng-blur.html +0 -9
  146. package/docs/static/examples/ng-channel/ng-channel-test.html +0 -17
  147. package/docs/static/examples/ng-channel/ng-channel.html +0 -24
  148. package/docs/static/examples/ng-channel/ng-channel.test.js +0 -31
  149. package/docs/static/examples/ng-class/ng-class.html +0 -71
  150. package/docs/static/examples/ng-class-even/ng-class-even.html +0 -8
  151. package/docs/static/examples/ng-class-odd/ng-class-odd.html +0 -8
  152. package/docs/static/examples/ng-click/ng-click.html +0 -6
  153. package/docs/static/examples/ng-copy/ng-copy.html +0 -6
  154. package/docs/static/examples/ng-cut/ng-cut.html +0 -6
  155. package/docs/static/examples/ng-dblclick/ng-dblclick.html +0 -10
  156. package/docs/static/examples/ng-focus/ng-focus.html +0 -9
  157. package/docs/static/examples/ng-keydown/ng-keydown.html +0 -9
  158. package/docs/static/examples/ng-keyup/ng-keyup.html +0 -9
  159. package/docs/static/examples/ng-load/ng-load.html +0 -8
  160. package/docs/static/examples/ng-mousedown/ng-mousedown.html +0 -6
  161. package/docs/static/examples/ng-mouseenter/ng-mouseenter.html +0 -4
  162. package/docs/static/examples/ng-mouseleave/ng-mouseleave.html +0 -4
  163. package/docs/static/examples/ng-mousemove/ng-mousemove.html +0 -4
  164. package/docs/static/examples/ng-mouseout/ng-mouseout.html +0 -4
  165. package/docs/static/examples/ng-mouseover/ng-mouseover.html +0 -4
  166. package/docs/static/examples/ng-mouseup/ng-mouseup.html +0 -4
  167. package/docs/static/examples/ng-non-bindable/ng-non-bindable-test.html +0 -13
  168. package/docs/static/examples/ng-non-bindable/ng-non-bindable.html +0 -3
  169. package/docs/static/examples/ng-non-bindable/ng-non-bindable.test.js +0 -11
  170. package/docs/static/typedoc/.nojekyll +0 -1
  171. package/docs/static/typedoc/assets/hierarchy.js +0 -1
  172. package/docs/static/typedoc/assets/highlight.css +0 -78
  173. package/docs/static/typedoc/assets/icons.js +0 -18
  174. package/docs/static/typedoc/assets/icons.svg +0 -1
  175. package/docs/static/typedoc/assets/main.js +0 -60
  176. package/docs/static/typedoc/assets/navigation.js +0 -1
  177. package/docs/static/typedoc/assets/search.js +0 -1
  178. package/docs/static/typedoc/assets/style.css +0 -1633
  179. package/docs/static/typedoc/classes/Location.html +0 -55
  180. package/docs/static/typedoc/classes/LocationProvider.html +0 -20
  181. package/docs/static/typedoc/classes/LogProvider.html +0 -6
  182. package/docs/static/typedoc/classes/PubSub.html +0 -71
  183. package/docs/static/typedoc/classes/PubSubProvider.html +0 -3
  184. package/docs/static/typedoc/classes/TemplateCacheProvider.html +0 -5
  185. package/docs/static/typedoc/hierarchy.html +0 -1
  186. package/docs/static/typedoc/index.html +0 -1
  187. package/docs/static/typedoc/interfaces/ChangesObject.html +0 -6
  188. package/docs/static/typedoc/interfaces/ComponentOptions.html +0 -16
  189. package/docs/static/typedoc/interfaces/Controller.html +0 -12
  190. package/docs/static/typedoc/interfaces/DefaultPorts.html +0 -5
  191. package/docs/static/typedoc/interfaces/Directive.html +0 -37
  192. package/docs/static/typedoc/interfaces/DirectivePrePost.html +0 -4
  193. package/docs/static/typedoc/interfaces/Html5Mode.html +0 -23
  194. package/docs/static/typedoc/interfaces/HttpHeadersGetter.html +0 -1
  195. package/docs/static/typedoc/interfaces/HttpProviderDefaults.html +0 -31
  196. package/docs/static/typedoc/interfaces/HttpRequestConfigHeaders.html +0 -6
  197. package/docs/static/typedoc/interfaces/HttpRequestTransformer.html +0 -1
  198. package/docs/static/typedoc/interfaces/HttpResponse.html +0 -7
  199. package/docs/static/typedoc/interfaces/HttpResponseTransformer.html +0 -1
  200. package/docs/static/typedoc/interfaces/HttpService.html +0 -38
  201. package/docs/static/typedoc/interfaces/LogService.html +0 -12
  202. package/docs/static/typedoc/interfaces/NgModelController.html +0 -30
  203. package/docs/static/typedoc/interfaces/NgModelOptions.html +0 -16
  204. package/docs/static/typedoc/interfaces/Provider.html +0 -34
  205. package/docs/static/typedoc/interfaces/RequestConfig.html +0 -48
  206. package/docs/static/typedoc/interfaces/RequestShortcutConfig.html +0 -38
  207. package/docs/static/typedoc/interfaces/ServiceProvider.html +0 -5
  208. package/docs/static/typedoc/interfaces/TemplateCache.html +0 -7
  209. package/docs/static/typedoc/interfaces/TranscludeFunctionObject.html +0 -8
  210. package/docs/static/typedoc/interfaces/UrlParts.html +0 -9
  211. package/docs/static/typedoc/types/AnnotatedDirectiveFactory.html +0 -1
  212. package/docs/static/typedoc/types/AnnotatedFactory.html +0 -8
  213. package/docs/static/typedoc/types/CloneAttachFunction.html +0 -2
  214. package/docs/static/typedoc/types/ControllerConstructor.html +0 -2
  215. package/docs/static/typedoc/types/DirectiveCompileFn.html +0 -2
  216. package/docs/static/typedoc/types/DirectiveController.html +0 -2
  217. package/docs/static/typedoc/types/DirectiveFactory.html +0 -1
  218. package/docs/static/typedoc/types/DirectiveFactoryFn.html +0 -1
  219. package/docs/static/typedoc/types/DirectiveLinkFn.html +0 -2
  220. package/docs/static/typedoc/types/ExpandoStore.html +0 -2
  221. package/docs/static/typedoc/types/Expression.html +0 -6
  222. package/docs/static/typedoc/types/FilterFactory.html +0 -2
  223. package/docs/static/typedoc/types/FilterFn.html +0 -2
  224. package/docs/static/typedoc/types/HttpPromise.html +0 -1
  225. package/docs/static/typedoc/types/HttpResponseStatus.html +0 -1
  226. package/docs/static/typedoc/types/Injectable.html +0 -4
  227. package/docs/static/typedoc/types/InjectableClass.html +0 -1
  228. package/docs/static/typedoc/types/InjectableFactory.html +0 -1
  229. package/docs/static/typedoc/types/LogCall.html +0 -2
  230. package/docs/static/typedoc/types/LogServiceFactory.html +0 -2
  231. package/docs/static/typedoc/types/OnChangesObject.html +0 -2
  232. package/docs/static/typedoc/types/SwapModeType.html +0 -2
  233. package/docs/static/typedoc/types/TController.html +0 -2
  234. package/docs/static/typedoc/types/UrlChangeListener.html +0 -5
  235. package/docs/static/typedoc/variables/EventBus.html +0 -1
  236. package/docs/static/typedoc/variables/SwapMode.html +0 -11
  237. package/docs/static/version.js +0 -13
  238. package/docs/test-results/.last-run.json +0 -4
  239. package/docs/test-results/static-examples-counter-counter-counter-example/error-context.md +0 -50
  240. package/eslint.config.js +0 -26
  241. package/images/android-chrome-192x192.png +0 -0
  242. package/images/android-chrome-512x512.png +0 -0
  243. package/images/apple-touch-icon.png +0 -0
  244. package/images/favicon-16x16.png +0 -0
  245. package/images/favicon-32x32.png +0 -0
  246. package/images/favicon.ico +0 -0
  247. package/images/site.webmanifest +0 -19
  248. package/index.html +0 -86
  249. package/legacy.d.ts +0 -2599
  250. package/playwright.config.ts +0 -81
  251. package/public/jasmine/boot0.js +0 -66
  252. package/public/jasmine/boot1.js +0 -134
  253. package/public/jasmine/jasmine-html.js +0 -970
  254. package/public/jasmine/jasmine.css +0 -323
  255. package/public/jasmine/jasmine.js +0 -11406
  256. package/public/public/README.md +0 -1
  257. package/public/public/circle.html +0 -1
  258. package/public/public/jasmine-helper.css +0 -9
  259. package/public/public/my_child_directive.html +0 -1
  260. package/public/public/my_directive.html +0 -1
  261. package/public/public/my_other_directive.html +0 -1
  262. package/public/public/test.html +0 -1
  263. package/rollup.config.js +0 -51
  264. package/src/angular.js +0 -293
  265. package/src/angular.spec.js +0 -1191
  266. package/src/animations/animate-cache.js +0 -80
  267. package/src/animations/animate-children-directive.js +0 -32
  268. package/src/animations/animate-children-directive.md +0 -80
  269. package/src/animations/animate-css-driver.js +0 -284
  270. package/src/animations/animate-css.html +0 -58
  271. package/src/animations/animate-css.js +0 -915
  272. package/src/animations/animate-css.md +0 -263
  273. package/src/animations/animate-js-driver.js +0 -60
  274. package/src/animations/animate-js.html +0 -47
  275. package/src/animations/animate-js.js +0 -371
  276. package/src/animations/animate-queue.js +0 -859
  277. package/src/animations/animate-runner.js +0 -193
  278. package/src/animations/animate-swap.js +0 -33
  279. package/src/animations/animate-swap.md +0 -88
  280. package/src/animations/animate.html +0 -19
  281. package/src/animations/animate.js +0 -546
  282. package/src/animations/animate.md +0 -933
  283. package/src/animations/animate.spec.js +0 -490
  284. package/src/animations/animation.js +0 -519
  285. package/src/animations/animations.test.js +0 -10
  286. package/src/animations/interface.ts +0 -19
  287. package/src/animations/raf-scheduler.html +0 -19
  288. package/src/animations/raf-scheduler.js +0 -92
  289. package/src/animations/raf-scheduler.spec.js +0 -98
  290. package/src/animations/shared.js +0 -341
  291. package/src/binding.html +0 -19
  292. package/src/binding.spec.js +0 -474
  293. package/src/binding.test.js +0 -10
  294. package/src/core/compile/attributes.js +0 -337
  295. package/src/core/compile/compile.html +0 -19
  296. package/src/core/compile/compile.js +0 -3270
  297. package/src/core/compile/compile.md +0 -1128
  298. package/src/core/compile/compile.spec.js +0 -15574
  299. package/src/core/compile/compile.test.js +0 -12
  300. package/src/core/controller/controller.html +0 -22
  301. package/src/core/controller/controller.js +0 -189
  302. package/src/core/controller/controller.spec.js +0 -334
  303. package/src/core/controller/controller.test.js +0 -12
  304. package/src/core/core.html +0 -20
  305. package/src/core/core.test.js +0 -12
  306. package/src/core/di/injector.html +0 -19
  307. package/src/core/di/injector.js +0 -307
  308. package/src/core/di/injector.md +0 -740
  309. package/src/core/di/injector.spec.js +0 -2310
  310. package/src/core/di/injector.test.js +0 -12
  311. package/src/core/di/internal-injector.js +0 -284
  312. package/src/core/di/ng-module.html +0 -19
  313. package/src/core/di/ng-module.js +0 -226
  314. package/src/core/di/ng-module.spec.js +0 -263
  315. package/src/core/di/ng-module.test.js +0 -12
  316. package/src/core/filter/filter.html +0 -19
  317. package/src/core/filter/filter.js +0 -55
  318. package/src/core/filter/filter.md +0 -132
  319. package/src/core/filter/filter.spec.js +0 -149
  320. package/src/core/filter/filter.test.js +0 -12
  321. package/src/core/interpolate/interpolate.html +0 -22
  322. package/src/core/interpolate/interpolate.js +0 -408
  323. package/src/core/interpolate/interpolate.spec.js +0 -601
  324. package/src/core/interpolate/interpolate.test.js +0 -12
  325. package/src/core/parse/ast/ast-node.ts +0 -81
  326. package/src/core/parse/ast/ast.html +0 -19
  327. package/src/core/parse/ast/ast.js +0 -574
  328. package/src/core/parse/ast/ast.spec.js +0 -1453
  329. package/src/core/parse/ast/ast.test.js +0 -10
  330. package/src/core/parse/ast-type.js +0 -23
  331. package/src/core/parse/interface.ts +0 -84
  332. package/src/core/parse/interpreter.js +0 -915
  333. package/src/core/parse/lexer/lexer.html +0 -19
  334. package/src/core/parse/lexer/lexer.js +0 -338
  335. package/src/core/parse/lexer/lexer.spec.js +0 -303
  336. package/src/core/parse/lexer/lexer.test.js +0 -10
  337. package/src/core/parse/lexer/token.ts +0 -22
  338. package/src/core/parse/parse.html +0 -19
  339. package/src/core/parse/parse.js +0 -337
  340. package/src/core/parse/parse.md +0 -57
  341. package/src/core/parse/parse.spec.js +0 -2107
  342. package/src/core/parse/parse.test.js +0 -10
  343. package/src/core/parse/parser/parser.html +0 -19
  344. package/src/core/parse/parser/parser.js +0 -64
  345. package/src/core/parse/parser/parser.spec.js +0 -8
  346. package/src/core/parse/parser/parser.test.js +0 -10
  347. package/src/core/prop.spec.js +0 -775
  348. package/src/core/root-element.spec.js +0 -14
  349. package/src/core/sanitize/interface.ts +0 -10
  350. package/src/core/sanitize/sanitize-uri.js +0 -75
  351. package/src/core/sanitize/sanitize-uri.spec.js +0 -249
  352. package/src/core/sanitize/sanitize-uri.test.js +0 -12
  353. package/src/core/sanitize/sanitize.html +0 -22
  354. package/src/core/scope/scope.html +0 -19
  355. package/src/core/scope/scope.js +0 -1249
  356. package/src/core/scope/scope.spec.js +0 -3000
  357. package/src/core/scope/scope.test.js +0 -12
  358. package/src/directive/aria/aria.html +0 -19
  359. package/src/directive/aria/aria.js +0 -382
  360. package/src/directive/aria/aria.md +0 -145
  361. package/src/directive/aria/aria.spec.js +0 -1241
  362. package/src/directive/aria/aria.test.js +0 -12
  363. package/src/directive/attrs/attrs.html +0 -19
  364. package/src/directive/attrs/attrs.js +0 -106
  365. package/src/directive/attrs/attrs.md +0 -224
  366. package/src/directive/attrs/attrs.spec.js +0 -71
  367. package/src/directive/attrs/attrs.test.js +0 -12
  368. package/src/directive/attrs/boolean.html +0 -19
  369. package/src/directive/attrs/boolean.spec.js +0 -137
  370. package/src/directive/attrs/boolean.test.js +0 -12
  371. package/src/directive/attrs/element-style.html +0 -22
  372. package/src/directive/attrs/element-style.spec.js +0 -85
  373. package/src/directive/attrs/element-style.test.js +0 -12
  374. package/src/directive/attrs/src.html +0 -19
  375. package/src/directive/attrs/src.spec.js +0 -163
  376. package/src/directive/attrs/src.test.js +0 -12
  377. package/src/directive/bind/bind-html.spec.js +0 -36
  378. package/src/directive/bind/bind.html +0 -20
  379. package/src/directive/bind/bind.js +0 -78
  380. package/src/directive/bind/bind.md +0 -142
  381. package/src/directive/bind/bind.spec.js +0 -314
  382. package/src/directive/bind/bind.test.js +0 -12
  383. package/src/directive/channel/channel.html +0 -19
  384. package/src/directive/channel/channel.js +0 -30
  385. package/src/directive/channel/channel.spec.js +0 -67
  386. package/src/directive/channel/channel.test.js +0 -10
  387. package/src/directive/class/class-test.html +0 -23
  388. package/src/directive/class/class.html +0 -19
  389. package/src/directive/class/class.js +0 -184
  390. package/src/directive/class/class.spec.js +0 -704
  391. package/src/directive/class/class.test.js +0 -12
  392. package/src/directive/cloak/cloak.html +0 -19
  393. package/src/directive/cloak/cloak.js +0 -11
  394. package/src/directive/cloak/cloak.spec.js +0 -44
  395. package/src/directive/cloak/cloak.test.js +0 -12
  396. package/src/directive/controller/controller.html +0 -22
  397. package/src/directive/controller/controller.js +0 -11
  398. package/src/directive/controller/controller.md +0 -46
  399. package/src/directive/controller/controller.spec.js +0 -175
  400. package/src/directive/controller/controller.test.js +0 -12
  401. package/src/directive/events/click.spec.js +0 -35
  402. package/src/directive/events/event.spec.js +0 -267
  403. package/src/directive/events/events-test.html +0 -36
  404. package/src/directive/events/events.html +0 -20
  405. package/src/directive/events/events.js +0 -65
  406. package/src/directive/events/events.md +0 -125
  407. package/src/directive/events/events.test.js +0 -12
  408. package/src/directive/form/form.html +0 -19
  409. package/src/directive/form/form.js +0 -669
  410. package/src/directive/form/form.spec.js +0 -1515
  411. package/src/directive/form/form.test.js +0 -12
  412. package/src/directive/http/delete.spec.js +0 -26
  413. package/src/directive/http/form-router-test.html +0 -44
  414. package/src/directive/http/form-test.html +0 -18
  415. package/src/directive/http/get.spec.js +0 -488
  416. package/src/directive/http/http.html +0 -22
  417. package/src/directive/http/http.js +0 -342
  418. package/src/directive/http/http.test.js +0 -12
  419. package/src/directive/http/post-example.html +0 -30
  420. package/src/directive/http/post.spec.js +0 -521
  421. package/src/directive/http/put.spec.js +0 -26
  422. package/src/directive/if/if-animate-css.html +0 -57
  423. package/src/directive/if/if-animate-svg.html +0 -25
  424. package/src/directive/if/if.html +0 -19
  425. package/src/directive/if/if.js +0 -72
  426. package/src/directive/if/if.md +0 -76
  427. package/src/directive/if/if.spec.js +0 -293
  428. package/src/directive/if/if.test.js +0 -114
  429. package/src/directive/include/include.html +0 -19
  430. package/src/directive/include/include.js +0 -151
  431. package/src/directive/include/include.md +0 -87
  432. package/src/directive/include/include.spec.js +0 -734
  433. package/src/directive/include/include.test.js +0 -12
  434. package/src/directive/init/init.html +0 -19
  435. package/src/directive/init/init.js +0 -22
  436. package/src/directive/init/init.md +0 -41
  437. package/src/directive/init/init.spec.js +0 -68
  438. package/src/directive/init/init.test.js +0 -12
  439. package/src/directive/input/input-example.html +0 -15
  440. package/src/directive/input/input.html +0 -19
  441. package/src/directive/input/input.js +0 -1078
  442. package/src/directive/input/input.md +0 -706
  443. package/src/directive/input/input.spec.js +0 -3700
  444. package/src/directive/input/input.test.js +0 -12
  445. package/src/directive/messages/messages.html +0 -22
  446. package/src/directive/messages/messages.js +0 -349
  447. package/src/directive/messages/messages.md +0 -543
  448. package/src/directive/messages/messages.spec.js +0 -1083
  449. package/src/directive/messages/messages.test.js +0 -12
  450. package/src/directive/model/change.md +0 -25
  451. package/src/directive/model/model.html +0 -19
  452. package/src/directive/model/model.js +0 -1170
  453. package/src/directive/model/model.spec.js +0 -1976
  454. package/src/directive/model/model.test.js +0 -12
  455. package/src/directive/model-options/model-option.test.js +0 -12
  456. package/src/directive/model-options/model-options.html +0 -22
  457. package/src/directive/model-options/model-options.js +0 -142
  458. package/src/directive/model-options/model-options.md +0 -407
  459. package/src/directive/model-options/model-options.spec.js +0 -1022
  460. package/src/directive/non-bindable/non-bindable.html +0 -22
  461. package/src/directive/non-bindable/non-bindable.js +0 -9
  462. package/src/directive/non-bindable/non-bindable.spec.js +0 -59
  463. package/src/directive/non-bindable/non-bindable.test.js +0 -12
  464. package/src/directive/observe/observe-demo.html +0 -184
  465. package/src/directive/observe/observe.html +0 -19
  466. package/src/directive/observe/observe.js +0 -41
  467. package/src/directive/observe/observe.spec.js +0 -106
  468. package/src/directive/observe/observe.test.js +0 -10
  469. package/src/directive/on/on.html +0 -19
  470. package/src/directive/on/on.spec.js +0 -215
  471. package/src/directive/on/on.test.js +0 -12
  472. package/src/directive/options/options-example.html +0 -17
  473. package/src/directive/options/options.html +0 -22
  474. package/src/directive/options/options.js +0 -542
  475. package/src/directive/options/options.md +0 -179
  476. package/src/directive/options/options.spec.js +0 -3554
  477. package/src/directive/options/options.test.js +0 -12
  478. package/src/directive/ref/href.html +0 -19
  479. package/src/directive/ref/href.spec.js +0 -141
  480. package/src/directive/ref/href.test.js +0 -19
  481. package/src/directive/ref/ref.html +0 -19
  482. package/src/directive/ref/ref.js +0 -89
  483. package/src/directive/ref/ref.spec.js +0 -546
  484. package/src/directive/repeat/repeat.html +0 -19
  485. package/src/directive/repeat/repeat.js +0 -333
  486. package/src/directive/repeat/repeat.md +0 -330
  487. package/src/directive/repeat/repeat.spec.js +0 -1209
  488. package/src/directive/repeat/repeat.test.js +0 -12
  489. package/src/directive/script/script.html +0 -19
  490. package/src/directive/script/script.js +0 -17
  491. package/src/directive/script/script.md +0 -11
  492. package/src/directive/script/script.spec.js +0 -47
  493. package/src/directive/script/script.test.js +0 -12
  494. package/src/directive/select/select.html +0 -19
  495. package/src/directive/select/select.js +0 -594
  496. package/src/directive/select/select.md +0 -74
  497. package/src/directive/select/select.spec.js +0 -2566
  498. package/src/directive/select/select.test.js +0 -12
  499. package/src/directive/setter/setter.html +0 -19
  500. package/src/directive/setter/setter.js +0 -59
  501. package/src/directive/setter/setter.spec.js +0 -100
  502. package/src/directive/setter/setter.test.js +0 -12
  503. package/src/directive/show-hide/show-hide.html +0 -22
  504. package/src/directive/show-hide/show-hide.js +0 -65
  505. package/src/directive/show-hide/show-hide.md +0 -255
  506. package/src/directive/show-hide/show-hide.spec.js +0 -268
  507. package/src/directive/show-hide/show-hide.test.js +0 -12
  508. package/src/directive/style/style.html +0 -19
  509. package/src/directive/style/style.js +0 -27
  510. package/src/directive/style/style.md +0 -23
  511. package/src/directive/style/style.spec.js +0 -183
  512. package/src/directive/style/style.test.js +0 -12
  513. package/src/directive/switch/switch.html +0 -19
  514. package/src/directive/switch/switch.js +0 -133
  515. package/src/directive/switch/switch.md +0 -66
  516. package/src/directive/switch/switch.spec.js +0 -509
  517. package/src/directive/switch/switch.test.js +0 -12
  518. package/src/directive/transclude/transclude.js +0 -122
  519. package/src/directive/validators/validators.html +0 -22
  520. package/src/directive/validators/validators.js +0 -346
  521. package/src/directive/validators/validators.spec.js +0 -740
  522. package/src/directive/validators/validators.test.js +0 -12
  523. package/src/filters/filter.js +0 -213
  524. package/src/filters/filter.md +0 -69
  525. package/src/filters/filter.spec.js +0 -719
  526. package/src/filters/filters.html +0 -22
  527. package/src/filters/filters.js +0 -239
  528. package/src/filters/filters.spec.js +0 -36
  529. package/src/filters/filters.test.js +0 -12
  530. package/src/filters/json.md +0 -16
  531. package/src/filters/limit-to.js +0 -55
  532. package/src/filters/limit-to.md +0 -19
  533. package/src/filters/limit-to.spec.js +0 -252
  534. package/src/filters/order-by.js +0 -181
  535. package/src/filters/order-by.md +0 -83
  536. package/src/filters/order-by.spec.js +0 -883
  537. package/src/index.js +0 -6
  538. package/src/index.spec.js +0 -11
  539. package/src/injection-tokens.js +0 -78
  540. package/src/interface.ts +0 -421
  541. package/src/ng.js +0 -289
  542. package/src/ng.spec.js +0 -33
  543. package/src/router/common/trace.js +0 -240
  544. package/src/router/directives/component-example.html +0 -37
  545. package/src/router/directives/state-directives.html +0 -22
  546. package/src/router/directives/state-directives.js +0 -393
  547. package/src/router/directives/state-directives.md +0 -435
  548. package/src/router/directives/state-directives.spec.js +0 -1091
  549. package/src/router/directives/state-directives.test.js +0 -10
  550. package/src/router/directives/view-directive.js +0 -489
  551. package/src/router/directives/view-directive.spec.js +0 -1937
  552. package/src/router/directives/view-directive.test.js +0 -10
  553. package/src/router/directives/view-directives.html +0 -22
  554. package/src/router/glob/glob.html +0 -19
  555. package/src/router/glob/glob.js +0 -102
  556. package/src/router/glob/glob.spec.js +0 -108
  557. package/src/router/glob/glob.test.js +0 -12
  558. package/src/router/hooks/core-resolvables.js +0 -38
  559. package/src/router/hooks/ignored-transition.js +0 -25
  560. package/src/router/hooks/invalid-transition.js +0 -14
  561. package/src/router/hooks/lazy-load.js +0 -104
  562. package/src/router/hooks/on-enter-exit-retain.js +0 -55
  563. package/src/router/hooks/redirect-to.js +0 -38
  564. package/src/router/hooks/resolve.js +0 -57
  565. package/src/router/hooks/update-globals.js +0 -34
  566. package/src/router/hooks/url.js +0 -34
  567. package/src/router/hooks/views.js +0 -41
  568. package/src/router/params/interface.ts +0 -626
  569. package/src/router/params/param-factory.js +0 -23
  570. package/src/router/params/param-type.js +0 -133
  571. package/src/router/params/param-types.js +0 -153
  572. package/src/router/params/param.js +0 -243
  573. package/src/router/params/state-params.js +0 -36
  574. package/src/router/path/path-node.js +0 -78
  575. package/src/router/path/path-utils.js +0 -207
  576. package/src/router/resolve/interface.ts +0 -208
  577. package/src/router/resolve/resolvable.js +0 -123
  578. package/src/router/resolve/resolve-context.js +0 -190
  579. package/src/router/router-test-hashbang.html +0 -45
  580. package/src/router/router-test.html +0 -41
  581. package/src/router/router.html +0 -22
  582. package/src/router/router.js +0 -54
  583. package/src/router/router.test.js +0 -12
  584. package/src/router/services.spec.js +0 -52
  585. package/src/router/state/README.md +0 -21
  586. package/src/router/state/interface.ts +0 -1007
  587. package/src/router/state/state-builder.js +0 -376
  588. package/src/router/state/state-builder.spec.js +0 -86
  589. package/src/router/state/state-matcher.js +0 -64
  590. package/src/router/state/state-object.js +0 -118
  591. package/src/router/state/state-queue-manager.js +0 -95
  592. package/src/router/state/state-registry.js +0 -257
  593. package/src/router/state/state-service.js +0 -699
  594. package/src/router/state/state.html +0 -23
  595. package/src/router/state/state.spec.js +0 -1002
  596. package/src/router/state/state.test.js +0 -12
  597. package/src/router/state/target-state.js +0 -162
  598. package/src/router/state/views.js +0 -195
  599. package/src/router/state-filter.spec.js +0 -139
  600. package/src/router/state-filters.js +0 -46
  601. package/src/router/template-factory.html +0 -19
  602. package/src/router/template-factory.js +0 -249
  603. package/src/router/template-factory.spec.js +0 -155
  604. package/src/router/template-factory.test.js +0 -12
  605. package/src/router/transition/hook-builder.js +0 -133
  606. package/src/router/transition/hook-registry.js +0 -172
  607. package/src/router/transition/interface.js +0 -18
  608. package/src/router/transition/interface.ts +0 -922
  609. package/src/router/transition/reject-factory.js +0 -122
  610. package/src/router/transition/transition-event-type.js +0 -26
  611. package/src/router/transition/transition-hook.js +0 -199
  612. package/src/router/transition/transition-service.js +0 -302
  613. package/src/router/transition/transition.js +0 -652
  614. package/src/router/url/url-config.js +0 -155
  615. package/src/router/url/url-matcher.js +0 -532
  616. package/src/router/url/url-rule.js +0 -231
  617. package/src/router/url/url-rules.js +0 -350
  618. package/src/router/url/url-service.js +0 -446
  619. package/src/router/url/url-service.spec.js +0 -1288
  620. package/src/router/url/url.html +0 -19
  621. package/src/router/url/url.test.js +0 -12
  622. package/src/router/view/interface.ts +0 -51
  623. package/src/router/view/view.html +0 -19
  624. package/src/router/view/view.js +0 -274
  625. package/src/router/view/view.spec.js +0 -100
  626. package/src/router/view/view.test.js +0 -12
  627. package/src/router/view-hook.spec.js +0 -215
  628. package/src/router/view-scroll.js +0 -33
  629. package/src/router/view-scroll.spec.js +0 -72
  630. package/src/services/anchor-scroll.html +0 -76
  631. package/src/services/anchor-scroll.js +0 -147
  632. package/src/services/cookie-reader.js +0 -48
  633. package/src/services/exception/exception-handler.js +0 -75
  634. package/src/services/exception/interface.ts +0 -7
  635. package/src/services/http/http.html +0 -23
  636. package/src/services/http/http.js +0 -922
  637. package/src/services/http/http.md +0 -413
  638. package/src/services/http/http.spec.js +0 -3941
  639. package/src/services/http/http.test.js +0 -11
  640. package/src/services/http/interface.ts +0 -243
  641. package/src/services/http/template-request.spec.js +0 -220
  642. package/src/services/http-backend/http-backend.html +0 -22
  643. package/src/services/http-backend/http-backend.js +0 -158
  644. package/src/services/http-backend/http-backend.spec.js +0 -389
  645. package/src/services/http-backend/http-backend.test.js +0 -12
  646. package/src/services/location/interface.ts +0 -70
  647. package/src/services/location/location.html +0 -22
  648. package/src/services/location/location.js +0 -1006
  649. package/src/services/location/location.spec.js +0 -3792
  650. package/src/services/location/location.test.js +0 -12
  651. package/src/services/log/interface.ts +0 -39
  652. package/src/services/log/log.html +0 -19
  653. package/src/services/log/log.js +0 -74
  654. package/src/services/log/log.spec.js +0 -64
  655. package/src/services/log/log.test.js +0 -12
  656. package/src/services/pubsub/pubsub.html +0 -19
  657. package/src/services/pubsub/pubsub.js +0 -349
  658. package/src/services/pubsub/pubsub.spec.js +0 -400
  659. package/src/services/pubsub/pubsub.test.js +0 -12
  660. package/src/services/sce/sce.html +0 -19
  661. package/src/services/sce/sce.js +0 -847
  662. package/src/services/sce/sce.md +0 -300
  663. package/src/services/sce/sce.spec.js +0 -617
  664. package/src/services/sce/sce.test.js +0 -12
  665. package/src/services/template-cache/interface.ts +0 -10
  666. package/src/services/template-cache/template-cache.html +0 -22
  667. package/src/services/template-cache/template-cache.js +0 -15
  668. package/src/services/template-cache/template-cache.spec.js +0 -134
  669. package/src/services/template-cache/template-cache.test.js +0 -12
  670. package/src/services/template-request.js +0 -142
  671. package/src/shared/cache.js +0 -7
  672. package/src/shared/common.js +0 -438
  673. package/src/shared/common.spec.js +0 -294
  674. package/src/shared/constants.js +0 -21
  675. package/src/shared/dom.js +0 -716
  676. package/src/shared/hof.js +0 -151
  677. package/src/shared/hof.spec.js +0 -60
  678. package/src/shared/interface.ts +0 -21
  679. package/src/shared/min-err.spec.js +0 -178
  680. package/src/shared/noderef.js +0 -225
  681. package/src/shared/predicates.js +0 -34
  682. package/src/shared/queue.js +0 -105
  683. package/src/shared/queue.spec.js +0 -80
  684. package/src/shared/shared.html +0 -24
  685. package/src/shared/shared.test.js +0 -12
  686. package/src/shared/strings.js +0 -142
  687. package/src/shared/strings.spec.js +0 -40
  688. package/src/shared/test-utils.js +0 -47
  689. package/src/shared/url-utils/interface.ts +0 -54
  690. package/src/shared/url-utils/url-utils.html +0 -22
  691. package/src/shared/url-utils/url-utils.js +0 -122
  692. package/src/shared/url-utils/url-utils.spec.js +0 -148
  693. package/src/shared/url-utils/url-utils.test.js +0 -12
  694. package/src/shared/utils.js +0 -1255
  695. package/src/shared/utils.spec.js +0 -178
  696. package/src/src.html +0 -21
  697. package/src/src.test.js +0 -10
  698. package/tsconfig.json +0 -19
  699. package/tsconfig.types.json +0 -14
  700. package/typedoc.json +0 -8
  701. package/utils/express.js +0 -203
  702. package/utils/version.cjs +0 -23
  703. package/vite.config.js +0 -14
@@ -1,1976 +0,0 @@
1
- import { createElementFromHTML, dealoc } from "../../shared/dom.js";
2
- import { Angular } from "../../angular.js";
3
- import { NgModelController } from "./model.js";
4
- import { isDefined, isObject } from "../../shared/utils.js";
5
- import { browserTrigger, wait } from "../../shared/test-utils.js";
6
-
7
- describe("ngModel", () => {
8
- let ctrl;
9
- let scope;
10
- let element;
11
- let parentFormCtrl;
12
- let $compile;
13
- let injector;
14
- let $rootScope;
15
- let errors = [];
16
- let app = document.getElementById("app");
17
-
18
- beforeEach(() => {
19
- errors = [];
20
- dealoc(document.getElementById("app"));
21
- window.angular = new Angular();
22
- window.angular
23
- .module("myModule", ["ng"])
24
- .decorator("$exceptionHandler", function () {
25
- return (exception) => {
26
- errors.push(exception.message);
27
- };
28
- });
29
- injector = window.angular.bootstrap(document.getElementById("app"), [
30
- "myModule",
31
- ]);
32
- $compile = injector.get("$compile");
33
-
34
- const attrs = { name: "testAlias", ngModel: "value" };
35
-
36
- parentFormCtrl = {
37
- $$setPending: jasmine.createSpy("$$setPending"),
38
- $setValidity: jasmine.createSpy("$setValidity"),
39
- $setDirty: jasmine.createSpy("$setDirty"),
40
- $$clearControlValidity: () => {},
41
- };
42
-
43
- element = createElementFromHTML("<form><input></form>");
44
- let $controller = injector.get("$controller");
45
- scope = injector.get("$rootScope");
46
- $rootScope = scope;
47
- ctrl = $controller(NgModelController, {
48
- $scope: scope,
49
- $element: element.querySelector("input"),
50
- $attrs: attrs,
51
- });
52
-
53
- // Assign the mocked parentFormCtrl to the model controller
54
- ctrl.$$parentForm = parentFormCtrl;
55
- });
56
-
57
- afterEach(() => {
58
- dealoc(element);
59
- });
60
-
61
- describe("NgModelController", () => {
62
- it("should init the properties", () => {
63
- expect(ctrl.$untouched).toBe(true);
64
- expect(ctrl.$touched).toBe(false);
65
- expect(ctrl.$dirty).toBe(false);
66
- expect(ctrl.$pristine).toBe(true);
67
- expect(ctrl.$valid).toBe(true);
68
- expect(ctrl.$invalid).toBe(false);
69
-
70
- expect(ctrl.$viewValue).toBeDefined();
71
- expect(ctrl.$modelValue).toBeDefined();
72
-
73
- expect(ctrl.$formatters).toEqual([]);
74
- expect(ctrl.$parsers).toEqual([]);
75
-
76
- expect(ctrl.$name).toBe("testAlias");
77
- });
78
-
79
- describe("setValidity", () => {
80
- function expectOneError() {
81
- expect(ctrl.$error).toEqual({ someError: true });
82
- expect(ctrl.$$success).toEqual({});
83
- expect(ctrl.$pending).toBeUndefined();
84
- }
85
-
86
- function expectOneSuccess() {
87
- expect(ctrl.$error).toEqual({});
88
- expect(ctrl.$$success).toEqual({ someError: true });
89
- expect(ctrl.$pending).toBeUndefined();
90
- }
91
-
92
- function expectOnePending() {
93
- expect(ctrl.$error).toEqual({});
94
- expect(ctrl.$$success).toEqual({});
95
- expect(ctrl.$pending).toEqual({ someError: true });
96
- }
97
-
98
- function expectCleared() {
99
- expect(ctrl.$error).toEqual({});
100
- expect(ctrl.$$success).toEqual({});
101
- expect(ctrl.$pending).toBeUndefined();
102
- }
103
-
104
- it("should propagate validity to the parent form", () => {
105
- expect(parentFormCtrl.$setValidity).not.toHaveBeenCalled();
106
- ctrl.$setValidity("ERROR", false);
107
- expect(parentFormCtrl.$setValidity).toHaveBeenCalledOnceWith(
108
- "ERROR",
109
- false,
110
- ctrl,
111
- );
112
- });
113
-
114
- it("should transition from states correctly", () => {
115
- expectCleared();
116
-
117
- ctrl.$setValidity("someError", false);
118
- expectOneError();
119
-
120
- ctrl.$setValidity("someError", undefined);
121
- expectOnePending();
122
-
123
- ctrl.$setValidity("someError", true);
124
- expectOneSuccess();
125
-
126
- ctrl.$setValidity("someError", null);
127
- expectCleared();
128
- });
129
-
130
- it("should set valid/invalid with multiple errors", () => {
131
- ctrl.$setValidity("first", false);
132
- expect(ctrl.$valid).toBe(false);
133
- expect(ctrl.$invalid).toBe(true);
134
-
135
- ctrl.$setValidity("second", false);
136
- expect(ctrl.$valid).toBe(false);
137
- expect(ctrl.$invalid).toBe(true);
138
-
139
- ctrl.$setValidity("third", undefined);
140
- expect(ctrl.$valid).toBeUndefined();
141
- expect(ctrl.$invalid).toBeUndefined();
142
-
143
- ctrl.$setValidity("third", null);
144
- expect(ctrl.$valid).toBe(false);
145
- expect(ctrl.$invalid).toBe(true);
146
-
147
- ctrl.$setValidity("second", true);
148
- expect(ctrl.$valid).toBe(false);
149
- expect(ctrl.$invalid).toBe(true);
150
-
151
- ctrl.$setValidity("first", true);
152
- expect(ctrl.$valid).toBe(true);
153
- expect(ctrl.$invalid).toBe(false);
154
- });
155
- });
156
-
157
- describe("setPristine", () => {
158
- it("should set control to its pristine state", () => {
159
- ctrl.$setViewValue("edit");
160
- expect(ctrl.$dirty).toBe(true);
161
- expect(ctrl.$pristine).toBe(false);
162
-
163
- ctrl.$setPristine();
164
- expect(ctrl.$dirty).toBe(false);
165
- expect(ctrl.$pristine).toBe(true);
166
- });
167
- });
168
-
169
- describe("setDirty", () => {
170
- it("should set control to its dirty state", () => {
171
- expect(ctrl.$pristine).toBe(true);
172
- expect(ctrl.$dirty).toBe(false);
173
-
174
- ctrl.$setDirty();
175
- expect(ctrl.$pristine).toBe(false);
176
- expect(ctrl.$dirty).toBe(true);
177
- });
178
-
179
- it("should set parent form to its dirty state", () => {
180
- ctrl.$setDirty();
181
- expect(parentFormCtrl.$setDirty).toHaveBeenCalled();
182
- });
183
- });
184
-
185
- describe("setUntouched", () => {
186
- it("should set control to its untouched state", () => {
187
- ctrl.$setTouched();
188
-
189
- ctrl.$setUntouched();
190
- expect(ctrl.$touched).toBe(false);
191
- expect(ctrl.$untouched).toBe(true);
192
- });
193
- });
194
-
195
- describe("setTouched", () => {
196
- it("should set control to its touched state", () => {
197
- ctrl.$setUntouched();
198
-
199
- ctrl.$setTouched();
200
- expect(ctrl.$touched).toBe(true);
201
- expect(ctrl.$untouched).toBe(false);
202
- });
203
- });
204
-
205
- describe("view -> model", () => {
206
- it("should set the value to $viewValue", () => {
207
- ctrl.$setViewValue("some-val");
208
- expect(ctrl.$viewValue).toBe("some-val");
209
- });
210
-
211
- it("should pipeline all registered parsers and set result to $modelValue", () => {
212
- const log = [];
213
-
214
- ctrl.$parsers.push((value) => {
215
- log.push(value);
216
- return `${value}-a`;
217
- });
218
-
219
- ctrl.$parsers.push((value) => {
220
- log.push(value);
221
- return `${value}-b`;
222
- });
223
-
224
- ctrl.$setViewValue("init");
225
- expect(log).toEqual(["init", "init-a"]);
226
- expect(ctrl.$modelValue).toBe("init-a-b");
227
- });
228
-
229
- it("should fire viewChangeListeners when the value changes in the view (even if invalid)", () => {
230
- const spy = jasmine.createSpy("viewChangeListener");
231
- ctrl.$viewChangeListeners.push(spy);
232
- ctrl.$setViewValue("val");
233
- expect(spy).toHaveBeenCalled();
234
- spy.calls.reset();
235
-
236
- // invalid
237
- ctrl.$parsers.push(() => undefined);
238
- ctrl.$setViewValue("val2");
239
- expect(spy).toHaveBeenCalled();
240
- });
241
-
242
- it("should reset the model when the view is invalid", () => {
243
- ctrl.$setViewValue("aaaa");
244
- expect(ctrl.$modelValue).toBe("aaaa");
245
-
246
- // add a validator that will make any input invalid
247
- ctrl.$parsers.push(() => undefined);
248
- expect(ctrl.$modelValue).toBe("aaaa");
249
- ctrl.$setViewValue("bbbb");
250
- expect(ctrl.$modelValue).toBeUndefined();
251
- });
252
-
253
- it("should not reset the model when the view is invalid due to an external validator", () => {
254
- ctrl.$setViewValue("aaaa");
255
- expect(ctrl.$modelValue).toBe("aaaa");
256
-
257
- ctrl.$setValidity("someExternalError", false);
258
- ctrl.$setViewValue("bbbb");
259
- expect(ctrl.$modelValue).toBe("bbbb");
260
- });
261
-
262
- it("should not reset the view when the view is invalid", async () => {
263
- // add a validator that will make any input invalid
264
- ctrl.$parsers.push(() => undefined);
265
- spyOn(ctrl, "$render");
266
-
267
- // first digest
268
- ctrl.$setViewValue("bbbb");
269
- expect(ctrl.$modelValue).toBeUndefined();
270
- expect(ctrl.$viewValue).toBe("bbbb");
271
- expect(ctrl.$render).not.toHaveBeenCalled();
272
- expect(scope.value).toBeUndefined();
273
-
274
- // further digests
275
- scope.$apply('value = "aaa"');
276
- await wait();
277
-
278
- expect(ctrl.$viewValue).toBe("aaa");
279
- ctrl.$render.calls.reset();
280
-
281
- ctrl.$setViewValue("cccc");
282
- expect(ctrl.$modelValue).toBeUndefined();
283
- expect(ctrl.$viewValue).toBe("cccc");
284
- expect(ctrl.$render).not.toHaveBeenCalled();
285
- expect(scope.value).toBeUndefined();
286
- });
287
-
288
- it("should call parentForm.$setDirty only when pristine", () => {
289
- ctrl.$setViewValue("");
290
- expect(ctrl.$pristine).toBe(false);
291
- expect(ctrl.$dirty).toBe(true);
292
- expect(parentFormCtrl.$setDirty).toHaveBeenCalled();
293
-
294
- parentFormCtrl.$setDirty.calls.reset();
295
- ctrl.$setViewValue("");
296
- expect(ctrl.$pristine).toBe(false);
297
- expect(ctrl.$dirty).toBe(true);
298
- expect(parentFormCtrl.$setDirty).not.toHaveBeenCalled();
299
- });
300
-
301
- it("should remove all other errors when any parser returns undefined", () => {
302
- let a;
303
- let b;
304
- const val = function (val, x) {
305
- return x ? val : x;
306
- };
307
-
308
- ctrl.$parsers.push((v) => val(v, a));
309
- ctrl.$parsers.push((v) => val(v, b));
310
-
311
- ctrl.$validators.high = function (value) {
312
- return !isDefined(value) || value > 5;
313
- };
314
-
315
- ctrl.$validators.even = function (value) {
316
- return !isDefined(value) || value % 2 === 0;
317
- };
318
-
319
- a = b = true;
320
-
321
- ctrl.$setViewValue("3");
322
- expect(ctrl.$error).toEqual({ high: true, even: true });
323
-
324
- ctrl.$setViewValue("10");
325
- expect(ctrl.$error).toEqual({});
326
-
327
- a = undefined;
328
-
329
- ctrl.$setViewValue("12");
330
- expect(ctrl.$error).toEqual({ parse: true });
331
-
332
- a = true;
333
- b = undefined;
334
-
335
- ctrl.$setViewValue("14");
336
- expect(ctrl.$error).toEqual({ parse: true });
337
-
338
- a = undefined;
339
- b = undefined;
340
-
341
- ctrl.$setViewValue("16");
342
- expect(ctrl.$error).toEqual({ parse: true });
343
-
344
- a = b = false; // not undefined
345
-
346
- ctrl.$setViewValue("2");
347
- expect(ctrl.$error).toEqual({ high: true });
348
- });
349
-
350
- it("should not remove external validators when a parser failed", () => {
351
- ctrl.$parsers.push((v) => undefined);
352
- ctrl.$setValidity("externalError", false);
353
- ctrl.$setViewValue("someValue");
354
- expect(ctrl.$error).toEqual({ externalError: true, parse: true });
355
- });
356
-
357
- it("should remove all non-parse-related CSS classes from the form when a parser fails", () => {
358
- const element = $compile(
359
- '<form name="myForm">' +
360
- '<input name="myControl" ng-model="value" >' +
361
- "</form>",
362
- )($rootScope);
363
- const inputElm = element.querySelector("input");
364
- const ctrl = $rootScope.myForm.myControl;
365
-
366
- let parserIsFailing = false;
367
- ctrl.$parsers.push((value) => (parserIsFailing ? undefined : value));
368
-
369
- ctrl.$validators.alwaysFail = function () {
370
- return false;
371
- };
372
-
373
- ctrl.$setViewValue("123");
374
- expect(element.classList.contains("ng-valid-parse")).toBeTrue();
375
- expect(element.classList.contains("ng-invalid-parse")).toBeFalse();
376
- expect(element.classList.contains("ng-invalid-always-fail")).toBeTrue();
377
-
378
- parserIsFailing = true;
379
- ctrl.$setViewValue("12345");
380
- expect(element.classList.contains("ng-valid-parse")).toBeFalse();
381
- expect(element.classList.contains("ng-invalid-parse")).toBeTrue();
382
- expect(
383
- element.classList.contains("ng-invalid-always-fail"),
384
- ).toBeFalse();
385
- dealoc(element);
386
- });
387
-
388
- it("should set the ng-invalid-parse and ng-valid-parse CSS class when parsers fail and pass", () => {
389
- let pass = true;
390
- ctrl.$parsers.push((v) => (pass ? v : undefined));
391
-
392
- const input = element.querySelector("input");
393
-
394
- ctrl.$setViewValue("1");
395
- expect(input.classList.contains("ng-valid-parse")).toBeTrue();
396
- expect(input.classList.contains("ng-invalid-parse")).toBeFalse();
397
-
398
- pass = undefined;
399
-
400
- ctrl.$setViewValue("2");
401
- expect(input.classList.contains("ng-valid-parse")).toBeFalse();
402
- expect(input.classList.contains("ng-invalid-parse")).toBeTrue();
403
- });
404
-
405
- it("should update the model after all async validators resolve", async () => {
406
- let defer = Promise.withResolvers();
407
- ctrl.$asyncValidators.promiseValidator = function (value) {
408
- return defer.promise;
409
- };
410
-
411
- // set view value on first digest
412
- ctrl.$setViewValue("b");
413
-
414
- expect(ctrl.$modelValue).toBeUndefined();
415
- expect(scope.value).toBeUndefined();
416
-
417
- defer.resolve();
418
- await wait();
419
- expect(ctrl.$modelValue).toBe("b");
420
- expect(scope.value).toBe("b");
421
-
422
- // // set view value on further digests
423
- ctrl.$setViewValue("c");
424
-
425
- expect(ctrl.$modelValue).toBe("b");
426
- expect(scope.value).toBe("b");
427
-
428
- defer.resolve();
429
- await wait();
430
- expect(ctrl.$modelValue).toBe("c");
431
- expect(scope.value).toBe("c");
432
- });
433
-
434
- it("should not throw an error if the scope has been destroyed", () => {
435
- scope.$destroy();
436
- ctrl.$setViewValue("some-val");
437
- expect(ctrl.$viewValue).toBe("some-val");
438
- });
439
- });
440
-
441
- describe("model -> view", () => {
442
- it("should set the value to $modelValue", async () => {
443
- scope.$apply("value = 10");
444
- await wait();
445
- expect(ctrl.$modelValue).toBe(10);
446
- });
447
-
448
- it("should pipeline all registered formatters in reversed order and set result to $viewValue", async () => {
449
- const log = [];
450
-
451
- ctrl.$formatters.unshift((value) => {
452
- log.push(value);
453
- return value + 2;
454
- });
455
-
456
- ctrl.$formatters.unshift((value) => {
457
- log.push(value);
458
- return `${value}`;
459
- });
460
-
461
- scope.$apply("value = 3");
462
- await wait();
463
- expect(log).toEqual([3, 5]);
464
- expect(ctrl.$viewValue).toBe("5");
465
- });
466
-
467
- it("should $render only if value changed", async () => {
468
- spyOn(ctrl, "$render");
469
-
470
- scope.$apply("value = 3");
471
- await wait();
472
- expect(ctrl.$render).toHaveBeenCalled();
473
- ctrl.$render.calls.reset();
474
-
475
- ctrl.$formatters.push(() => 3);
476
- scope.$apply("value = 5");
477
- await wait();
478
- expect(ctrl.$render).not.toHaveBeenCalled();
479
- });
480
-
481
- it("should clear the view even if invalid", async () => {
482
- spyOn(ctrl, "$render");
483
-
484
- ctrl.$formatters.push(() => undefined);
485
- scope.$apply("value = 5");
486
- await wait();
487
- expect(ctrl.$render).toHaveBeenCalled();
488
- });
489
-
490
- it("should render immediately even if there are async validators", async () => {
491
- spyOn(ctrl, "$render");
492
- let defer = Promise.withResolvers();
493
- ctrl.$asyncValidators.someValidator = function () {
494
- return defer.promise;
495
- };
496
-
497
- scope.$apply("value = 5");
498
- await wait();
499
- expect(ctrl.$viewValue).toBe(5);
500
- expect(ctrl.$render).toHaveBeenCalled();
501
- });
502
-
503
- it("should not rerender nor validate in case view value is not changed", async () => {
504
- ctrl.$formatters.push((value) => "nochange");
505
-
506
- spyOn(ctrl, "$render");
507
- ctrl.$validators.spyValidator = jasmine.createSpy("spyValidator");
508
- scope.$apply('value = "first"');
509
- scope.$apply('value = "second"');
510
- await wait();
511
- expect(ctrl.$validators.spyValidator).toHaveBeenCalled();
512
- expect(ctrl.$render).toHaveBeenCalled();
513
- });
514
-
515
- it("should always format the viewValue as a string for a blank input type when the value is present", async () => {
516
- const form = $compile(
517
- '<form name="form"><input name="field" ng-model="val" /></form>',
518
- )($rootScope);
519
-
520
- $rootScope.val = 123;
521
- await wait();
522
- expect($rootScope.form.field.$viewValue).toBe("123");
523
-
524
- $rootScope.val = null;
525
- await wait();
526
- expect($rootScope.form.field.$viewValue).toBe(null);
527
-
528
- dealoc(form);
529
- });
530
-
531
- it("should always format the viewValue as a string for a `text` input type when the value is present", async () => {
532
- const form = $compile(
533
- '<form name="form"><input type="text" name="field" ng-model="val" /></form>',
534
- )($rootScope);
535
- $rootScope.val = 123;
536
- await wait();
537
-
538
- expect($rootScope.form.field.$viewValue).toBe("123");
539
-
540
- $rootScope.val = null;
541
- await wait();
542
-
543
- expect($rootScope.form.field.$viewValue).toBe(null);
544
-
545
- dealoc(form);
546
- });
547
-
548
- it("should always format the viewValue as a string for an `email` input type when the value is present", async () => {
549
- const form = $compile(
550
- '<form name="form"><input type="email" name="field" ng-model="val" /></form>',
551
- )($rootScope);
552
- $rootScope.val = 123;
553
- await wait();
554
-
555
- expect($rootScope.form.field.$viewValue).toBe("123");
556
-
557
- $rootScope.val = null;
558
- await wait();
559
- expect($rootScope.form.field.$viewValue).toBe(null);
560
-
561
- dealoc(form);
562
- });
563
-
564
- it("should always format the viewValue as a string for a `url` input type when the value is present", async () => {
565
- const form = $compile(
566
- '<form name="form"><input type="url" name="field" ng-model="val" /></form>',
567
- )($rootScope);
568
- $rootScope.val = 123;
569
- await wait();
570
-
571
- expect($rootScope.form.field.$viewValue).toBe("123");
572
-
573
- $rootScope.val = null;
574
- await wait();
575
-
576
- expect($rootScope.form.field.$viewValue).toBe(null);
577
-
578
- dealoc(form);
579
- });
580
-
581
- it("should set NaN as the $modelValue when an asyncValidator is present", async () => {
582
- let defer = Promise.withResolvers();
583
- ctrl.$asyncValidators.test = function () {
584
- return defer.promise;
585
- };
586
-
587
- scope.$apply("value = 10");
588
- defer.resolve();
589
- await wait();
590
-
591
- expect(ctrl.$modelValue).toBe(10);
592
-
593
- scope.value = NaN;
594
- await wait();
595
- expect(ctrl.$modelValue).toBeNaN();
596
- });
597
-
598
- describe("$processModelValue", () => {
599
- // Emulate setting the model on the scope
600
- function setModelValue(ctrl, value) {
601
- ctrl.$modelValue = ctrl.$$rawModelValue = value;
602
- ctrl.$$parserValid = undefined;
603
- }
604
-
605
- it("should run the model -> view pipeline", () => {
606
- const log = [];
607
- const input = ctrl.$$element;
608
-
609
- ctrl.$formatters.unshift((value) => {
610
- log.push(value);
611
- return value + 2;
612
- });
613
-
614
- ctrl.$formatters.unshift((value) => {
615
- log.push(value);
616
- return `${value}`;
617
- });
618
-
619
- spyOn(ctrl, "$render");
620
-
621
- setModelValue(ctrl, 3);
622
-
623
- expect(ctrl.$modelValue).toBe(3);
624
-
625
- ctrl.$processModelValue();
626
-
627
- expect(ctrl.$modelValue).toBe(3);
628
- expect(log).toEqual([3, 5]);
629
- expect(ctrl.$viewValue).toBe("5");
630
- expect(ctrl.$render).toHaveBeenCalled();
631
- });
632
-
633
- it("should add the validation and empty-state classes", async () => {
634
- const input = $compile(
635
- '<input name="myControl" maxlength="1" ng-model="value" >',
636
- )($rootScope);
637
- await wait();
638
-
639
- //const ctrl = getController(input, "ngModel");
640
-
641
- expect(input.classList.contains("ng-empty")).toBeTrue();
642
- expect(input.classList.contains("ng-valid")).toBeTrue();
643
-
644
- // setModelValue(ctrl, 3);
645
- // ctrl.$processModelValue();
646
-
647
- // // $animate adds / removes classes in the $postUpdate, which
648
- // // we cannot trigger with $digest, because that would set the model from the scope,
649
- // // so we simply check if the functions have been called
650
- // expect($animate.removeClass.calls.mostRecent().args[0][0]).toBe(
651
- // input[0],
652
- // );
653
- // expect($animate.removeClass.calls.mostRecent().args[1]).toBe(
654
- // "ng-empty",
655
- // );
656
-
657
- // expect($animate.addClass.calls.mostRecent().args[0][0]).toBe(
658
- // input[0],
659
- // );
660
- // expect($animate.addClass.calls.mostRecent().args[1]).toBe(
661
- // "ng-not-empty",
662
- // );
663
-
664
- // $animate.removeClass.calls.reset();
665
- // $animate.addClass.calls.reset();
666
-
667
- // setModelValue(ctrl, 35);
668
- // ctrl.$processModelValue();
669
-
670
- // expect($animate.addClass.calls.argsFor(1)[0][0]).toBe(input[0]);
671
- // expect($animate.addClass.calls.argsFor(1)[1]).toBe("ng-invalid");
672
-
673
- // expect($animate.addClass.calls.argsFor(2)[0][0]).toBe(input[0]);
674
- // expect($animate.addClass.calls.argsFor(2)[1]).toBe(
675
- // "ng-invalid-maxlength",
676
- // );
677
- });
678
-
679
- // this is analogue to $setViewValue
680
- it("should run the model -> view pipeline even if the value has not changed", () => {
681
- const log = [];
682
-
683
- ctrl.$formatters.unshift((value) => {
684
- log.push(value);
685
- return value + 2;
686
- });
687
-
688
- ctrl.$formatters.unshift((value) => {
689
- log.push(value);
690
- return `${value}`;
691
- });
692
-
693
- spyOn(ctrl, "$render");
694
-
695
- setModelValue(ctrl, 3);
696
- ctrl.$processModelValue();
697
-
698
- expect(ctrl.$modelValue).toBe(3);
699
- expect(ctrl.$viewValue).toBe("5");
700
- expect(log).toEqual([3, 5]);
701
- expect(ctrl.$render).toHaveBeenCalled();
702
-
703
- ctrl.$processModelValue();
704
- expect(ctrl.$modelValue).toBe(3);
705
- expect(ctrl.$viewValue).toBe("5");
706
- expect(log).toEqual([3, 5, 3, 5]);
707
- // $render() is not called if the viewValue didn't change
708
- expect(ctrl.$render).toHaveBeenCalled();
709
- });
710
- });
711
- });
712
-
713
- describe("validation", () => {
714
- describe("$validate", () => {
715
- it("should perform validations when $validate() is called", async () => {
716
- scope.$apply('value = ""');
717
- await wait();
718
- let validatorResult = false;
719
- ctrl.$validators.someValidator = function (value) {
720
- return validatorResult;
721
- };
722
-
723
- ctrl.$validate();
724
-
725
- expect(ctrl.$valid).toBe(false);
726
-
727
- validatorResult = true;
728
- ctrl.$validate();
729
-
730
- expect(ctrl.$valid).toBe(true);
731
- });
732
-
733
- it("should pass the last parsed modelValue to the validators", () => {
734
- ctrl.$parsers.push((modelValue) => `${modelValue}def`);
735
-
736
- ctrl.$setViewValue("abc");
737
-
738
- ctrl.$validators.test = function (modelValue, viewValue) {
739
- return true;
740
- };
741
-
742
- spyOn(ctrl.$validators, "test");
743
-
744
- ctrl.$validate();
745
-
746
- expect(ctrl.$validators.test).toHaveBeenCalledWith("abcdef", "abc");
747
- });
748
-
749
- it("should set the model to undefined when it becomes invalid", async () => {
750
- let valid = true;
751
- ctrl.$validators.test = function (modelValue, viewValue) {
752
- return valid;
753
- };
754
-
755
- scope.$apply('value = "abc"');
756
- await wait();
757
- expect(scope.value).toBe("abc");
758
-
759
- valid = false;
760
- ctrl.$validate();
761
-
762
- expect(scope.value).toBeUndefined();
763
- });
764
-
765
- it("should update the model when it becomes valid", async () => {
766
- let valid = true;
767
- ctrl.$validators.test = function (modelValue, viewValue) {
768
- return valid;
769
- };
770
-
771
- scope.$apply('value = "abc"');
772
- await wait();
773
- expect(scope.value).toBe("abc");
774
-
775
- valid = false;
776
- ctrl.$validate();
777
- expect(scope.value).toBeUndefined();
778
-
779
- valid = true;
780
- ctrl.$validate();
781
- expect(scope.value).toBe("abc");
782
- });
783
-
784
- it("should not update the model when it is valid, but there is a parse error", async () => {
785
- ctrl.$parsers.push((modelValue) => undefined);
786
-
787
- ctrl.$setViewValue("abc");
788
- expect(ctrl.$error.parse).toBe(true);
789
- expect(scope.value).toBeUndefined();
790
-
791
- ctrl.$validators.test = function (modelValue, viewValue) {
792
- return true;
793
- };
794
-
795
- ctrl.$validate();
796
- expect(ctrl.$error).toEqual({ parse: true });
797
- expect(scope.value).toBeUndefined();
798
- });
799
-
800
- it("should not set an invalid model to undefined when validity is the same", async () => {
801
- ctrl.$validators.test = function () {
802
- return false;
803
- };
804
-
805
- scope.$apply('value = "invalid"');
806
- await wait();
807
- expect(ctrl.$valid).toBe(false);
808
- expect(scope.value).toBe("invalid");
809
-
810
- ctrl.$validate();
811
- expect(ctrl.$valid).toBe(false);
812
- expect(scope.value).toBe("invalid");
813
- });
814
-
815
- it("should not change a model that has a formatter", async () => {
816
- ctrl.$validators.test = function () {
817
- return true;
818
- };
819
-
820
- ctrl.$formatters.push((modelValue) => "xyz");
821
-
822
- scope.$apply('value = "abc"');
823
- await wait();
824
- expect(ctrl.$viewValue).toBe("xyz");
825
-
826
- ctrl.$validate();
827
- expect(scope.value).toBe("abc");
828
- });
829
-
830
- it("should not change a model that has a parser", async () => {
831
- ctrl.$validators.test = function () {
832
- return true;
833
- };
834
-
835
- ctrl.$parsers.push((modelValue) => "xyz");
836
-
837
- scope.$apply('value = "abc"');
838
- await wait();
839
-
840
- ctrl.$validate();
841
- expect(scope.value).toBe("abc");
842
- });
843
- });
844
-
845
- describe("view -> model update", () => {
846
- it("should always perform validations using the parsed model value", () => {
847
- let captures;
848
- ctrl.$validators.raw = function () {
849
- captures = Array.prototype.slice.call(arguments);
850
- return captures[0];
851
- };
852
-
853
- ctrl.$parsers.push((value) => value.toUpperCase());
854
-
855
- ctrl.$setViewValue("my-value");
856
-
857
- expect(captures).toEqual(["MY-VALUE", "my-value"]);
858
- });
859
-
860
- it("should always perform validations using the formatted view value", async () => {
861
- let captures;
862
- ctrl.$validators.raw = function () {
863
- captures = Array.prototype.slice.call(arguments);
864
- return captures[0];
865
- };
866
-
867
- ctrl.$formatters.push((value) => `${value}...`);
868
-
869
- scope.$apply('value = "matias"');
870
- await wait();
871
- expect(captures).toEqual(["matias", "matias..."]);
872
- });
873
-
874
- it("should only perform validations if the view value is different", async () => {
875
- let count = 0;
876
- ctrl.$validators.countMe = function () {
877
- count++;
878
- };
879
-
880
- ctrl.$setViewValue("my-value");
881
- expect(count).toBe(1);
882
-
883
- ctrl.$setViewValue("my-value");
884
- expect(count).toBe(1);
885
-
886
- ctrl.$setViewValue("your-value");
887
- expect(count).toBe(2);
888
- });
889
- });
890
-
891
- it("should perform validations twice each time the model value changes within a digest", async () => {
892
- let count = 0;
893
- ctrl.$validators.number = function (value) {
894
- count++;
895
- return /^\d+$/.test(value);
896
- };
897
-
898
- scope.$apply('value = ""');
899
- await wait();
900
- expect(count).toBe(1);
901
-
902
- scope.$apply("value = 1");
903
- await wait();
904
- expect(count).toBe(2);
905
-
906
- scope.$apply("value = 1");
907
- await wait();
908
- expect(count).toBe(2);
909
-
910
- scope.$apply('value = ""');
911
- await wait();
912
- expect(count).toBe(3);
913
- });
914
-
915
- it("should only validate to true if all validations are true", () => {
916
- ctrl.$modelValue = undefined;
917
- ctrl.$validators.a = () => true;
918
- ctrl.$validators.b = () => true;
919
- ctrl.$validators.c = () => false;
920
-
921
- ctrl.$validate();
922
- expect(ctrl.$valid).toBe(false);
923
-
924
- ctrl.$validators.c = () => true;
925
-
926
- ctrl.$validate();
927
- expect(ctrl.$valid).toBe(true);
928
- });
929
-
930
- it("should treat all responses as boolean for synchronous validators", () => {
931
- const expectValid = function (value, expected) {
932
- ctrl.$modelValue = undefined;
933
- ctrl.$validators.a = () => value;
934
-
935
- ctrl.$validate();
936
- expect(ctrl.$valid).toBe(expected);
937
- };
938
-
939
- // False tests
940
- expectValid(false, false);
941
- expectValid(undefined, false);
942
- expectValid(null, false);
943
- expectValid(0, false);
944
- expectValid(NaN, false);
945
- expectValid("", false);
946
-
947
- // True tests
948
- expectValid(true, true);
949
- expectValid(1, true);
950
- expectValid("0", true);
951
- expectValid("false", true);
952
- expectValid([], true);
953
- expectValid({}, true);
954
- });
955
-
956
- it("should register invalid validations on the $error object", () => {
957
- ctrl.$modelValue = undefined;
958
- ctrl.$validators.unique = () => false;
959
- ctrl.$validators.tooLong = () => false;
960
- ctrl.$validators.notNumeric = () => true;
961
-
962
- ctrl.$validate();
963
-
964
- expect(ctrl.$error.unique).toBe(true);
965
- expect(ctrl.$error.tooLong).toBe(true);
966
- expect(ctrl.$error.notNumeric).not.toBe(true);
967
- });
968
-
969
- it("should render a validator asynchronously when a promise is returned", async () => {
970
- let defer = Promise.withResolvers();
971
- ctrl.$asyncValidators.promiseValidator = function (value) {
972
- return defer.promise;
973
- };
974
-
975
- scope.$apply('value = ""');
976
- await wait();
977
- expect(ctrl.$valid).toBeUndefined();
978
- expect(ctrl.$invalid).toBeUndefined();
979
- expect(ctrl.$pending.promiseValidator).toBe(true);
980
-
981
- defer.resolve();
982
- await wait();
983
- expect(ctrl.$valid).toBe(true);
984
- expect(ctrl.$invalid).toBe(false);
985
- expect(ctrl.$pending).toBeUndefined();
986
-
987
- defer = Promise.withResolvers();
988
- ctrl.$asyncValidators.promiseValidator = function (value) {
989
- return defer.promise;
990
- };
991
-
992
- scope.$apply('value = "123"');
993
- defer.reject();
994
- await wait();
995
- expect(ctrl.$valid).toBe(false);
996
- expect(ctrl.$invalid).toBe(true);
997
- expect(ctrl.$pending).toBeUndefined();
998
- });
999
-
1000
- it("should throw an error when a promise is not returned for an asynchronous validator", async () => {
1001
- ctrl.$asyncValidators.async = function (value) {
1002
- return true;
1003
- };
1004
- scope.$apply('value = "123"');
1005
- await wait();
1006
- expect(errors[0].match(/nopromise/)).toBeTruthy();
1007
- });
1008
-
1009
- it("should only run the async validators once all the sync validators have passed", async () => {
1010
- const stages = {};
1011
- stages.async = { defer: null, count: 0 };
1012
- stages.async.defer = Promise.withResolvers();
1013
- stages.sync = { status1: false, status2: false, count: 0 };
1014
- ctrl.$validators.syncValidator1 = function (modelValue, viewValue) {
1015
- stages.sync.count++;
1016
- return stages.sync.status1;
1017
- };
1018
-
1019
- ctrl.$validators.syncValidator2 = function (modelValue, viewValue) {
1020
- stages.sync.count++;
1021
- return stages.sync.status2;
1022
- };
1023
-
1024
- ctrl.$asyncValidators.asyncValidator = function (
1025
- modelValue,
1026
- viewValue,
1027
- ) {
1028
- stages.async.count++;
1029
- return stages.async.defer.promise;
1030
- };
1031
-
1032
- scope.$apply('value = "123"');
1033
- await wait();
1034
- expect(ctrl.$valid).toBe(false);
1035
- expect(ctrl.$invalid).toBe(true);
1036
-
1037
- expect(stages.sync.count).toBe(2);
1038
- expect(stages.async.count).toBe(0);
1039
-
1040
- stages.sync.status1 = true;
1041
-
1042
- scope.$apply('value = "456"');
1043
- await wait();
1044
- expect(stages.sync.count).toBe(4);
1045
- expect(stages.async.count).toBe(0);
1046
-
1047
- stages.sync.status2 = true;
1048
-
1049
- scope.$apply('value = "789"');
1050
- await wait();
1051
- expect(stages.sync.count).toBe(6);
1052
- expect(stages.async.count).toBe(1);
1053
-
1054
- stages.async.defer.resolve();
1055
- scope.$apply();
1056
- await wait();
1057
- expect(ctrl.$valid).toBe(true);
1058
- expect(ctrl.$invalid).toBe(false);
1059
- });
1060
-
1061
- it("should ignore expired async validation promises once delivered", async () => {
1062
- let defer = Promise.withResolvers();
1063
- ctrl.$asyncValidators.async = function (value) {
1064
- return defer.promise;
1065
- };
1066
-
1067
- scope.$apply('value = ""');
1068
- await wait();
1069
- defer.reject();
1070
-
1071
- scope.$apply('value = "123"');
1072
- await wait();
1073
- defer.resolve();
1074
- expect(ctrl.$valid).toBe(false);
1075
- expect(ctrl.$invalid).toBe(true);
1076
- expect(ctrl.$pending).toBeUndefined();
1077
- });
1078
-
1079
- it("should clear and ignore all pending promises when the model value changes", async () => {
1080
- ctrl.$validators.sync = function (value) {
1081
- return true;
1082
- };
1083
-
1084
- const defers = [];
1085
- ctrl.$asyncValidators.async = function (value) {
1086
- const defer = Promise.withResolvers();
1087
- defers.push(defer);
1088
- return defer.promise;
1089
- };
1090
-
1091
- scope.$apply('value = "123"');
1092
- await wait();
1093
- expect(ctrl.$pending).toEqual({ async: true });
1094
- expect(ctrl.$valid).toBeUndefined();
1095
- expect(ctrl.$invalid).toBeUndefined();
1096
- expect(defers.length).toBe(1);
1097
- expect(isObject(ctrl.$pending)).toBe(true);
1098
-
1099
- scope.$apply('value = "456"');
1100
- await wait();
1101
- expect(ctrl.$pending).toEqual({ async: true });
1102
- expect(ctrl.$valid).toBeUndefined();
1103
- expect(ctrl.$invalid).toBeUndefined();
1104
- expect(defers.length).toBe(2);
1105
- expect(isObject(ctrl.$pending)).toBe(true);
1106
-
1107
- defers[1].resolve();
1108
- await wait();
1109
- expect(ctrl.$valid).toBe(true);
1110
- expect(ctrl.$invalid).toBe(false);
1111
- expect(isObject(ctrl.$pending)).toBe(false);
1112
- });
1113
-
1114
- it("should clear and ignore all pending promises when a parser fails", async () => {
1115
- let failParser = false;
1116
- ctrl.$parsers.push((value) => (failParser ? undefined : value));
1117
-
1118
- let defer;
1119
- ctrl.$asyncValidators.async = function (value) {
1120
- defer = Promise.withResolvers();
1121
- return defer.promise;
1122
- };
1123
-
1124
- ctrl.$setViewValue("x..y..z");
1125
- expect(ctrl.$valid).toBeUndefined();
1126
- expect(ctrl.$invalid).toBeUndefined();
1127
-
1128
- failParser = true;
1129
-
1130
- ctrl.$setViewValue("1..2..3");
1131
- expect(ctrl.$valid).toBe(false);
1132
- expect(ctrl.$invalid).toBe(true);
1133
- expect(isObject(ctrl.$pending)).toBe(false);
1134
-
1135
- defer.resolve();
1136
- await wait();
1137
- expect(ctrl.$valid).toBe(false);
1138
- expect(ctrl.$invalid).toBe(true);
1139
- expect(isObject(ctrl.$pending)).toBe(false);
1140
- });
1141
-
1142
- it("should clear all errors from async validators if a parser fails", async () => {
1143
- let failParser = false;
1144
- let defer = Promise.withResolvers();
1145
- ctrl.$parsers.push((value) => (failParser ? undefined : value));
1146
-
1147
- ctrl.$asyncValidators.async = function (value) {
1148
- return defer.promise;
1149
- };
1150
-
1151
- ctrl.$setViewValue("x..y..z");
1152
- defer.reject();
1153
- await wait();
1154
- expect(ctrl.$error).toEqual({ async: true });
1155
-
1156
- failParser = true;
1157
-
1158
- ctrl.$setViewValue("1..2..3");
1159
- expect(ctrl.$error).toEqual({ parse: true });
1160
- });
1161
-
1162
- it("should clear all errors from async validators if a sync validator fails", async () => {
1163
- let failValidator = false;
1164
- let defer = Promise.withResolvers();
1165
- ctrl.$validators.sync = function (value) {
1166
- return !failValidator;
1167
- };
1168
-
1169
- ctrl.$asyncValidators.async = function (value) {
1170
- return defer.promise;
1171
- };
1172
-
1173
- ctrl.$setViewValue("x..y..z");
1174
- defer.reject();
1175
- await wait();
1176
- expect(ctrl.$error).toEqual({ async: true });
1177
-
1178
- failValidator = true;
1179
-
1180
- ctrl.$setViewValue("1..2..3");
1181
- expect(ctrl.$error).toEqual({ sync: true });
1182
- });
1183
-
1184
- it("should be possible to extend Object prototype and still be able to do form validation", async () => {
1185
- Object.prototype.someThing = function () {};
1186
- const element = $compile(
1187
- '<form name="myForm">' +
1188
- '<input type="text" name="username" ng-model="username" minlength="10" required />' +
1189
- "</form>",
1190
- )($rootScope);
1191
- await wait();
1192
- const inputElm = element.querySelector("input");
1193
-
1194
- const formCtrl = $rootScope.myForm;
1195
- const usernameCtrl = formCtrl.username;
1196
-
1197
- expect(usernameCtrl.$invalid).toBe(true);
1198
- expect(formCtrl.$invalid).toBe(true);
1199
-
1200
- usernameCtrl.$setViewValue("valid-username");
1201
- await wait();
1202
- expect(usernameCtrl.$invalid).toBe(false);
1203
- expect(formCtrl.$invalid).toBe(false);
1204
- delete Object.prototype.someThing;
1205
-
1206
- dealoc(element);
1207
- });
1208
-
1209
- it("should re-evaluate the form validity state once the asynchronous promise has been delivered", async () => {
1210
- const element = $compile(
1211
- '<form name="myForm">' +
1212
- '<input type="text" name="username" ng-model="username" minlength="10" required />' +
1213
- '<input type="number" name="age" ng-model="age" min="10" required />' +
1214
- "</form>",
1215
- )($rootScope);
1216
- await wait();
1217
- const inputElm = element.querySelector("input");
1218
-
1219
- const formCtrl = $rootScope.myForm;
1220
- const usernameCtrl = formCtrl.username;
1221
- const ageCtrl = formCtrl.age;
1222
-
1223
- let usernameDefer = Promise.withResolvers();
1224
- usernameCtrl.$asyncValidators.usernameAvailability = function () {
1225
- return usernameDefer.promise;
1226
- };
1227
-
1228
- expect(usernameCtrl.$invalid).toBe(true);
1229
- expect(formCtrl.$invalid).toBe(true);
1230
- usernameCtrl.$setViewValue("valid-username");
1231
- expect(formCtrl.$pending.usernameAvailability).toBeTruthy();
1232
- expect(usernameCtrl.$invalid).toBeUndefined();
1233
- expect(formCtrl.$invalid).toBeUndefined();
1234
-
1235
- usernameDefer.resolve();
1236
- await wait();
1237
- expect(usernameCtrl.$invalid).toBe(false);
1238
- expect(ageCtrl.$invalid).toBe(true);
1239
- expect(formCtrl.$invalid).toBe(true);
1240
-
1241
- ageCtrl.$setViewValue(22);
1242
- await wait();
1243
-
1244
- expect(usernameCtrl.$invalid).toBe(false);
1245
- expect(ageCtrl.$invalid).toBe(false);
1246
- ///expect(formCtrl.$invalid).toBe(false);
1247
-
1248
- usernameCtrl.$setViewValue("valid");
1249
- expect(usernameCtrl.$invalid).toBe(true);
1250
- expect(ageCtrl.$invalid).toBe(false);
1251
- expect(formCtrl.$invalid).toBe(true);
1252
-
1253
- // usernameDefer = Promise.withResolvers();
1254
- // usernameCtrl.$asyncValidators.usernameAvailability = function () {
1255
- // return usernameDefer.promise;
1256
- // };
1257
- // usernameCtrl.$setViewValue("another-valid-username");
1258
- // usernameDefer.resolve();
1259
- await wait();
1260
- // expect(usernameCtrl.$invalid).toBe(false);
1261
- // expect(formCtrl.$invalid).toBe(false);
1262
- // expect(formCtrl.$pending).toBeFalsy();
1263
- // expect(ageCtrl.$invalid).toBe(false);
1264
-
1265
- dealoc(element);
1266
- });
1267
-
1268
- it("should always use the most recent $viewValue for validation", () => {
1269
- ctrl.$parsers.push((value) => {
1270
- if (value && value.slice(-1) === "b") {
1271
- value = "a";
1272
- ctrl.$setViewValue(value);
1273
- ctrl.$render();
1274
- }
1275
-
1276
- return value;
1277
- });
1278
-
1279
- ctrl.$validators.mock = function (modelValue) {
1280
- return true;
1281
- };
1282
-
1283
- spyOn(ctrl.$validators, "mock").and.callThrough();
1284
-
1285
- ctrl.$setViewValue("ab");
1286
-
1287
- expect(ctrl.$validators.mock).toHaveBeenCalledWith("a", "a");
1288
- expect(ctrl.$validators.mock).toHaveBeenCalledTimes(2);
1289
- });
1290
-
1291
- it("should validate even if the modelValue did not change", () => {
1292
- ctrl.$parsers.push((value) => {
1293
- if (value && value.slice(-1) === "b") {
1294
- value = "a";
1295
- }
1296
-
1297
- return value;
1298
- });
1299
-
1300
- ctrl.$validators.mock = function () {
1301
- return true;
1302
- };
1303
-
1304
- spyOn(ctrl.$validators, "mock").and.callThrough();
1305
-
1306
- ctrl.$setViewValue("a");
1307
-
1308
- expect(ctrl.$validators.mock).toHaveBeenCalledWith("a", "a");
1309
- expect(ctrl.$validators.mock).toHaveBeenCalledTimes(1);
1310
-
1311
- ctrl.$setViewValue("ab");
1312
-
1313
- expect(ctrl.$validators.mock).toHaveBeenCalledWith("a", "ab");
1314
- expect(ctrl.$validators.mock).toHaveBeenCalledTimes(2);
1315
- });
1316
-
1317
- it("should validate correctly when $parser name equals $validator key", async () => {
1318
- ctrl.$validators.parserOrValidator = function (value) {
1319
- switch (value) {
1320
- case "allInvalid":
1321
- case "parseValid-validatorsInvalid":
1322
- case "stillParseValid-validatorsInvalid":
1323
- return false;
1324
- default:
1325
- return true;
1326
- }
1327
- };
1328
-
1329
- ctrl.$validators.validator = function (value) {
1330
- switch (value) {
1331
- case "allInvalid":
1332
- case "parseValid-validatorsInvalid":
1333
- case "stillParseValid-validatorsInvalid":
1334
- return false;
1335
- default:
1336
- return true;
1337
- }
1338
- };
1339
-
1340
- ctrl.$parsers.push((value) => {
1341
- switch (value) {
1342
- case "allInvalid":
1343
- case "stillAllInvalid":
1344
- case "parseInvalid-validatorsValid":
1345
- case "stillParseInvalid-validatorsValid":
1346
- ctrl.$$parserName = "parserOrValidator";
1347
- return undefined;
1348
- default:
1349
- return value;
1350
- }
1351
- });
1352
-
1353
- // Parser and validators are invalid
1354
- scope.$apply('value = "allInvalid"');
1355
- await wait();
1356
- expect(scope.value).toBe("allInvalid");
1357
- expect(ctrl.$error).toEqual({
1358
- parserOrValidator: true,
1359
- validator: true,
1360
- });
1361
-
1362
- ctrl.$validate();
1363
- expect(scope.value).toEqual("allInvalid");
1364
- expect(ctrl.$error).toEqual({
1365
- parserOrValidator: true,
1366
- validator: true,
1367
- });
1368
-
1369
- ctrl.$setViewValue("stillAllInvalid");
1370
- expect(scope.value).toBeUndefined();
1371
- expect(ctrl.$error).toEqual({ parserOrValidator: true });
1372
-
1373
- ctrl.$validate();
1374
- expect(scope.value).toBeUndefined();
1375
- expect(ctrl.$error).toEqual({ parserOrValidator: true });
1376
-
1377
- // Parser is valid, validators are invalid
1378
- scope.$apply('value = "parseValid-validatorsInvalid"');
1379
- await wait();
1380
- expect(scope.value).toBe("parseValid-validatorsInvalid");
1381
- expect(ctrl.$error).toEqual({
1382
- parserOrValidator: true,
1383
- validator: true,
1384
- });
1385
-
1386
- ctrl.$validate();
1387
- await wait();
1388
- expect(scope.value).toBe("parseValid-validatorsInvalid");
1389
- expect(ctrl.$error).toEqual({
1390
- parserOrValidator: true,
1391
- validator: true,
1392
- });
1393
-
1394
- ctrl.$setViewValue("stillParseValid-validatorsInvalid");
1395
- await wait();
1396
- expect(scope.value).toBeUndefined();
1397
- expect(ctrl.$error).toEqual({
1398
- parserOrValidator: true,
1399
- validator: true,
1400
- });
1401
-
1402
- ctrl.$validate();
1403
- await wait();
1404
- expect(scope.value).toBeUndefined();
1405
- expect(ctrl.$error).toEqual({
1406
- parserOrValidator: true,
1407
- validator: true,
1408
- });
1409
-
1410
- // Parser is invalid, validators are valid
1411
- scope.$apply('value = "parseInvalid-validatorsValid"');
1412
- await wait();
1413
- expect(scope.value).toBe("parseInvalid-validatorsValid");
1414
- expect(ctrl.$error).toEqual({});
1415
-
1416
- ctrl.$validate();
1417
- await wait();
1418
- expect(scope.value).toBe("parseInvalid-validatorsValid");
1419
- expect(ctrl.$error).toEqual({});
1420
-
1421
- ctrl.$setViewValue("stillParseInvalid-validatorsValid");
1422
- await wait();
1423
- expect(scope.value).toBeUndefined();
1424
- expect(ctrl.$error).toEqual({ parserOrValidator: true });
1425
-
1426
- ctrl.$validate();
1427
- await wait();
1428
- expect(scope.value).toBeUndefined();
1429
- expect(ctrl.$error).toEqual({ parserOrValidator: true });
1430
- });
1431
- });
1432
-
1433
- describe("override ModelOptions", () => {
1434
- it("should replace the previous model options", () => {
1435
- const { $options } = ctrl;
1436
- ctrl.$overrideModelOptions({});
1437
- expect(ctrl.$options).not.toBe($options);
1438
- });
1439
-
1440
- it("should set the given options", () => {
1441
- const { $options } = ctrl;
1442
- ctrl.$overrideModelOptions({ debounce: 1000, updateOn: "blur" });
1443
- expect(ctrl.$options.getOption("debounce")).toEqual(1000);
1444
- expect(ctrl.$options.getOption("updateOn")).toEqual("blur");
1445
- expect(ctrl.$options.getOption("updateOnDefault")).toBe(false);
1446
- });
1447
-
1448
- it("should inherit from a parent model options if specified", async () => {
1449
- const element = $compile(
1450
- '<form name="form" ng-model-options="{debounce: 1000, updateOn: \'blur\'}">' +
1451
- ' <input ng-model="value" name="input">' +
1452
- "</form>",
1453
- )($rootScope);
1454
- await wait();
1455
- const ctrl = $rootScope.form.input;
1456
- ctrl.$overrideModelOptions({ debounce: 2000, "*": "$inherit" });
1457
- expect(ctrl.$options.getOption("debounce")).toEqual(2000);
1458
- expect(ctrl.$options.getOption("updateOn")).toEqual("blur");
1459
- expect(ctrl.$options.getOption("updateOnDefault")).toBe(false);
1460
- dealoc(element);
1461
- });
1462
-
1463
- it("should not inherit from a parent model options if not specified", async () => {
1464
- const element = $compile(
1465
- '<form name="form" ng-model-options="{debounce: 1000, updateOn: \'blur\'}">' +
1466
- ' <input ng-model="value" name="input">' +
1467
- "</form>",
1468
- )($rootScope);
1469
- await wait();
1470
- const ctrl = $rootScope.form.input;
1471
- ctrl.$overrideModelOptions({ debounce: 2000 });
1472
- expect(ctrl.$options.getOption("debounce")).toEqual(2000);
1473
- expect(ctrl.$options.getOption("updateOn")).toEqual("");
1474
- expect(ctrl.$options.getOption("updateOnDefault")).toBe(true);
1475
- dealoc(element);
1476
- });
1477
- });
1478
- });
1479
-
1480
- describe("CSS classes", () => {
1481
- const EMAIL_REGEXP =
1482
- /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
1483
-
1484
- it("should set ng-empty or ng-not-empty when the view value changes", async () => {
1485
- const element = $compile('<input ng-model="value" />')($rootScope);
1486
- await wait();
1487
- expect(element.value).toBe("");
1488
-
1489
- $rootScope.value = "XXX";
1490
- await wait();
1491
- expect(element.value).toBe("XXX");
1492
-
1493
- element.value = "";
1494
- browserTrigger(element, "change");
1495
- await wait();
1496
- expect(element.value).toBe("");
1497
-
1498
- element.value = "YYY";
1499
- browserTrigger(element, "change");
1500
- await wait();
1501
- expect(element.value).toBe("YYY");
1502
- });
1503
-
1504
- it("should set css classes (ng-valid, ng-invalid, ng-pristine, ng-dirty, ng-untouched, ng-touched)", async () => {
1505
- app.innerHTML = '<input type="email" ng-model="value" />';
1506
- $compile(app)($rootScope);
1507
- const element = app.querySelector("input");
1508
- await wait();
1509
- expect(element.classList.contains("ng-invalid-email")).toBe(false);
1510
-
1511
- $rootScope.value = "invalid-email";
1512
- await wait();
1513
-
1514
- expect(element.classList.contains("ng-invalid")).toBeTrue();
1515
- expect(element.classList.contains("ng-pristine")).toBeTrue();
1516
- expect(element.classList.contains("ng-valid-email")).toBe(false);
1517
- expect(element.classList.contains("ng-invalid-email")).toBe(true);
1518
-
1519
- element.value = "invalid-again";
1520
- browserTrigger(element, "change");
1521
-
1522
- expect(element.classList.contains("ng-invalid")).toBeTrue();
1523
- expect(element.classList.contains("ng-dirty")).toBeTrue();
1524
- expect(element.classList.contains("ng-valid-email")).toBe(false);
1525
- expect(element.classList.contains("ng-invalid-email")).toBe(true);
1526
-
1527
- element.value = "vojta@google.com";
1528
- browserTrigger(element, "change");
1529
- await wait();
1530
- expect(element.classList.contains("ng-valid")).toBeTrue();
1531
- expect(element.classList.contains("ng-dirty")).toBeTrue();
1532
- expect(element.classList.contains("ng-valid-email")).toBe(true);
1533
- expect(element.classList.contains("ng-invalid-email")).toBe(false);
1534
-
1535
- browserTrigger(element, "blur");
1536
- await wait();
1537
- expect(element.classList.contains("ng-touched")).toBeTrue();
1538
- });
1539
-
1540
- it("should set invalid classes on init", async () => {
1541
- const element = $compile(
1542
- '<input type="email" ng-model="value" required />',
1543
- )($rootScope);
1544
- await wait();
1545
- expect(element.classList.contains("ng-invalid")).toBeTrue();
1546
- expect(element.classList.contains("ng-invalid-required")).toBeTrue();
1547
-
1548
- dealoc(element);
1549
- });
1550
- });
1551
-
1552
- describe("custom formatter and parser that are added by a directive in post linking", () => {
1553
- let inputElm;
1554
- let scope;
1555
- let module;
1556
-
1557
- beforeEach(() => {
1558
- dealoc(document.getElementById("app"));
1559
- window.angular = new Angular();
1560
- module = window.angular
1561
- .module("myModule", [])
1562
- .directive("customFormat", () => ({
1563
- require: "ngModel",
1564
- link(scope, element, attrs, ngModelCtrl) {
1565
- ngModelCtrl.$formatters.push((value) => value.part);
1566
- ngModelCtrl.$parsers.push((value) => ({ part: value }));
1567
- },
1568
- }));
1569
- });
1570
-
1571
- afterEach(() => {
1572
- dealoc(inputElm);
1573
- });
1574
-
1575
- function createInput(type) {
1576
- inputElm = createElementFromHTML(
1577
- `<input type="${type}" ng-model="val" custom-format/>`,
1578
- );
1579
- const injector = angular.bootstrap(inputElm, ["myModule"]);
1580
- scope = injector.get("$rootScope");
1581
- }
1582
-
1583
- it("should use them after the builtin ones for text inputs", async () => {
1584
- createInput("text");
1585
- scope.val = { part: "a" };
1586
- await wait();
1587
- expect(inputElm.value).toBe("a");
1588
-
1589
- inputElm.value = "b";
1590
- browserTrigger(inputElm, "change");
1591
- expect(scope.val).toEqual({ part: "b" });
1592
- });
1593
-
1594
- it("should use them after the builtin ones for number inputs", async () => {
1595
- createInput("number");
1596
- scope.$apply("val = {part: 1}");
1597
- await wait();
1598
- expect(inputElm.value).toBe("1");
1599
-
1600
- inputElm.value = "2";
1601
- browserTrigger(inputElm, "change");
1602
- expect(scope.val).toEqual({ part: 2 });
1603
- });
1604
-
1605
- it("should use them after the builtin ones for date inputs", async () => {
1606
- createInput("date");
1607
- scope.val = { part: "2000-11-08" };
1608
- await wait();
1609
- expect(inputElm.value).toBe("2000-11-08");
1610
-
1611
- inputElm.value = "2001-12-09";
1612
- browserTrigger(inputElm, "change");
1613
- expect(scope.val).toEqual({ part: "2001-12-09" });
1614
- });
1615
- });
1616
-
1617
- describe("$touched", () => {
1618
- it('should set the control touched state on "blur" event', async () => {
1619
- const element = $compile(
1620
- '<form name="myForm">' +
1621
- '<input name="myControl" ng-model="value" >' +
1622
- "</form>",
1623
- )($rootScope);
1624
- await wait();
1625
- const inputElm = element.querySelector("input");
1626
- const control = $rootScope.myForm.myControl;
1627
-
1628
- expect(control.$touched).toBe(false);
1629
- expect(control.$untouched).toBe(true);
1630
-
1631
- browserTrigger(inputElm, "blur");
1632
- expect(control.$touched).toBe(true);
1633
- expect(control.$untouched).toBe(false);
1634
-
1635
- dealoc(element);
1636
- });
1637
-
1638
- it('should digest asynchronously on "blur" event if a apply is already in progress', async () => {
1639
- const element = $compile(
1640
- '<form name="myForm">' +
1641
- '<input name="myControl" ng-model="value" >' +
1642
- "</form>",
1643
- )($rootScope);
1644
- const inputElm = element.querySelector("input");
1645
- const control = $rootScope.myForm.myControl;
1646
-
1647
- expect(control.$touched).toBe(false);
1648
- expect(control.$untouched).toBe(true);
1649
-
1650
- browserTrigger(inputElm, "blur");
1651
- expect(control.$touched).toBe(true);
1652
- expect(control.$untouched).toBe(false);
1653
- });
1654
- });
1655
-
1656
- describe("nested in a form", () => {
1657
- it("should register/deregister a nested ngModel with parent form when entering or leaving DOM", async () => {
1658
- const element = $compile(
1659
- '<form name="myForm">' +
1660
- '<input ng-if="inputPresent" name="myControl" ng-model="value" required >' +
1661
- "</form>",
1662
- )($rootScope);
1663
- await wait();
1664
-
1665
- let isFormValid;
1666
-
1667
- $rootScope.inputPresent = false;
1668
- $rootScope.$watch("myForm.$valid", (value) => {
1669
- isFormValid = value;
1670
- });
1671
-
1672
- await wait();
1673
-
1674
- expect($rootScope.myForm.$valid).toBe(true);
1675
- expect(isFormValid).toBe(true);
1676
- expect($rootScope.myForm.myControl).toBeUndefined();
1677
-
1678
- $rootScope.inputPresent = true;
1679
- await wait();
1680
-
1681
- expect($rootScope.myForm.$valid).toBe(false);
1682
- expect(isFormValid).toBe(false);
1683
- expect($rootScope.myForm.myControl).toBeDefined();
1684
-
1685
- $rootScope.inputPresent = false;
1686
- await wait();
1687
-
1688
- expect($rootScope.myForm.$valid).toBe(true);
1689
- expect(isFormValid).toBe(true);
1690
- expect($rootScope.myForm.myControl).toBeUndefined();
1691
-
1692
- dealoc(element);
1693
- });
1694
-
1695
- it("should register/deregister a nested ngModel with parent form when entering or leaving DOM with animations", async () => {
1696
- // ngAnimate performs the dom manipulation after digest, and since the form validity can be affected by a form
1697
- // control going away we must ensure that the deregistration happens during the digest while we are still doing
1698
- // dirty checking.
1699
- // module("ngAnimate");
1700
-
1701
- const element = $compile(
1702
- '<form name="myForm">' +
1703
- '<input ng-if="inputPresent" name="myControl" ng-model="value" required >' +
1704
- "</form>",
1705
- )($rootScope);
1706
- await wait();
1707
-
1708
- let isFormValid;
1709
-
1710
- $rootScope.inputPresent = false;
1711
- // this watch ensure that the form validity gets updated during digest (so that we can observe it)
1712
- $rootScope.$watch("myForm.$valid", (value) => {
1713
- isFormValid = value;
1714
- });
1715
-
1716
- await wait();
1717
-
1718
- expect($rootScope.myForm.$valid).toBe(true);
1719
- expect(isFormValid).toBe(true);
1720
- expect($rootScope.myForm.myControl).toBeUndefined();
1721
-
1722
- $rootScope.inputPresent = true;
1723
- await wait();
1724
-
1725
- expect($rootScope.myForm.$valid).toBe(false);
1726
- expect(isFormValid).toBe(false);
1727
- expect($rootScope.myForm.myControl).toBeDefined();
1728
-
1729
- $rootScope.inputPresent = false;
1730
- await wait();
1731
-
1732
- expect($rootScope.myForm.$valid).toBe(true);
1733
- expect(isFormValid).toBe(true);
1734
- expect($rootScope.myForm.myControl).toBeUndefined();
1735
-
1736
- dealoc(element);
1737
- });
1738
-
1739
- it("should keep previously defined watches consistent when changes in validity are made", async () => {
1740
- let isFormValid;
1741
- $rootScope.$watch("myForm.$valid", (value) => {
1742
- isFormValid = value;
1743
- });
1744
-
1745
- const element = $compile(
1746
- '<form name="myForm">' +
1747
- '<input name="myControl" ng-model="value" required >' +
1748
- "</form>",
1749
- )($rootScope);
1750
-
1751
- await wait();
1752
- expect(isFormValid).toBe(false);
1753
- expect($rootScope.myForm.$valid).toBe(false);
1754
-
1755
- $rootScope.value = "value";
1756
- await wait();
1757
- expect(isFormValid).toBe(true);
1758
- expect($rootScope.myForm.$valid).toBe(true);
1759
-
1760
- dealoc(element);
1761
- });
1762
- });
1763
-
1764
- // TODO:
1765
- // describe("animations", () => {
1766
- // function findElementAnimations(element, queue) {
1767
- // const node = element;
1768
- // const animations = [];
1769
- // for (let i = 0; i < queue.length; i++) {
1770
- // const animation = queue[i];
1771
- // if (animation.element === node) {
1772
- // animations.push(animation);
1773
- // }
1774
- // }
1775
- // return animations;
1776
- // }
1777
-
1778
- // function assertValidAnimation(animation, event, classNameA, classNameB) {
1779
- // expect(animation.event).toBe(event);
1780
- // expect(animation.args[1]).toBe(classNameA);
1781
- // if (classNameB) expect(animation.args[2]).toBe(classNameB);
1782
- // }
1783
-
1784
- // let doc;
1785
- // let input;
1786
- // let scope;
1787
- // let model;
1788
-
1789
- // //beforeEach(module("ngAnimateMock"));
1790
-
1791
- // beforeEach(() => {
1792
- // scope = $rootScope.$new();
1793
- // doc = (
1794
- // '<form name="myForm">' +
1795
- // ' <input type="text" ng-model="input" name="myInput" />' +
1796
- // "</form>",
1797
- // );
1798
- // $rootElement.append(doc);
1799
- // $compile(doc)(scope);
1800
- // $animate.queue = [];
1801
-
1802
- // input = doc.querySelector("input");
1803
- // model = scope.myForm.myInput;
1804
- // });
1805
-
1806
- // afterEach(() => {
1807
- // dealoc(input);
1808
- // });
1809
-
1810
- // it("should trigger an animation when invalid", () => {
1811
- // model.$setValidity("required", false);
1812
-
1813
- // const animations = findElementAnimations(input, $animate.queue);
1814
- // assertValidAnimation(animations[0], "removeClass", "ng-valid");
1815
- // assertValidAnimation(animations[1], "addClass", "ng-invalid");
1816
- // assertValidAnimation(animations[2], "addClass", "ng-invalid-required");
1817
- // });
1818
-
1819
- // it("should trigger an animation when valid", () => {
1820
- // model.$setValidity("required", false);
1821
-
1822
- // $animate.queue = [];
1823
-
1824
- // model.$setValidity("required", true);
1825
-
1826
- // const animations = findElementAnimations(input, $animate.queue);
1827
- // assertValidAnimation(animations[0], "addClass", "ng-valid");
1828
- // assertValidAnimation(animations[1], "removeClass", "ng-invalid");
1829
- // assertValidAnimation(animations[2], "addClass", "ng-valid-required");
1830
- // assertValidAnimation(animations[3], "removeClass", "ng-invalid-required");
1831
- // });
1832
-
1833
- // it("should trigger an animation when dirty", () => {
1834
- // model.$setViewValue("some dirty value");
1835
-
1836
- // const animations = findElementAnimations(input, $animate.queue);
1837
- // assertValidAnimation(animations[0], "removeClass", "ng-empty");
1838
- // assertValidAnimation(animations[1], "addClass", "ng-not-empty");
1839
- // assertValidAnimation(animations[2], "removeClass", "ng-pristine");
1840
- // assertValidAnimation(animations[3], "addClass", "ng-dirty");
1841
- // });
1842
-
1843
- // it("should trigger an animation when pristine", () => {
1844
- // model.$setPristine();
1845
-
1846
- // const animations = findElementAnimations(input, $animate.queue);
1847
- // assertValidAnimation(animations[0], "removeClass", "ng-dirty");
1848
- // assertValidAnimation(animations[1], "addClass", "ng-pristine");
1849
- // });
1850
-
1851
- // it("should trigger an animation when untouched", () => {
1852
- // model.$setUntouched();
1853
-
1854
- // const animations = findElementAnimations(input, $animate.queue);
1855
- // assertValidAnimation(animations[0], "setClass", "ng-untouched");
1856
- // expect(animations[0].args[2]).toBe("ng-touched");
1857
- // });
1858
-
1859
- // it("should trigger an animation when touched", () => {
1860
- // model.$setTouched();
1861
-
1862
- // const animations = findElementAnimations(input, $animate.queue);
1863
- // assertValidAnimation(
1864
- // animations[0],
1865
- // "setClass",
1866
- // "ng-touched",
1867
- // "ng-untouched",
1868
- // );
1869
- // expect(animations[0].args[2]).toBe("ng-untouched");
1870
- // });
1871
-
1872
- // it("should trigger custom errors as addClass/removeClass when invalid/valid", () => {
1873
- // model.$setValidity("custom-error", false);
1874
-
1875
- // let animations = findElementAnimations(input, $animate.queue);
1876
- // assertValidAnimation(animations[0], "removeClass", "ng-valid");
1877
- // assertValidAnimation(animations[1], "addClass", "ng-invalid");
1878
- // assertValidAnimation(
1879
- // animations[2],
1880
- // "addClass",
1881
- // "ng-invalid-custom-error",
1882
- // );
1883
-
1884
- // $animate.queue = [];
1885
- // model.$setValidity("custom-error", true);
1886
-
1887
- // animations = findElementAnimations(input, $animate.queue);
1888
- // assertValidAnimation(animations[0], "addClass", "ng-valid");
1889
- // assertValidAnimation(animations[1], "removeClass", "ng-invalid");
1890
- // assertValidAnimation(animations[2], "addClass", "ng-valid-custom-error");
1891
- // assertValidAnimation(
1892
- // animations[3],
1893
- // "removeClass",
1894
- // "ng-invalid-custom-error",
1895
- // );
1896
- // });
1897
- // });
1898
- });
1899
-
1900
- describe("data-change", () => {
1901
- let $rootScope, $compile;
1902
- let el = document.getElementById("app");
1903
-
1904
- beforeEach(() => {
1905
- dealoc(document.getElementById("app"));
1906
- window.angular = new Angular();
1907
- });
1908
-
1909
- afterEach(() => dealoc(el));
1910
-
1911
- it("should $eval expression after new value is set in the model", async () => {
1912
- el.innerHTML =
1913
- 'Test<input type="text" ng-model="value" data-change="change()" />';
1914
-
1915
- window.angular.bootstrap(el, []).invoke((_$rootScope_, _$compile_) => {
1916
- $rootScope = _$rootScope_;
1917
- $compile = _$compile_;
1918
- });
1919
-
1920
- $rootScope.change = jasmine.createSpy("change").and.callFake(() => {
1921
- expect($rootScope.value).toBe("new value");
1922
- });
1923
-
1924
- el.querySelector("input").setAttribute("value", "new value");
1925
- el.querySelector("input").dispatchEvent(new Event("change"));
1926
- await wait();
1927
- expect($rootScope.change).toHaveBeenCalled();
1928
- });
1929
-
1930
- it("should not $eval the expression if changed from model", async () => {
1931
- el.innerHTML =
1932
- 'Test<input type="text" ng-model="value" data-change="change()" />';
1933
-
1934
- window.angular.bootstrap(el, []).invoke((_$rootScope_, _$compile_) => {
1935
- $rootScope = _$rootScope_;
1936
- $compile = _$compile_;
1937
- });
1938
-
1939
- $rootScope.change = jasmine.createSpy("change");
1940
- $rootScope.$apply("value = true");
1941
- await wait();
1942
- expect($rootScope.change).not.toHaveBeenCalled();
1943
- });
1944
-
1945
- it("should $eval ngChange expression on checkbox", async () => {
1946
- el.innerHTML =
1947
- 'Test<input type="checkbox" ng-model="value" data-change="changeFn()" />';
1948
-
1949
- window.angular.bootstrap(el, []).invoke((_$rootScope_, _$compile_) => {
1950
- $rootScope = _$rootScope_;
1951
- $compile = _$compile_;
1952
- });
1953
-
1954
- $rootScope.changeFn = jasmine.createSpy("changeFn");
1955
- expect($rootScope.changeFn).not.toHaveBeenCalled();
1956
-
1957
- el.querySelector("input").dispatchEvent(new Event("change"));
1958
- await wait();
1959
- expect($rootScope.changeFn).toHaveBeenCalled();
1960
- });
1961
-
1962
- it("should be able to change the model and via that also update the view", async () => {
1963
- el.innerHTML =
1964
- '<input type="text" ng-model="value" data-change="value=\'b\'" />';
1965
-
1966
- window.angular.bootstrap(el, []).invoke((_$rootScope_, _$compile_) => {
1967
- $rootScope = _$rootScope_;
1968
- $compile = _$compile_;
1969
- });
1970
-
1971
- el.querySelector("input").setAttribute("value", "a");
1972
- el.querySelector("input").dispatchEvent(new Event("change"));
1973
- await wait();
1974
- expect(el.querySelector("input").value).toBe("b");
1975
- });
1976
- });