I\'ve created an edit directive to wrap an html input in a fancy frame.
Now I\'m creating a unit test to check that once I type in the input the dirty state of the f
From an answer to a similar question:
The mistake you're making is what you're expecting the jQuery's trigger method to do. If you check out the code you'll see that what it is doing is actually executing the jQuery registered event handlers not the DOM Level 3 events. Because it's only executing jQuery handlers you wont be causing the change event which is what you need to be triggered to update the value property of the textbox.
Instead you can update the input's value and trigger the change or the input event:
input.val('x').trigger('input');
When doing this inside a controller in a live application however (as opposed to in the unit test environment), you need to break out of the $digest cycle, or you will get the $apply already in progress
error.
You can do this by for example using setTimeout
:
$scope.trigger = function() {
setTimeout(function() {
$('input').val('x').trigger('input');
});
};
You also need to make sure that you are loading jQuery before AngularJS. If you don't, Angular will use jqLite instead. jqLite uses addEventHandler
to register event handlers, and handlers registered this way don't get triggered by jQuery's trigger
function.
Demo of your code updated: http://plnkr.co/edit/u3ZWXWLvOjbKWlY8JEM5?p=preview
When unit testing:
it('should work', function() {
var element = $compile('<form name="form"><edit ng-model="name"></edit></form>')($scope);
$rootScope.$digest();
var scope = element.scope(),
form = scope.form,
input = element.find('input');
expect(form.$dirty).toBe(false);
input.val('x').trigger('input');
expect(form.$dirty).toBe(true);
});
Demo of the unit test: http://plnkr.co/edit/Emc3dIlDaxXyE9U6dEG6?p=preview