我有一个指令,使用选择器克隆页面上的元素,并将克隆移动到页面上的其他位置:
(function() {
'use strict';
function ctAnimatedClone($timeout) {
var directive = {
restrict: 'E',
scope: {
visible: '=',
...
},
link: function(scope, element) {
...
function cloneAndAnimateElement() {
originalElement = angular.element(scope.elementSelector).first();
clone = originalElement.clone();
originalPosition = originalElement[0].getBoundingClientRect();
clone.addClass('easeIn');
originalElement.css({ visibility: 'hidden' });
element.prepend(clone);
var baseStyles = {
opacity: 0.5,
visibility: 'visible',
position: 'absolute'
};
var styles = angular.extend(baseStyles, clonePositioning());
clone.css(styles);
$timeout(function() {
clone.css({
opacity: 1.0,
position: 'absolute',
top: scope.clonedElementPositionOffset.top,
left: scope.clonedElementPositionOffset.left,
marginLeft: '-' + (originalPosition.width / 2) + 'px'
});
});
}
}
};
return directive;
}
angular
.module('crowdtap.animated-clone')
.directive('ctAnimatedClone', ctAnimatedClone);
})();
我正在尝试使用Jasmine测试它,但它失败了:TypeError:Cannot set property 'visible' of undefined
/* global expect */
/* global inject */
describe('animated clone directive', function() {
"use strict";
var $compile, $rootScope;
var elementHtml = "<div class='test-div'></div><ct-animated-clone visible='false' element-selector=\"'.test-div'\" cloned-element-position-offset=\"{ top: '50%', left: '50%' }\" fades-away-on-close='false' closed='false' stationary='false'></ct-animated-clone>";
//
beforeEach(function() {
module('crowdtap.animated-clone');
inject(function(_$compile_, _$rootScope_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
});
});
it('moves the element when visible changes from false to true', function() {
var element = $compile(elementHtml)($rootScope);
$rootScope.$digest();
var scope = element.isolateScope();
scope.visible = true; //<------------------------------------------------
scope.$apply();
expect(element.css()).toContain("top: 10%");
});
});
如何测试需要在页面上显示其他HTML元素的指令?
答案 0 :(得分:1)
我最终通过了这个测试:
describe('animated clone directive', function() {
"use strict";
var $compile, $rootScope, $timeout, elementHtml, element;
beforeEach(function() {
module('crowdtap.animated-clone');
inject(function(_$compile_, _$rootScope_, _$timeout_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$timeout = _$timeout_;
});
var dummyDiv = "<div class='test-div' style='width: 10px; position: absolute; top: 1px; left: 2px;'></div>";
angular.element('body').append(dummyDiv);
});
afterEach(function() {
angular.element('body > .test-div').remove();
});
...
describe('when stationary is false', function() {
beforeEach(function() {
elementHtml = "<ct-animated-clone visible='false' element-selector=\"'.test-div'\" cloned-element-position-offset=\"{ top: '50%', left: '50%' }\" fades-away-on-close='false' closed='false' stationary='false'></ct-animated-clone>";
element = $compile(elementHtml)($rootScope);
$rootScope.$digest();
var scope = element.isolateScope();
scope.visible = true;
scope.$apply();
});
it('first positions the clone on top of the element', function() {
var clone = element.children('.test-div');
var cloneStyles = clone.attr('style');
expect(cloneStyles).toContain("position: absolute");
expect(cloneStyles).toContain("top: 1px");
expect(cloneStyles).toContain("left: 2px");
expect(cloneStyles).toContain("margin-left: 0px");
expect(cloneStyles).toContain("opacity: 0.5");
});
});
});
});