I have a directive, which should behave differently, depending on how much time passed since it's initialization:
am.directive('showText', () => ({
restrict: 'E',
replace: true,
scope: {
value: '@'
},
controller: ($scope, $timeout) => {
console.log('timeout triggered');
$scope.textVisible = false;
let visibilityCheckTimeout = $timeout(() => {
if (parseInt($scope.value, 10) < 100) {
$scope.textVisible = true;
}
}, 330);
// Clear timeout upon directive destruction
$scope.$on('$destroy', $timeout.cancel(visibilityCheckTimeout));
},
}));
The problem is, that when I'm trying to test it with Jasmine, I can't seem to find a way to trigger this timeout in any way. Already tried a $timeout.flush()
and $timeout.verifyNoPendingTasks()
(which actually throws an error, if I'll comment flush
call). But it's still not triggering that timeout's callback execution
describe('showText.', () => {
let $compile;
let $rootScope;
let $scope;
let $timeout;
const compileElement = (rootScope, value = 0) => {
$scope = rootScope.$new();
$scope.value = value;
const element = $compile(`
<show-text
value="value"
></show-text>
`)($scope);
$scope.$digest();
return element;
};
beforeEach(() => {
module('app.directives.showText');
inject((_$compile_, _$rootScope_, _$timeout_) => {
$compile = _$compile_;
$rootScope = _$rootScope_;
$timeout = _$timeout_;
});
});
it(`Process lasts > 0.33s. Should show text.`, () => {
const VALUE = 30;
const element = compileElement($rootScope, VALUE);
const elementContent = element.find('.show-text__content');
$timeout.flush(1000);
$timeout.verifyNoPendingTasks();
$rootScope.$digest();
expect(element.isolateScope().textVisible).toBeTruthy();
expect(elementContent.length).toEqual(1);
expect(elementContent.text().trim()).toBe('Example text');
});
});
Test fails.
Can't find what am I doing wrong. Any tips on how to properly test such a case?
Thanks.
UPD
After some investigation, I've found that in this particular test-case, in compileElement
function, value
property isn't being evaluated by $compile
service. And equals "value"
. I've used same function already 10th of times, and can't get, why it's not taking a $scope.value
's property as it was before.