1

I have searched for a very long time and found no solution. I'm new to karma/jasmine testing, but so far it has murdered my productivity. I tried to write my tests in a TDD way but I can't get the tests to work, even though the code does what I want.

I've got this directive that validates an input and displays an error on blur:

angular.module('myApp')
.directive('formValidate', function() {
    var message = {
        error: '',
        warning: '',
        notification: ''
    };

    return {
        link: function(scope, element, attrs) {
            scope.message = message;
            var formElements = element.find('input');
            for (var i = 0; i < formElements.length; i++) {
                switch (formElements[i].getAttribute('type')) {
                    case 'email':
                        validateEmail(scope, formElements[i]);
                        break;
                    case 'password':
                        validatePassword(scope, formElements[i]);
                    default:
                        break;
                }
            }
        }
    };

    function promptUser(scope, text) {
        scope.$apply(function() {
            scope.message.error = text;
        });
    }

    function validateEmail(scope, element) {
        var element = angular.element(element);
        element.bind('blur', function() {
            if (element.hasClass('ng-invalid-email')) {
                promptUser(scope, 'Invalid email format');
            } else {
                promptUser(scope, '');
            }
        });
    }

    function validatePassword (scope, element) {
        var element = angular.element(element);
        element.bind('blur', function() {
            if (element.hasClass('ng-invalid-minlength')) {
                promptUser(scope, 'Password must be at least 6 characters');
            } else {
                promptUser(scope, '');
            }
        });
    }
});

I am trying to test it with:

'use strict';

describe('formValidation directive', function() {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50;

beforeEach(module('myApp'));
beforeEach(module('ui.router'));

var $compile, $scope;

beforeEach(module('myApp'));
beforeEach(module('ui.router'));

beforeEach(inject(function(_$rootScope_, _$compile_) {
    $compile = _$compile_;
    $scope = _$rootScope_.$new();
}));

describe('register', function() {
    var $element, $controller, testForm, form;

    beforeEach(function() {
        testForm = angular.element('<form name="form" form-validate>' + '<p class="form-error">{{ message.error }}</p>' + '<input type="email" ng-model="register.email" name="email" placeholder="email">' + '<input type="password" ng-model="register.password" name="register-password" placeholder="password" ng-minlength="6">' + '<input type="password" ng-model="register.passwordVerify" name="password-verify" placeholder="password verify" ng-minlength="6">' + '<input type="submit" id="login-btn" value="Submit" >' + '</form>');

        $element = $compile(testForm)($scope);
        $scope.$digest();

    });


    describe('individual field', function() {
        it('adds correct content to error message', function() {
            //How can I set the value of an input here
            //And then trigger a blur event to run the directive
            var input = testForm.find('input')[0];
            var angInput = angular.element(input);
            angInput.val('test'); // I console.log'd this and it doesn't seem to do anything
            expect($scope.message.error === 'Invalid email format').toEqual(true);
        });
        it('does not add error if format is valid', function() {

        });
        it('unhides error element when valid', function() {

        });
    });

    describe('all fields', function() {

    });
});

I would really like to start working with angular TDD, but this is taking way too long.

Vikk
  • 617
  • 7
  • 17
  • what's the problems with those tests? do they give you any kind of errors? – Gianmarco Dec 08 '15 at 19:05
  • The "adds correct content to...." test fails. The expect() is not gonna work because when I call angInput.val(), it doesn't change anything. The input is still pristine and untouched. I suppose the real problem here is that I can't change the input value and make it dirty or invalid. – Vikk Dec 08 '15 at 21:06

1 Answers1

0

The important line you are after is:

angular.element(dirElementInput).val('Some text').trigger('input');

(got from Setting view value an input field in a unit test of an angular form directive)

Community
  • 1
  • 1
Max Donchenko
  • 160
  • 1
  • 2
  • 13