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

package.src.directive.if.if.spec.js Maven / Gradle / Ivy

import { dealoc, JQLite } from "../../shared/jqlite/jqlite";
import { valueFn } from "../../shared/utils";
import { Angular } from "../../loader";
import { wait } from "../../shared/test-utils";

describe("ngIf", () => {
  describe("basic", () => {
    let $scope;
    let $compile;
    let element;
    let $compileProvider;
    let $rootScope;
    let injector;
    let angular;

    beforeEach(function () {
      angular = new Angular();
      window.angular = new Angular();
      window.angular.module("test", []);
      injector = window.angular.bootstrap(document.getElementById("dummy"), [
        "test",
        function (_$compileProvider_) {
          $compileProvider = _$compileProvider_;
        },
      ]);
      injector.invoke((_$rootScope_, _$compile_) => {
        $rootScope = _$rootScope_;
        $scope = $rootScope.$new();
        $compile = _$compile_;
        element = $compile("
")($scope); }); }); afterEach(() => { dealoc(element); }); function makeIf() { Array.from(arguments).forEach((expr) => { element.append( $compile(`
Hi
`)( $scope, ), ); }); $scope.$apply(); } it("should immediately remove the element if condition is falsy", () => { makeIf("false", "undefined", "null", "NaN", "''", "0"); expect(element.children().length).toBe(0); }); it("should leave the element if condition is true", () => { makeIf("true"); expect(element.children().length).toBe(1); }); it("should leave the element if the condition is a non-empty string", () => { makeIf("'f'", "'0'", "'false'", "'no'", "'n'", "'[]'"); expect(element.children().length).toBe(6); }); it("should leave the element if the condition is an object", () => { makeIf("[]", "{}"); expect(element.children().length).toBe(2); }); it("should not add the element twice if the condition goes from true to true", () => { $scope.hello = "true1"; makeIf("hello"); expect(element.children().length).toBe(1); $scope.$apply('hello = "true2"'); expect(element.children().length).toBe(1); }); it("should not recreate the element if the condition goes from true to true", () => { $scope.hello = "true1"; makeIf("hello"); element.children().data("flag", true); $scope.$apply('hello = "true2"'); expect(element.children().data("flag")).toBe(true); }); it("should create then remove the element if condition changes", () => { $scope.hello = true; makeIf("hello"); expect(element.children().length).toBe(1); $scope.$apply("hello = false"); expect(element.children().length).toBe(0); }); it("should create a new scope every time the expression evaluates to true", () => { $scope.$apply("value = true"); element.append( $compile( '
', )($scope), ); $scope.$apply(); expect(element.children("div").length).toBe(1); }); it("should destroy the child scope every time the expression evaluates to false", () => { $scope.value = true; element.append($compile('
')($scope)); $scope.$apply(); const childScope = $scope.$$childHead; let destroyed = false; childScope.$on("$destroy", () => { destroyed = true; }); $scope.value = false; $scope.$apply(); expect(destroyed).toBe(true); }); it("should play nice with other elements beside it", () => { $scope.values = [1, 2, 3, 4]; element.append( $compile( '
' + '
' + '
', )($scope), ); $scope.$apply(); expect(element.children().length).toBe(9); $scope.$apply("values.splice(0,1)"); expect(element.children().length).toBe(6); $scope.$apply("values.push(1)"); expect(element.children().length).toBe(9); }); it("should play nice with ngInclude on the same element", (done) => { element = JQLite( `
`, ); window.angular.module("myModule", []).run(($rootScope) => { $rootScope.value = "first"; }); injector = angular.bootstrap(element, ["myModule"]); setTimeout(() => { expect(element.text()).toBe("Hello"); done(); }, 300); }); it("should work with multiple elements", () => { $scope.show = true; $scope.things = [1, 2, 3]; element.append( $compile( "
before;
" + '
start;
' + '
{{thing}};
' + "
end;
" + "
after;
", )($scope), ); $scope.$apply(); expect(element.text()).toBe("before;start;1;2;3;end;after;"); $scope.things.push(4); $scope.$apply(); expect(element.text()).toBe("before;start;1;2;3;4;end;after;"); $scope.show = false; $scope.$apply(); // expect(element.text()).toBe("before;after;"); }); it("should restore the element to its compiled state", () => { $scope.value = true; makeIf("value"); expect(element.children().length).toBe(1); element.children()[0].classList.remove("my-class"); expect(element.children()[0].className).not.toContain("my-class"); $scope.$apply("value = false"); expect(element.children().length).toBe(0); $scope.$apply("value = true"); expect(element.children().length).toBe(1); expect(element.children()[0].className).toContain("my-class"); }); it("should work when combined with an ASYNC template that loads after the first digest", async () => { $compileProvider.directive("test", () => ({ templateUrl: "/public/test.html", })); element.append('
'); $compile(element)($rootScope); $rootScope.show = true; expect(element.text()).toBe(""); $rootScope.$apply(); expect(element.text()).toBe(""); await wait(100); expect(element.text()).toBe("hello"); $rootScope.show = false; $rootScope.$apply(); expect(element.children().length).toBe(0); expect(element.text()).toBe(""); }); it("should not trigger a digest when the element is removed", () => { const spy = spyOn($rootScope, "$digest").and.callThrough(); $scope.hello = true; makeIf("hello"); expect(element.children().length).toBe(1); $scope.$apply("hello = false"); spy.calls.reset(); expect(element.children().length).toBe(0); expect(spy).not.toHaveBeenCalled(); }); describe("and transcludes", () => { it("should allow access to directive controller from children when used in a replace template", () => { let controller; const { directive } = $compileProvider; directive( "template", valueFn({ template: '
', replace: true, controller() { this.flag = true; }, }), ); directive( "test", valueFn({ require: "^template", link(scope, el, attr, ctrl) { controller = ctrl; }, }), ); $compile("
")($rootScope); $rootScope.$apply(); expect(controller.flag).toBe(true); }); it("should use the correct transcluded scope", () => { $compileProvider.directive( "iso", valueFn({ link(scope) { scope.val = "value in iso scope"; }, restrict: "E", transclude: true, template: '
val={{val}}-
', scope: {}, }), ); $rootScope.val = "transcluded content"; const element = $compile('')( $rootScope, ); expect(element.text().trim()).toEqual( "val=value in iso scope-transcluded content", ); }); }); }); });




© 2015 - 2025 Weber Informatics LLC | Privacy Policy