@angular-wave/angular.ts 0.9.4 → 0.9.6

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 (645) hide show
  1. package/@types/index.d.ts +1 -84
  2. package/{src/index.ts → @types/namespace.d.ts} +4 -24
  3. package/@types/router/template-factory.d.ts +2 -2
  4. package/dist/angular-ts.esm.js +3 -3
  5. package/dist/angular-ts.umd.js +3 -3
  6. package/dist/angular-ts.umd.min.js +1 -1
  7. package/package.json +9 -2
  8. package/.github/workflows/ci.yml +0 -104
  9. package/.github/workflows/gh-pages.yml +0 -75
  10. package/.husky/pre-commit +0 -5
  11. package/.prettierignore +0 -9
  12. package/CHANGELOG.md +0 -17667
  13. package/CODE_OF_CONDUCT.md +0 -3
  14. package/CONTRIBUTING.md +0 -247
  15. package/DEVELOPERS.md +0 -499
  16. package/Makefile +0 -60
  17. package/RELEASE.md +0 -86
  18. package/TRIAGING.md +0 -127
  19. package/docs/.cspell.yml +0 -8
  20. package/docs/.github/dependabot.yml +0 -14
  21. package/docs/.nvmrc +0 -1
  22. package/docs/CONTRIBUTING.md +0 -28
  23. package/docs/Dockerfile +0 -4
  24. package/docs/LICENSE +0 -201
  25. package/docs/README.md +0 -217
  26. package/docs/assets/icons/logo.svg +0 -1
  27. package/docs/assets/scss/_variables_project.scss +0 -12
  28. package/docs/assets/scss/_variables_project_after_bs.scss +0 -8
  29. package/docs/assets/scss/index.scss +0 -48
  30. package/docs/config.yaml +0 -15
  31. package/docs/content/_index.md +0 -28
  32. package/docs/content/docs/_index.md +0 -61
  33. package/docs/content/docs/directive/_index.md +0 -4
  34. package/docs/content/docs/directive/app.md +0 -11
  35. package/docs/content/docs/directive/aria.md +0 -0
  36. package/docs/content/docs/directive/bind.md +0 -72
  37. package/docs/content/docs/directive/blur.md +0 -38
  38. package/docs/content/docs/directive/channel.md +0 -37
  39. package/docs/content/docs/directive/class-even.md +0 -47
  40. package/docs/content/docs/directive/class-odd.md +0 -48
  41. package/docs/content/docs/directive/class.md +0 -64
  42. package/docs/content/docs/directive/click.md +0 -41
  43. package/docs/content/docs/directive/cloak.md +0 -74
  44. package/docs/content/docs/directive/copy.md +0 -38
  45. package/docs/content/docs/directive/cut.md +0 -40
  46. package/docs/content/docs/directive/dblclick.md +0 -41
  47. package/docs/content/docs/directive/focus.md +0 -38
  48. package/docs/content/docs/directive/get.md +0 -203
  49. package/docs/content/docs/directive/include.md +0 -7
  50. package/docs/content/docs/directive/keydown.md +0 -38
  51. package/docs/content/docs/directive/keyup.md +0 -38
  52. package/docs/content/docs/directive/load.md +0 -43
  53. package/docs/content/docs/directive/mousedown.md +0 -38
  54. package/docs/content/docs/directive/mouseenter.md +0 -38
  55. package/docs/content/docs/directive/mouseleave.md +0 -38
  56. package/docs/content/docs/directive/mousemove.md +0 -38
  57. package/docs/content/docs/directive/mouseout.md +0 -38
  58. package/docs/content/docs/directive/mouseover.md +0 -38
  59. package/docs/content/docs/directive/mouseup.md +0 -38
  60. package/docs/content/docs/directive/non-bindable.md +0 -28
  61. package/docs/content/docs/filter/_index.md +0 -4
  62. package/docs/content/docs/filter/filter.md +0 -78
  63. package/docs/content/docs/filter/json.md +0 -19
  64. package/docs/content/docs/filter/limit-to.md +0 -30
  65. package/docs/content/docs/filter/order-by.md +0 -123
  66. package/docs/content/docs/provider/_index.md +0 -4
  67. package/docs/content/docs/provider/eventBusProvider.md +0 -35
  68. package/docs/content/docs/provider/locationProvider.md +0 -26
  69. package/docs/content/docs/provider/logProvider.md +0 -59
  70. package/docs/content/docs/provider/sceProvider.md +0 -194
  71. package/docs/content/docs/provider/templateCacheProvider.md +0 -100
  72. package/docs/content/docs/provider/templateRequestProvider.md +0 -5
  73. package/docs/content/docs/service/_index.md +0 -4
  74. package/docs/content/docs/service/compile.md +0 -5
  75. package/docs/content/docs/service/controller.md +0 -5
  76. package/docs/content/docs/service/eventBus.md +0 -56
  77. package/docs/content/docs/service/http.md +0 -161
  78. package/docs/content/docs/service/interpolation.md +0 -5
  79. package/docs/content/docs/service/location.md +0 -57
  80. package/docs/content/docs/service/log.md +0 -113
  81. package/docs/content/docs/service/parse.md +0 -5
  82. package/docs/content/docs/service/rootElement.md +0 -5
  83. package/docs/content/docs/service/rootScope.md +0 -5
  84. package/docs/content/docs/service/sce.md +0 -194
  85. package/docs/content/docs/service/templateCache.md +0 -64
  86. package/docs/content/docs/service/templateRequest.md +0 -5
  87. package/docs/content/docs/service/url.md +0 -5
  88. package/docs/content/docs/values/_index.md +0 -4
  89. package/docs/content/docs/values/document.md +0 -29
  90. package/docs/content/docs/values/window.md +0 -29
  91. package/docs/docker-compose.yaml +0 -12
  92. package/docs/docsy.work +0 -5
  93. package/docs/docsy.work.sum +0 -0
  94. package/docs/go.mod +0 -5
  95. package/docs/go.sum +0 -6
  96. package/docs/hugo-disabled.toml +0 -220
  97. package/docs/hugo.yaml +0 -200
  98. package/docs/layouts/404.html +0 -13
  99. package/docs/layouts/_markup/render-heading.html +0 -1
  100. package/docs/layouts/partials/hooks/head-end.html +0 -3
  101. package/docs/layouts/shortcodes/showcss.html +0 -2
  102. package/docs/layouts/shortcodes/showhtml.html +0 -2
  103. package/docs/layouts/shortcodes/showjs.html +0 -2
  104. package/docs/layouts/shortcodes/showraw.html +0 -1
  105. package/docs/layouts/shortcodes/version.html +0 -1
  106. package/docs/package-lock.json +0 -2293
  107. package/docs/package.json +0 -53
  108. package/docs/static/examples/counter/counter-test.html +0 -13
  109. package/docs/static/examples/counter/counter.html +0 -5
  110. package/docs/static/examples/counter/counter.test.js +0 -28
  111. package/docs/static/examples/document/document.html +0 -3
  112. package/docs/static/examples/eventbus/eventbus-test.html +0 -15
  113. package/docs/static/examples/eventbus/eventbus.html +0 -13
  114. package/docs/static/examples/eventbus/eventbus.js +0 -15
  115. package/docs/static/examples/eventbus/eventbus.test.js +0 -19
  116. package/docs/static/examples/i18n/i18n.html +0 -77
  117. package/docs/static/examples/ng-bind/ng-bind.html +0 -9
  118. package/docs/static/examples/ng-blur/ng-blur.html +0 -9
  119. package/docs/static/examples/ng-channel/ng-channel-test.html +0 -17
  120. package/docs/static/examples/ng-channel/ng-channel.html +0 -24
  121. package/docs/static/examples/ng-channel/ng-channel.test.js +0 -31
  122. package/docs/static/examples/ng-class/ng-class.html +0 -71
  123. package/docs/static/examples/ng-class-even/ng-class-even.html +0 -8
  124. package/docs/static/examples/ng-class-odd/ng-class-odd.html +0 -8
  125. package/docs/static/examples/ng-click/ng-click.html +0 -6
  126. package/docs/static/examples/ng-copy/ng-copy.html +0 -6
  127. package/docs/static/examples/ng-cut/ng-cut.html +0 -6
  128. package/docs/static/examples/ng-dblclick/ng-dblclick.html +0 -10
  129. package/docs/static/examples/ng-focus/ng-focus.html +0 -9
  130. package/docs/static/examples/ng-keydown/ng-keydown.html +0 -9
  131. package/docs/static/examples/ng-keyup/ng-keyup.html +0 -9
  132. package/docs/static/examples/ng-load/ng-load.html +0 -8
  133. package/docs/static/examples/ng-mousedown/ng-mousedown.html +0 -6
  134. package/docs/static/examples/ng-mouseenter/ng-mouseenter.html +0 -4
  135. package/docs/static/examples/ng-mouseleave/ng-mouseleave.html +0 -4
  136. package/docs/static/examples/ng-mousemove/ng-mousemove.html +0 -4
  137. package/docs/static/examples/ng-mouseout/ng-mouseout.html +0 -4
  138. package/docs/static/examples/ng-mouseover/ng-mouseover.html +0 -4
  139. package/docs/static/examples/ng-mouseup/ng-mouseup.html +0 -4
  140. package/docs/static/examples/ng-non-bindable/ng-non-bindable-test.html +0 -13
  141. package/docs/static/examples/ng-non-bindable/ng-non-bindable.html +0 -3
  142. package/docs/static/examples/ng-non-bindable/ng-non-bindable.test.js +0 -11
  143. package/docs/static/examples/window/window.html +0 -4
  144. package/docs/static/typedoc/.nojekyll +0 -1
  145. package/docs/static/typedoc/assets/hierarchy.js +0 -1
  146. package/docs/static/typedoc/assets/highlight.css +0 -29
  147. package/docs/static/typedoc/assets/icons.js +0 -18
  148. package/docs/static/typedoc/assets/icons.svg +0 -1
  149. package/docs/static/typedoc/assets/main.js +0 -60
  150. package/docs/static/typedoc/assets/navigation.js +0 -1
  151. package/docs/static/typedoc/assets/search.js +0 -1
  152. package/docs/static/typedoc/assets/style.css +0 -1633
  153. package/docs/static/typedoc/classes/Location.html +0 -55
  154. package/docs/static/typedoc/classes/LocationProvider.html +0 -20
  155. package/docs/static/typedoc/classes/LogProvider.html +0 -6
  156. package/docs/static/typedoc/classes/PubSub.html +0 -71
  157. package/docs/static/typedoc/classes/PubSubProvider.html +0 -4
  158. package/docs/static/typedoc/classes/TemplateCacheProvider.html +0 -5
  159. package/docs/static/typedoc/hierarchy.html +0 -1
  160. package/docs/static/typedoc/index.html +0 -1
  161. package/docs/static/typedoc/interfaces/DefaultPorts.html +0 -5
  162. package/docs/static/typedoc/interfaces/Html5Mode.html +0 -23
  163. package/docs/static/typedoc/interfaces/HttpHeadersGetter.html +0 -1
  164. package/docs/static/typedoc/interfaces/HttpProviderDefaults.html +0 -31
  165. package/docs/static/typedoc/interfaces/HttpRequestConfigHeaders.html +0 -6
  166. package/docs/static/typedoc/interfaces/HttpRequestTransformer.html +0 -1
  167. package/docs/static/typedoc/interfaces/HttpResponse.html +0 -7
  168. package/docs/static/typedoc/interfaces/HttpResponseTransformer.html +0 -1
  169. package/docs/static/typedoc/interfaces/HttpService.html +0 -38
  170. package/docs/static/typedoc/interfaces/LogService.html +0 -12
  171. package/docs/static/typedoc/interfaces/RequestConfig.html +0 -48
  172. package/docs/static/typedoc/interfaces/RequestShortcutConfig.html +0 -38
  173. package/docs/static/typedoc/interfaces/ServiceProvider.html +0 -5
  174. package/docs/static/typedoc/interfaces/UrlParts.html +0 -9
  175. package/docs/static/typedoc/types/HttpParamSerializer.html +0 -2
  176. package/docs/static/typedoc/types/HttpParams.html +0 -2
  177. package/docs/static/typedoc/types/HttpPromise.html +0 -1
  178. package/docs/static/typedoc/types/HttpResponseStatus.html +0 -1
  179. package/docs/static/typedoc/types/LogCall.html +0 -2
  180. package/docs/static/typedoc/types/LogServiceFactory.html +0 -2
  181. package/docs/static/typedoc/types/UrlChangeListener.html +0 -5
  182. package/docs/static/typedoc/variables/EventBus.html +0 -1
  183. package/docs/static/version.js +0 -13
  184. package/docs/test-results/.last-run.json +0 -4
  185. package/docs/test-results/static-examples-counter-counter-counter-example/error-context.md +0 -50
  186. package/eslint.config.js +0 -26
  187. package/images/android-chrome-192x192.png +0 -0
  188. package/images/android-chrome-512x512.png +0 -0
  189. package/images/apple-touch-icon.png +0 -0
  190. package/images/favicon-16x16.png +0 -0
  191. package/images/favicon-32x32.png +0 -0
  192. package/images/favicon.ico +0 -0
  193. package/images/site.webmanifest +0 -19
  194. package/index.html +0 -86
  195. package/legacy.d.ts +0 -1678
  196. package/playwright.config.ts +0 -81
  197. package/public/jasmine/boot0.js +0 -66
  198. package/public/jasmine/boot1.js +0 -134
  199. package/public/jasmine/jasmine-html.js +0 -970
  200. package/public/jasmine/jasmine.css +0 -323
  201. package/public/jasmine/jasmine.js +0 -11406
  202. package/public/public/README.md +0 -1
  203. package/public/public/circle.html +0 -1
  204. package/public/public/jasmine-helper.css +0 -9
  205. package/public/public/my_child_directive.html +0 -1
  206. package/public/public/my_directive.html +0 -1
  207. package/public/public/my_other_directive.html +0 -1
  208. package/public/public/test.html +0 -1
  209. package/rollup.config.js +0 -51
  210. package/src/angular.js +0 -286
  211. package/src/angular.spec.js +0 -1191
  212. package/src/animations/animate-cache.js +0 -80
  213. package/src/animations/animate-children-directive.js +0 -32
  214. package/src/animations/animate-children-directive.md +0 -80
  215. package/src/animations/animate-css-driver.js +0 -284
  216. package/src/animations/animate-css.html +0 -58
  217. package/src/animations/animate-css.js +0 -915
  218. package/src/animations/animate-css.md +0 -263
  219. package/src/animations/animate-js-driver.js +0 -60
  220. package/src/animations/animate-js.html +0 -47
  221. package/src/animations/animate-js.js +0 -371
  222. package/src/animations/animate-queue.js +0 -859
  223. package/src/animations/animate-runner.js +0 -193
  224. package/src/animations/animate-swap.js +0 -33
  225. package/src/animations/animate-swap.md +0 -88
  226. package/src/animations/animate.html +0 -19
  227. package/src/animations/animate.js +0 -546
  228. package/src/animations/animate.md +0 -933
  229. package/src/animations/animate.spec.js +0 -490
  230. package/src/animations/animation.js +0 -519
  231. package/src/animations/animations.test.js +0 -10
  232. package/src/animations/interface.ts +0 -19
  233. package/src/animations/raf-scheduler.html +0 -19
  234. package/src/animations/raf-scheduler.js +0 -92
  235. package/src/animations/raf-scheduler.spec.js +0 -98
  236. package/src/animations/shared.js +0 -341
  237. package/src/binding.html +0 -19
  238. package/src/binding.spec.js +0 -474
  239. package/src/binding.test.js +0 -10
  240. package/src/core/compile/attributes.js +0 -337
  241. package/src/core/compile/compile.html +0 -19
  242. package/src/core/compile/compile.js +0 -3271
  243. package/src/core/compile/compile.md +0 -1128
  244. package/src/core/compile/compile.spec.js +0 -15574
  245. package/src/core/compile/compile.test.js +0 -12
  246. package/src/core/controller/controller.html +0 -22
  247. package/src/core/controller/controller.js +0 -193
  248. package/src/core/controller/controller.spec.js +0 -334
  249. package/src/core/controller/controller.test.js +0 -12
  250. package/src/core/controller/interface.ts +0 -6
  251. package/src/core/core.html +0 -20
  252. package/src/core/core.test.js +0 -12
  253. package/src/core/di/injector.html +0 -19
  254. package/src/core/di/injector.js +0 -307
  255. package/src/core/di/injector.md +0 -740
  256. package/src/core/di/injector.spec.js +0 -2310
  257. package/src/core/di/injector.test.js +0 -12
  258. package/src/core/di/internal-injector.js +0 -286
  259. package/src/core/di/ng-module.html +0 -19
  260. package/src/core/di/ng-module.js +0 -229
  261. package/src/core/di/ng-module.spec.js +0 -263
  262. package/src/core/di/ng-module.test.js +0 -12
  263. package/src/core/filter/filter.html +0 -19
  264. package/src/core/filter/filter.js +0 -55
  265. package/src/core/filter/filter.md +0 -132
  266. package/src/core/filter/filter.spec.js +0 -149
  267. package/src/core/filter/filter.test.js +0 -12
  268. package/src/core/interpolate/interface.ts +0 -14
  269. package/src/core/interpolate/interpolate.html +0 -22
  270. package/src/core/interpolate/interpolate.js +0 -410
  271. package/src/core/interpolate/interpolate.spec.js +0 -601
  272. package/src/core/interpolate/interpolate.test.js +0 -12
  273. package/src/core/parse/ast/ast-node.ts +0 -81
  274. package/src/core/parse/ast/ast.html +0 -19
  275. package/src/core/parse/ast/ast.js +0 -574
  276. package/src/core/parse/ast/ast.spec.js +0 -1453
  277. package/src/core/parse/ast/ast.test.js +0 -10
  278. package/src/core/parse/ast-type.js +0 -23
  279. package/src/core/parse/interface.ts +0 -84
  280. package/src/core/parse/interpreter.js +0 -915
  281. package/src/core/parse/lexer/lexer.html +0 -19
  282. package/src/core/parse/lexer/lexer.js +0 -338
  283. package/src/core/parse/lexer/lexer.spec.js +0 -303
  284. package/src/core/parse/lexer/lexer.test.js +0 -10
  285. package/src/core/parse/lexer/token.ts +0 -22
  286. package/src/core/parse/parse.html +0 -19
  287. package/src/core/parse/parse.js +0 -337
  288. package/src/core/parse/parse.md +0 -57
  289. package/src/core/parse/parse.spec.js +0 -2107
  290. package/src/core/parse/parse.test.js +0 -10
  291. package/src/core/parse/parser/parser.html +0 -19
  292. package/src/core/parse/parser/parser.js +0 -64
  293. package/src/core/parse/parser/parser.spec.js +0 -8
  294. package/src/core/parse/parser/parser.test.js +0 -10
  295. package/src/core/prop.spec.js +0 -775
  296. package/src/core/root-element.spec.js +0 -14
  297. package/src/core/sanitize/interface.ts +0 -10
  298. package/src/core/sanitize/sanitize-uri.js +0 -75
  299. package/src/core/sanitize/sanitize-uri.spec.js +0 -249
  300. package/src/core/sanitize/sanitize-uri.test.js +0 -12
  301. package/src/core/sanitize/sanitize.html +0 -22
  302. package/src/core/scope/scope.html +0 -19
  303. package/src/core/scope/scope.js +0 -1252
  304. package/src/core/scope/scope.spec.js +0 -3000
  305. package/src/core/scope/scope.test.js +0 -12
  306. package/src/directive/aria/aria.html +0 -19
  307. package/src/directive/aria/aria.js +0 -382
  308. package/src/directive/aria/aria.md +0 -145
  309. package/src/directive/aria/aria.spec.js +0 -1241
  310. package/src/directive/aria/aria.test.js +0 -12
  311. package/src/directive/attrs/attrs.html +0 -19
  312. package/src/directive/attrs/attrs.js +0 -106
  313. package/src/directive/attrs/attrs.md +0 -224
  314. package/src/directive/attrs/attrs.spec.js +0 -71
  315. package/src/directive/attrs/attrs.test.js +0 -12
  316. package/src/directive/attrs/boolean.html +0 -19
  317. package/src/directive/attrs/boolean.spec.js +0 -137
  318. package/src/directive/attrs/boolean.test.js +0 -12
  319. package/src/directive/attrs/element-style.html +0 -22
  320. package/src/directive/attrs/element-style.spec.js +0 -85
  321. package/src/directive/attrs/element-style.test.js +0 -12
  322. package/src/directive/attrs/src.html +0 -19
  323. package/src/directive/attrs/src.spec.js +0 -163
  324. package/src/directive/attrs/src.test.js +0 -12
  325. package/src/directive/bind/bind-html.spec.js +0 -36
  326. package/src/directive/bind/bind.html +0 -20
  327. package/src/directive/bind/bind.js +0 -78
  328. package/src/directive/bind/bind.md +0 -142
  329. package/src/directive/bind/bind.spec.js +0 -314
  330. package/src/directive/bind/bind.test.js +0 -12
  331. package/src/directive/channel/channel.html +0 -19
  332. package/src/directive/channel/channel.js +0 -30
  333. package/src/directive/channel/channel.spec.js +0 -67
  334. package/src/directive/channel/channel.test.js +0 -10
  335. package/src/directive/class/class-test.html +0 -23
  336. package/src/directive/class/class.html +0 -19
  337. package/src/directive/class/class.js +0 -184
  338. package/src/directive/class/class.spec.js +0 -704
  339. package/src/directive/class/class.test.js +0 -12
  340. package/src/directive/cloak/cloak.html +0 -19
  341. package/src/directive/cloak/cloak.js +0 -11
  342. package/src/directive/cloak/cloak.spec.js +0 -44
  343. package/src/directive/cloak/cloak.test.js +0 -12
  344. package/src/directive/controller/controller.html +0 -22
  345. package/src/directive/controller/controller.js +0 -11
  346. package/src/directive/controller/controller.md +0 -46
  347. package/src/directive/controller/controller.spec.js +0 -175
  348. package/src/directive/controller/controller.test.js +0 -12
  349. package/src/directive/events/click.spec.js +0 -35
  350. package/src/directive/events/event.spec.js +0 -267
  351. package/src/directive/events/events-test.html +0 -36
  352. package/src/directive/events/events.html +0 -20
  353. package/src/directive/events/events.js +0 -65
  354. package/src/directive/events/events.md +0 -125
  355. package/src/directive/events/events.test.js +0 -12
  356. package/src/directive/form/form.html +0 -19
  357. package/src/directive/form/form.js +0 -669
  358. package/src/directive/form/form.spec.js +0 -1515
  359. package/src/directive/form/form.test.js +0 -12
  360. package/src/directive/http/delete.spec.js +0 -23
  361. package/src/directive/http/form-router-test.html +0 -44
  362. package/src/directive/http/form-test.html +0 -18
  363. package/src/directive/http/get.spec.js +0 -488
  364. package/src/directive/http/http.html +0 -22
  365. package/src/directive/http/http.js +0 -342
  366. package/src/directive/http/http.test.js +0 -12
  367. package/src/directive/http/interface.ts +0 -36
  368. package/src/directive/http/post-example.html +0 -30
  369. package/src/directive/http/post.spec.js +0 -521
  370. package/src/directive/http/put.spec.js +0 -23
  371. package/src/directive/if/if-animate-css.html +0 -57
  372. package/src/directive/if/if-animate-svg.html +0 -25
  373. package/src/directive/if/if.html +0 -19
  374. package/src/directive/if/if.js +0 -72
  375. package/src/directive/if/if.md +0 -76
  376. package/src/directive/if/if.spec.js +0 -293
  377. package/src/directive/if/if.test.js +0 -114
  378. package/src/directive/include/include.html +0 -19
  379. package/src/directive/include/include.js +0 -151
  380. package/src/directive/include/include.md +0 -87
  381. package/src/directive/include/include.spec.js +0 -734
  382. package/src/directive/include/include.test.js +0 -12
  383. package/src/directive/init/init.html +0 -19
  384. package/src/directive/init/init.js +0 -22
  385. package/src/directive/init/init.md +0 -41
  386. package/src/directive/init/init.spec.js +0 -68
  387. package/src/directive/init/init.test.js +0 -12
  388. package/src/directive/inject/inject.html +0 -19
  389. package/src/directive/inject/inject.js +0 -35
  390. package/src/directive/inject/inject.spec.js +0 -108
  391. package/src/directive/inject/inject.test.js +0 -12
  392. package/src/directive/input/input-example.html +0 -15
  393. package/src/directive/input/input.html +0 -19
  394. package/src/directive/input/input.js +0 -1078
  395. package/src/directive/input/input.md +0 -706
  396. package/src/directive/input/input.spec.js +0 -3700
  397. package/src/directive/input/input.test.js +0 -12
  398. package/src/directive/messages/messages.html +0 -22
  399. package/src/directive/messages/messages.js +0 -349
  400. package/src/directive/messages/messages.md +0 -543
  401. package/src/directive/messages/messages.spec.js +0 -1083
  402. package/src/directive/messages/messages.test.js +0 -12
  403. package/src/directive/model/change.md +0 -25
  404. package/src/directive/model/model.html +0 -19
  405. package/src/directive/model/model.js +0 -1170
  406. package/src/directive/model/model.spec.js +0 -1976
  407. package/src/directive/model/model.test.js +0 -12
  408. package/src/directive/model-options/model-option.test.js +0 -12
  409. package/src/directive/model-options/model-options.html +0 -22
  410. package/src/directive/model-options/model-options.js +0 -142
  411. package/src/directive/model-options/model-options.md +0 -407
  412. package/src/directive/model-options/model-options.spec.js +0 -1022
  413. package/src/directive/non-bindable/non-bindable.html +0 -22
  414. package/src/directive/non-bindable/non-bindable.js +0 -9
  415. package/src/directive/non-bindable/non-bindable.spec.js +0 -59
  416. package/src/directive/non-bindable/non-bindable.test.js +0 -12
  417. package/src/directive/observe/observe-demo.html +0 -184
  418. package/src/directive/observe/observe.html +0 -19
  419. package/src/directive/observe/observe.js +0 -41
  420. package/src/directive/observe/observe.spec.js +0 -106
  421. package/src/directive/observe/observe.test.js +0 -10
  422. package/src/directive/on/on.html +0 -19
  423. package/src/directive/on/on.spec.js +0 -215
  424. package/src/directive/on/on.test.js +0 -12
  425. package/src/directive/options/options-example.html +0 -17
  426. package/src/directive/options/options.html +0 -22
  427. package/src/directive/options/options.js +0 -542
  428. package/src/directive/options/options.md +0 -179
  429. package/src/directive/options/options.spec.js +0 -3554
  430. package/src/directive/options/options.test.js +0 -12
  431. package/src/directive/ref/href.html +0 -19
  432. package/src/directive/ref/href.spec.js +0 -141
  433. package/src/directive/ref/href.test.js +0 -19
  434. package/src/directive/ref/ref.html +0 -19
  435. package/src/directive/ref/ref.js +0 -89
  436. package/src/directive/ref/ref.spec.js +0 -546
  437. package/src/directive/repeat/repeat.html +0 -19
  438. package/src/directive/repeat/repeat.js +0 -333
  439. package/src/directive/repeat/repeat.md +0 -330
  440. package/src/directive/repeat/repeat.spec.js +0 -1209
  441. package/src/directive/repeat/repeat.test.js +0 -12
  442. package/src/directive/script/script.html +0 -19
  443. package/src/directive/script/script.js +0 -17
  444. package/src/directive/script/script.md +0 -11
  445. package/src/directive/script/script.spec.js +0 -47
  446. package/src/directive/script/script.test.js +0 -12
  447. package/src/directive/select/select.html +0 -19
  448. package/src/directive/select/select.js +0 -594
  449. package/src/directive/select/select.md +0 -74
  450. package/src/directive/select/select.spec.js +0 -2566
  451. package/src/directive/select/select.test.js +0 -12
  452. package/src/directive/setter/setter.html +0 -19
  453. package/src/directive/setter/setter.js +0 -59
  454. package/src/directive/setter/setter.spec.js +0 -100
  455. package/src/directive/setter/setter.test.js +0 -12
  456. package/src/directive/show-hide/show-hide.html +0 -22
  457. package/src/directive/show-hide/show-hide.js +0 -65
  458. package/src/directive/show-hide/show-hide.md +0 -255
  459. package/src/directive/show-hide/show-hide.spec.js +0 -268
  460. package/src/directive/show-hide/show-hide.test.js +0 -12
  461. package/src/directive/style/style.html +0 -19
  462. package/src/directive/style/style.js +0 -27
  463. package/src/directive/style/style.md +0 -23
  464. package/src/directive/style/style.spec.js +0 -183
  465. package/src/directive/style/style.test.js +0 -12
  466. package/src/directive/switch/switch.html +0 -19
  467. package/src/directive/switch/switch.js +0 -133
  468. package/src/directive/switch/switch.md +0 -66
  469. package/src/directive/switch/switch.spec.js +0 -509
  470. package/src/directive/switch/switch.test.js +0 -12
  471. package/src/directive/transclude/transclude.js +0 -122
  472. package/src/directive/validators/validators.html +0 -22
  473. package/src/directive/validators/validators.js +0 -346
  474. package/src/directive/validators/validators.spec.js +0 -740
  475. package/src/directive/validators/validators.test.js +0 -12
  476. package/src/filters/filter.js +0 -213
  477. package/src/filters/filter.spec.js +0 -719
  478. package/src/filters/filters.html +0 -22
  479. package/src/filters/filters.js +0 -239
  480. package/src/filters/filters.spec.js +0 -36
  481. package/src/filters/filters.test.js +0 -12
  482. package/src/filters/interface.ts +0 -9
  483. package/src/filters/limit-to.js +0 -55
  484. package/src/filters/limit-to.spec.js +0 -252
  485. package/src/filters/order-by.js +0 -181
  486. package/src/filters/order-by.spec.js +0 -883
  487. package/src/index.js +0 -6
  488. package/src/index.spec.js +0 -11
  489. package/src/injection-tokens.js +0 -81
  490. package/src/interface.ts +0 -430
  491. package/src/ng.js +0 -291
  492. package/src/ng.spec.js +0 -45
  493. package/src/router/common/trace.js +0 -240
  494. package/src/router/directives/component-example.html +0 -37
  495. package/src/router/directives/state-directives.html +0 -22
  496. package/src/router/directives/state-directives.js +0 -393
  497. package/src/router/directives/state-directives.md +0 -435
  498. package/src/router/directives/state-directives.spec.js +0 -1091
  499. package/src/router/directives/state-directives.test.js +0 -10
  500. package/src/router/directives/view-directive.js +0 -489
  501. package/src/router/directives/view-directive.spec.js +0 -1921
  502. package/src/router/directives/view-directive.test.js +0 -10
  503. package/src/router/directives/view-directives.html +0 -22
  504. package/src/router/glob/glob.html +0 -19
  505. package/src/router/glob/glob.js +0 -102
  506. package/src/router/glob/glob.spec.js +0 -108
  507. package/src/router/glob/glob.test.js +0 -12
  508. package/src/router/hooks/core-resolvables.js +0 -38
  509. package/src/router/hooks/ignored-transition.js +0 -25
  510. package/src/router/hooks/invalid-transition.js +0 -14
  511. package/src/router/hooks/lazy-load.js +0 -104
  512. package/src/router/hooks/on-enter-exit-retain.js +0 -55
  513. package/src/router/hooks/redirect-to.js +0 -38
  514. package/src/router/hooks/resolve.js +0 -57
  515. package/src/router/hooks/update-globals.js +0 -34
  516. package/src/router/hooks/url.js +0 -34
  517. package/src/router/hooks/views.js +0 -41
  518. package/src/router/params/interface.ts +0 -626
  519. package/src/router/params/param-factory.js +0 -23
  520. package/src/router/params/param-type.js +0 -133
  521. package/src/router/params/param-types.js +0 -153
  522. package/src/router/params/param.js +0 -243
  523. package/src/router/params/state-params.js +0 -36
  524. package/src/router/path/path-node.js +0 -78
  525. package/src/router/path/path-utils.js +0 -207
  526. package/src/router/resolve/interface.ts +0 -208
  527. package/src/router/resolve/resolvable.js +0 -123
  528. package/src/router/resolve/resolve-context.js +0 -190
  529. package/src/router/router-test-hashbang.html +0 -45
  530. package/src/router/router-test.html +0 -41
  531. package/src/router/router.html +0 -22
  532. package/src/router/router.js +0 -54
  533. package/src/router/router.test.js +0 -12
  534. package/src/router/services.spec.js +0 -52
  535. package/src/router/state/interface.ts +0 -1007
  536. package/src/router/state/state-builder.js +0 -376
  537. package/src/router/state/state-builder.spec.js +0 -86
  538. package/src/router/state/state-matcher.js +0 -64
  539. package/src/router/state/state-object.js +0 -118
  540. package/src/router/state/state-queue-manager.js +0 -95
  541. package/src/router/state/state-registry.js +0 -262
  542. package/src/router/state/state-service.js +0 -687
  543. package/src/router/state/state.html +0 -23
  544. package/src/router/state/state.spec.js +0 -1002
  545. package/src/router/state/state.test.js +0 -12
  546. package/src/router/state/target-state.js +0 -162
  547. package/src/router/state/views.js +0 -195
  548. package/src/router/state-filter.spec.js +0 -139
  549. package/src/router/state-filters.js +0 -46
  550. package/src/router/template-factory.html +0 -19
  551. package/src/router/template-factory.js +0 -249
  552. package/src/router/template-factory.spec.js +0 -146
  553. package/src/router/template-factory.test.js +0 -12
  554. package/src/router/transition/hook-builder.js +0 -137
  555. package/src/router/transition/hook-registry.js +0 -181
  556. package/src/router/transition/interface.js +0 -18
  557. package/src/router/transition/interface.ts +0 -922
  558. package/src/router/transition/reject-factory.js +0 -122
  559. package/src/router/transition/transition-event-type.js +0 -26
  560. package/src/router/transition/transition-hook.js +0 -199
  561. package/src/router/transition/transition-service.js +0 -297
  562. package/src/router/transition/transition.js +0 -653
  563. package/src/router/url/url-config.js +0 -155
  564. package/src/router/url/url-matcher.js +0 -532
  565. package/src/router/url/url-rule.js +0 -231
  566. package/src/router/url/url-rules.js +0 -350
  567. package/src/router/url/url-service.js +0 -446
  568. package/src/router/url/url-service.spec.js +0 -1288
  569. package/src/router/url/url.html +0 -19
  570. package/src/router/url/url.test.js +0 -12
  571. package/src/router/view/interface.ts +0 -51
  572. package/src/router/view/view.html +0 -19
  573. package/src/router/view/view.js +0 -262
  574. package/src/router/view/view.spec.js +0 -100
  575. package/src/router/view/view.test.js +0 -12
  576. package/src/router/view-hook.spec.js +0 -215
  577. package/src/router/view-scroll.js +0 -33
  578. package/src/router/view-scroll.spec.js +0 -72
  579. package/src/services/anchor-scroll/anchor-scroll.html +0 -76
  580. package/src/services/anchor-scroll/anchor-scroll.js +0 -147
  581. package/src/services/exception/exception-handler.js +0 -75
  582. package/src/services/exception/interface.ts +0 -7
  583. package/src/services/http/http.html +0 -23
  584. package/src/services/http/http.js +0 -1109
  585. package/src/services/http/http.spec.js +0 -4320
  586. package/src/services/http/http.test.js +0 -11
  587. package/src/services/http/interface.ts +0 -256
  588. package/src/services/http/template-request.spec.js +0 -220
  589. package/src/services/location/interface.ts +0 -70
  590. package/src/services/location/location.html +0 -22
  591. package/src/services/location/location.js +0 -1006
  592. package/src/services/location/location.spec.js +0 -3792
  593. package/src/services/location/location.test.js +0 -12
  594. package/src/services/log/interface.ts +0 -39
  595. package/src/services/log/log.html +0 -19
  596. package/src/services/log/log.js +0 -74
  597. package/src/services/log/log.spec.js +0 -64
  598. package/src/services/log/log.test.js +0 -12
  599. package/src/services/pubsub/pubsub.html +0 -19
  600. package/src/services/pubsub/pubsub.js +0 -349
  601. package/src/services/pubsub/pubsub.spec.js +0 -400
  602. package/src/services/pubsub/pubsub.test.js +0 -12
  603. package/src/services/sce/sce.html +0 -19
  604. package/src/services/sce/sce.js +0 -852
  605. package/src/services/sce/sce.spec.js +0 -617
  606. package/src/services/sce/sce.test.js +0 -12
  607. package/src/services/template-cache/template-cache.html +0 -22
  608. package/src/services/template-cache/template-cache.js +0 -15
  609. package/src/services/template-cache/template-cache.spec.js +0 -134
  610. package/src/services/template-cache/template-cache.test.js +0 -12
  611. package/src/services/template-request/interface.ts +0 -23
  612. package/src/services/template-request/template-request.js +0 -142
  613. package/src/shared/cache.js +0 -7
  614. package/src/shared/common.js +0 -365
  615. package/src/shared/common.spec.js +0 -294
  616. package/src/shared/constants.js +0 -21
  617. package/src/shared/dom.js +0 -716
  618. package/src/shared/hof.js +0 -157
  619. package/src/shared/hof.spec.js +0 -60
  620. package/src/shared/interface.ts +0 -21
  621. package/src/shared/min-err.spec.js +0 -178
  622. package/src/shared/noderef.js +0 -225
  623. package/src/shared/predicates.js +0 -34
  624. package/src/shared/queue.js +0 -105
  625. package/src/shared/queue.spec.js +0 -80
  626. package/src/shared/shared.html +0 -24
  627. package/src/shared/shared.test.js +0 -12
  628. package/src/shared/strings.js +0 -142
  629. package/src/shared/strings.spec.js +0 -40
  630. package/src/shared/test-utils.js +0 -47
  631. package/src/shared/url-utils/interface.ts +0 -54
  632. package/src/shared/url-utils/url-utils.html +0 -22
  633. package/src/shared/url-utils/url-utils.js +0 -122
  634. package/src/shared/url-utils/url-utils.spec.js +0 -148
  635. package/src/shared/url-utils/url-utils.test.js +0 -12
  636. package/src/shared/utils.js +0 -1255
  637. package/src/shared/utils.spec.js +0 -178
  638. package/src/src.html +0 -21
  639. package/src/src.test.js +0 -10
  640. package/tsconfig.json +0 -19
  641. package/tsconfig.types.json +0 -14
  642. package/typedoc.json +0 -8
  643. package/utils/express.js +0 -203
  644. package/utils/version.cjs +0 -23
  645. 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
- });