All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.src.directive.model-options.model-options.spec.js Maven / Gradle / Ivy

import { defaultModelOptions } from "./model-options";
import { dealoc, JQLite } from "../../shared/jqlite/jqlite";
import { Angular } from "../../loader";
import { createInjector } from "../../core/di/injector";
import { valueFn } from "../../shared/utils";

function changeGivenInputTo(inputElm, val) {
  inputElm[0].value = val;
  inputElm[0].dispatchEvent(new Event("change"));
}

function browserTrigger(inputElm, event) {
  inputElm[0].dispatchEvent(new Event(event));
}

describe("ngModelOptions", () => {
  describe("defaultModelOptions", () => {
    it("should provide default values", () => {
      expect(defaultModelOptions.getOption("updateOn")).toEqual("");
      expect(defaultModelOptions.getOption("updateOnDefault")).toEqual(true);
      expect(defaultModelOptions.getOption("debounce")).toBe(0);
      expect(defaultModelOptions.getOption("getterSetter")).toBe(false);
      expect(defaultModelOptions.getOption("allowInvalid")).toBe(false);
      //expect(defaultModelOptions.getOption("timezone")).toBe(null);
    });
  });

  describe("directive", () => {
    describe("basic usage", () => {
      let $rootScope;
      let $compile;
      let $timeout;
      let $q;
      let inputElm;
      let formElm;
      let injector;

      beforeEach(() => {
        window.angular = new Angular();
        window.angular
          .module("myModule", ["ng"])
          .decorator("$exceptionHandler", function () {
            return (exception, cause) => {
              throw new Error(exception.message);
            };
          });
        injector = window.angular.bootstrap(document.getElementById("dummy"), [
          "myModule",
        ]);
        $compile = injector.get("$compile");
        $rootScope = injector.get("$rootScope");
      });

      describe("should fall back to `defaultModelOptions`", () => {
        it("if there is no `ngModelOptions` directive", () => {
          formElm = $compile(
            '
', )($rootScope); inputElm = formElm.find("input"); const inputOptions = $rootScope.form.alias.$options; expect(inputOptions.getOption("updateOn")).toEqual( defaultModelOptions.getOption("updateOn"), ); expect(inputOptions.getOption("updateOnDefault")).toEqual( defaultModelOptions.getOption("updateOnDefault"), ); expect(inputOptions.getOption("debounce")).toEqual( defaultModelOptions.getOption("debounce"), ); expect(inputOptions.getOption("getterSetter")).toEqual( defaultModelOptions.getOption("getterSetter"), ); expect(inputOptions.getOption("allowInvalid")).toEqual( defaultModelOptions.getOption("allowInvalid"), ); expect(inputOptions.getOption("timezone")).toEqual( defaultModelOptions.getOption("timezone"), ); }); it("if `ngModelOptions` on the same element does not specify the option", () => { formElm = $compile( '
', )($rootScope); inputElm = formElm.find("input"); const inputOptions = $rootScope.form.alias.$options; expect(inputOptions.getOption("debounce")).toEqual( defaultModelOptions.getOption("debounce"), ); expect(inputOptions.getOption("updateOnDefault")).toBe(false); expect(inputOptions.getOption("updateOnDefault")).not.toEqual( defaultModelOptions.getOption("updateOnDefault"), ); }); it("if the first `ngModelOptions` ancestor does not specify the option", () => { const form = $compile( '
' + '' + "
", )($rootScope); const inputOptions = $rootScope.form.alias.$options; expect(inputOptions.getOption("debounce")).toEqual( defaultModelOptions.getOption("debounce"), ); expect(inputOptions.getOption("updateOnDefault")).toBe(false); expect(inputOptions.getOption("updateOnDefault")).not.toEqual( defaultModelOptions.getOption("updateOnDefault"), ); dealoc(form); }); }); describe("sharing and inheritance", () => { it("should not inherit options from ancestor `ngModelOptions` directives by default", () => { const container = $compile( '
' + "
" + "" + "
" + "
", )($rootScope); const form = container.find("form"); const input = container.find("input"); const containerOptions = container.controller("ngModelOptions").$options; const formOptions = form.controller("ngModelOptions").$options; const inputOptions = input.controller("ngModelOptions").$options; expect(containerOptions.getOption("allowInvalid")).toEqual(true); expect(formOptions.getOption("allowInvalid")).toEqual(false); expect(inputOptions.getOption("allowInvalid")).toEqual(false); expect(containerOptions.getOption("updateOn")).toEqual(""); expect(containerOptions.getOption("updateOnDefault")).toEqual(true); expect(formOptions.getOption("updateOn")).toEqual("blur"); expect(formOptions.getOption("updateOnDefault")).toEqual(false); expect(inputOptions.getOption("updateOn")).toEqual(""); expect(inputOptions.getOption("updateOnDefault")).toEqual(true); dealoc(container); }); it('should inherit options that are marked with "$inherit" from the nearest ancestor `ngModelOptions` directive', () => { const container = $compile( '
' + "
" + "" + "
" + "
", )($rootScope); const form = container.find("form"); const input = container.find("input"); const containerOptions = container.controller("ngModelOptions").$options; const formOptions = form.controller("ngModelOptions").$options; const inputOptions = input.controller("ngModelOptions").$options; expect(containerOptions.getOption("allowInvalid")).toEqual(true); expect(formOptions.getOption("allowInvalid")).toEqual(true); expect(inputOptions.getOption("allowInvalid")).toEqual(false); expect(containerOptions.getOption("updateOn")).toEqual(""); expect(containerOptions.getOption("updateOnDefault")).toEqual(true); expect(formOptions.getOption("updateOn")).toEqual("blur"); expect(formOptions.getOption("updateOnDefault")).toEqual(false); expect(inputOptions.getOption("updateOn")).toEqual(""); expect(inputOptions.getOption("updateOnDefault")).toEqual(true); dealoc(container); }); it('should inherit all unspecified options if the options object contains a `"*"` property with value "$inherit"', () => { const container = $compile( "
" + "
" + "" + "
" + "
", )($rootScope); const form = container.find("form"); const input = container.find("input"); const containerOptions = container.controller("ngModelOptions").$options; const formOptions = form.controller("ngModelOptions").$options; const inputOptions = input.controller("ngModelOptions").$options; expect(containerOptions.getOption("allowInvalid")).toEqual(true); expect(formOptions.getOption("allowInvalid")).toEqual(true); expect(inputOptions.getOption("allowInvalid")).toEqual(false); expect(containerOptions.getOption("debounce")).toEqual(100); expect(formOptions.getOption("debounce")).toEqual(100); expect(inputOptions.getOption("debounce")).toEqual(0); expect(containerOptions.getOption("updateOn")).toEqual("keyup"); expect(containerOptions.getOption("updateOnDefault")).toEqual(false); expect(formOptions.getOption("updateOn")).toEqual("blur"); expect(formOptions.getOption("updateOnDefault")).toEqual(false); expect(inputOptions.getOption("updateOn")).toEqual(""); expect(inputOptions.getOption("updateOnDefault")).toEqual(true); dealoc(container); }); it("should correctly inherit default and another specified event for `updateOn`", () => { const container = $compile( "
" + "" + "
", )($rootScope); const input = container.find("input"); const inputOptions = input.controller("ngModelOptions").$options; expect(inputOptions.getOption("updateOn")).toEqual("blur"); expect(inputOptions.getOption("updateOnDefault")).toEqual(true); dealoc(container); }); it('should `updateOnDefault` as well if we have `updateOn: "$inherit"`', () => { const container = $compile( "
" + "" + "
" + "" + "
" + "
", )($rootScope); const input1 = container.find("input").eq(0); const inputOptions1 = input1.controller("ngModelOptions").$options; expect(inputOptions1.getOption("updateOn")).toEqual("keyup"); expect(inputOptions1.getOption("updateOnDefault")).toEqual(false); const input2 = container.find("input").eq(1); const inputOptions2 = input2.controller("ngModelOptions").$options; expect(inputOptions2.getOption("updateOn")).toEqual("blur"); expect(inputOptions2.getOption("updateOnDefault")).toEqual(true); dealoc(container); }); it("should make a copy of the options object", () => { $rootScope.options = { updateOn: "default" }; inputElm = $compile( '
", )($rootScope); expect($rootScope.options).toEqual({ updateOn: "default" }); expect($rootScope.form.alias.$options).not.toBe($rootScope.options); }); it("should be retrieved from an ancestor element containing an `ngModelOptions` directive", (done) => { const doc = $compile( '" + '' + "
", )($rootScope); inputElm = doc.find("input"); changeGivenInputTo(inputElm, "a"); expect($rootScope.name).toEqual(undefined); browserTrigger(inputElm, "blur"); expect($rootScope.name).toBeUndefined(); setTimeout(() => { expect($rootScope.name).toBeUndefined(); }, 50); setTimeout(() => { expect($rootScope.name).toEqual("a"); done(); }, 200); }); it("should allow sharing options between multiple inputs", () => { $rootScope.options = { updateOn: "default" }; inputElm = $compile( '" + '", )($rootScope); changeGivenInputTo(inputElm.eq(0), "a"); changeGivenInputTo(inputElm.eq(1), "b"); expect($rootScope.name1).toEqual("a"); expect($rootScope.name2).toEqual("b"); }); }); describe("updateOn", () => { it("should allow overriding the model update trigger event on text inputs", () => { inputElm = $compile( '", )($rootScope); changeGivenInputTo(inputElm, "a"); expect($rootScope.name).toBeUndefined(); browserTrigger(inputElm, "blur"); expect($rootScope.name).toEqual("a"); }); it("should not dirty the input if nothing was changed before updateOn trigger", () => { formElm = $compile( '
", )($rootScope); inputElm = formElm.find("input"); expect($rootScope.form.alias.$pristine).toBeTruthy(); browserTrigger(inputElm, "blur"); expect($rootScope.form.alias.$pristine).toBeTruthy(); }); it("should allow overriding the model update trigger event on text areas", () => { inputElm = $compile( '