After creating a custom directive that adds a wrapper element conditionally, I noticed that while the directive works as expected in production, it fails during unit testing. The issue lies with the $animate.enter function not calling the callback, causing all unit tests to fail when the presence of the wrapper is unexpected.
My Angular.js version is 1.2.16 and for unit testing, I am using ngMock and ngAnimate. The problem arises when the code triggers the ngAnimate enter function but never executes the callback.
If you want to see the code, please visit this link. Uncomment the appSpec.js script tag to replicate the issue where the directive stops functioning correctly.
I am looking for guidance on how to ensure that $animate.enter calls my callback function during unit testing.
addWrapperIf.js
angular.module('myModule', ['ngAnimate'])
.directive('addWrapperIf', ['$animate', function($animate) {
return {
transclude: 'element',
priority: 1000,
restrict: 'A',
compile: function (element, attr, transclude) {
return function ($scope, $element, $attr) {
var childElement, childScope;
$scope.$watch($attr.addWrapperIf, function addWrapperIfWatchAction(value) {
if (childElement) {
$animate.leave(childElement);
childElement = undefined;
}
if (childScope) {
childScope.$destroy();
childScope = undefined;
}
// add the wrapper
if (value) {
childScope = $scope.$new();
transclude(childScope, function (clone) {
childElement = clone
$animate.enter(clone, $element.parent(), $element);
});
}
// remove the wrapper
else {
childScope = $scope.$new();
transclude(childScope, function (clone) {
$animate.enter(clone, $element.parent(), $element, function() {
childElement = clone.contents();
clone.replaceWith(clone.contents());
});
});
}
});
}
}
};
}]);
addWrapperIfSpec.js
var expect = chai.expect;
describe('addWrapperIf', function () {
var $template;
var $compile;
var $scope;
beforeEach(window.module('myModule'));
beforeEach(inject(function(_$compile_, $rootScope){
$compile = _$compile_;
$scope = $rootScope.$new();
}));
function compileDirective(template) {
$template = $compile(template)($scope)[0];
$scope.$apply();
}
it('should output the correct values with default options', function() {
compileDirective('<div add-wrapper-if="false"><span>child</span></div>');
console.log($template); // <div add-wrapper-if="false"><span>child</span></div>
});
});