JordyV JordyV - 3 months ago 23
AngularJS Question

Validate ng-pattern in Angular unit test

I have the following piece of HTML which is loaded dynamically with a switch case. There was no need to create separate directives for this, therefore we decided to do it this way.

<li ng-form="form">
<input name="number" type="number" ng-model="selectedCriterion.valueFrom" ng-pattern="selectedCriterion.regexPattern">
</li>


with the following unit test

describe('form', function() {
rootScope.selectedCriterion = { regexPattern: '[0-5]+' };

it('allows numbers to be filled in the input field', function() {
var compiledElement = $compile(html)(rootScope);
rootScope.$apply();
var form = rootScope.form;
var inputElement = compiledElement.find('input[name="number"]');

inputElement.val(4).triggerHandler('input');
rootScope.$digest();

expect(inputElement.val()).toEqual('4');
expect(form.$valid).toEqual(true);

inputElement.val(8).triggerHandler('input');
rootScope.$digest();

expect(inputElement.val()).toEqual('8');
expect(form.$valid).toEqual(false);
});
});


What I would like to do is test the ng-pattern in a unit test, not in on e2e test level.
The test fails at the last expectation

expect(form.$valid).toEqual(false);


It seems that the form cannot validate itself on this level, even though I compile my HTML and call a $digest cycle manually.

What am I doing wrong? Can I validate the form on this level?

Edit: I have intensively searched StackOverflow and Google for answers without success.

Answer

I found the problem. Like vbuhlev said, my code worked, but the reason it did not for me in the first place was because I had an extra attribute on my input element that I did not put in the initial post because I thought it was not important. My actual input element had a debounce option:

<input name="number" type="number" ng-model="selectedCriterion.valueFrom" ng-pattern="selectedCriterion.regexPattern" ng-model-options="{debounce: 200}" >

Karma did not take this into account by default, saw that my form was "valid" and just went on. I solved this by flushing any tasks that were still pending with

$timeout.flush()

Shit now runs smooth as fuck!

Comments