From 2f96fbd17577685bc013a4f7ced06664af253944 Mon Sep 17 00:00:00 2001 From: Oren Avissar Date: Thu, 4 Apr 2013 18:17:58 -0700 Subject: feat(ngIf): add directive to remove and recreate DOM elements This directive is adapted from ui-if in the AngularUI project and provides a complement to the ngShow/ngHide directives that only change the visibility of the DOM element and ngSwitch which does change the DOM but is more verbose. --- test/ng/directive/ngIfSpec.js | 191 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100755 test/ng/directive/ngIfSpec.js (limited to 'test/ng/directive/ngIfSpec.js') diff --git a/test/ng/directive/ngIfSpec.js b/test/ng/directive/ngIfSpec.js new file mode 100755 index 00000000..081ba5bf --- /dev/null +++ b/test/ng/directive/ngIfSpec.js @@ -0,0 +1,191 @@ +'use strict'; + +describe('ngIf', function () { + var $scope, $compile, element; + + beforeEach(inject(function ($rootScope, _$compile_) { + $scope = $rootScope.$new(); + $compile = _$compile_; + element = $compile('
')($scope); + })); + + afterEach(function () { + dealoc(element); + }); + + function makeIf(expr) { + element.append($compile('
Hi
')($scope)); + $scope.$apply(); + } + + it('should immediately remove element if condition is false', function () { + makeIf('false'); + expect(element.children().length).toBe(0); + }); + + it('should leave the element if condition is true', function () { + makeIf('true'); + expect(element.children().length).toBe(1); + }); + + it('should create then remove the element if condition changes', function () { + $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', function () { + $scope.$apply('value = true'); + element.append($compile( + '
' + )($scope)); + $scope.$apply(); + expect(element.children('div').length).toBe(1); + }); + + it('should play nice with other elements beside it', function () { + $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 restore the element to its compiled state', function() { + $scope.value = true; + makeIf('value'); + expect(element.children().length).toBe(1); + jqLite(element.children()[0]).removeClass('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'); + }); + +}); + +describe('ngIf ngAnimate', function () { + var vendorPrefix, window; + var body, element; + + function html(html) { + body.html(html); + element = body.children().eq(0); + return element; + } + + beforeEach(function() { + // we need to run animation on attached elements; + body = jqLite(document.body); + }); + + afterEach(function(){ + dealoc(body); + dealoc(element); + }); + + beforeEach(module(function($animationProvider, $provide) { + $provide.value('$window', window = angular.mock.createMockWindow()); + return function($sniffer, $animator) { + vendorPrefix = '-' + $sniffer.vendorPrefix + '-'; + $animator.enabled(true); + }; + })); + + it('should fire off the enter animation + add and remove the css classes', + inject(function($compile, $rootScope, $sniffer) { + var $scope = $rootScope.$new(); + var style = vendorPrefix + 'transition: 1s linear all'; + element = $compile(html( + '
' + + '
Hi
' + + '
' + ))($scope); + + $rootScope.$digest(); + $scope.$apply('value = true'); + + + expect(element.children().length).toBe(1); + var first = element.children()[0]; + + if ($sniffer.supportsTransitions) { + expect(first.className).toContain('custom-enter-setup'); + window.setTimeout.expect(1).process(); + expect(first.className).toContain('custom-enter-start'); + window.setTimeout.expect(1000).process(); + } else { + expect(window.setTimeout.queue).toEqual([]); + } + + expect(first.className).not.toContain('custom-enter-setup'); + expect(first.className).not.toContain('custom-enter-start'); + })); + + it('should fire off the leave animation + add and remove the css classes', + inject(function ($compile, $rootScope, $sniffer) { + var $scope = $rootScope.$new(); + var style = vendorPrefix + 'transition: 1s linear all'; + element = $compile(html( + '
' + + '
Hi
' + + '
' + ))($scope); + $scope.$apply('value = true'); + + expect(element.children().length).toBe(1); + var first = element.children()[0]; + + if ($sniffer.supportsTransitions) { + window.setTimeout.expect(1).process(); + window.setTimeout.expect(1000).process(); + } else { + expect(window.setTimeout.queue).toEqual([]); + } + + $scope.$apply('value = false'); + expect(element.children().length).toBe($sniffer.supportsTransitions ? 1 : 0); + + if ($sniffer.supportsTransitions) { + expect(first.className).toContain('custom-leave-setup'); + window.setTimeout.expect(1).process(); + expect(first.className).toContain('custom-leave-start'); + window.setTimeout.expect(1000).process(); + } else { + expect(window.setTimeout.queue).toEqual([]); + } + + expect(element.children().length).toBe(0); + })); + + it('should catch and use the correct duration for animation', + inject(function ($compile, $rootScope, $sniffer) { + var $scope = $rootScope.$new(); + var style = vendorPrefix + 'transition: 0.5s linear all'; + element = $compile(html( + '
' + + '
Hi
' + + '
' + ))($scope); + $scope.$apply('value = true'); + + if ($sniffer.supportsTransitions) { + window.setTimeout.expect(1).process(); + window.setTimeout.expect(500).process(); + } else { + expect(window.setTimeout.queue).toEqual([]); + } + })); + +}); -- cgit v1.2.3