jeudi 25 février 2016

unit-test invoking of ngModelCtrl.$render in Directive

Trying to unit-test the invokement on ngModelCtrl.$render. Now by $setViewValue but actually I want to set a value on ng-model on the directive and test if $render is invoked.

The Directive:

angular.module('inputValidationBelow', []).directive('inputValidationBelow', function ($compile) {
    return {
        scope: {
            dataModel: '=ngModel',
            placeHolder: '@',
            identifier: '@',
            feedbackMessage: '@',
            type: '@'
        },
        templateUrl: 'scripts/directives/inputValidationBelow/inputValidationBelow.html',
        restrict: 'E',
        transclude: true,
        replace: false,
        require: ['ngModel', '^form'],
        link: function (scope, element, attrs, controllers) {

            scope.type = attrs.type;

            var ngModelController = controllers[0];

            ngModelController.$render = function () {
                if (typeof ngModelController.$viewValue !== 'undefined') {
                    scope.dataModel = ngModelController.$viewValue;
                }
            };
        }
    };
});

The unit test

it('should invoke ngModelCtrl.$render after changing value on ngModel from the outside (the view)', function () {
    var scope,
        element,
        ngModelCtrl,
        modelValue;

    scope = $rootScope.$new();
    element = angular.element('<form name="loginForm"><input-validation-below place-holder="foo"  feedback-message="bar" identifier="username" ng-model="login"></input-validation-below></form>');

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

    var ngModelCtrl = element.find('input-validation-below').controller('ngModel');

    modelValue = {username: 'SJV'};
    ngModelCtrl.$setViewValue(modelValue);

    scope.$digest();

    expect(scope.dataModel).toEqual(modelValue);
});

Test fails: Expected undefined to equal { username : 'SJV' }

I read this in the Angular docs:

Since ng-model does not do a deep watch, $render() is only invoked if the values of $modelValue and $viewValue are actually different from their previous value. If $modelValue or $viewValue are objects (rather than a string or number) then $render() will not be invoked if you only change a property on the objects.

But this confuses me a bit.

However, I need $render to be invoked ng-model being changed from the outside to make it as real life as possible AND for the code coverage its code-covered.

Question: could use some pointers on this.

Aucun commentaire:

Enregistrer un commentaire