1

Hi guys!

First of all, sorry for creating a new question for this issue but I am new on the site, and I can't comment yet. Despite that I've found questions on this site that gave answers that I could use, I've encountered another problem.


I'm testing an application which has translate functionality and it gave me an error:

Unknown provider: translateFilterProvider <- translateFilter

My directive looks like this:

cf-toplist-card.js

angular.module('cfPresentation.directives')
.directive('cfToplistCard',
[
'CFToplistCardController',
function(CFToplistCardController) {
    return {
        restrict: 'E',
        transclude: true,
        scope: {
            cfCardId: '=',
            cfRank: '=',
            cfColor: '=',
            cfId: '=',
            cfName: '=',
            cfPicUrl: '=',
            cfCurrentValueDesc: '=',
            cfCurrentValue: '=',
            cfTargetValue: '=',
            cfChange: '='        
        },
        controllerAs: 'vm',
        require: ['cfToplistCard'],
        bindToController: true,
        controller: CFToplistCardController,
        templateUrl: 'src/presentation/directives/toplistcard/cf-toplist-card.html',
        link: function(scope, element, attrs, controllers) {
            var vm = controllers[0];
        }
    };
}
])
.factory('CFToplistCardController',['$timeout', function($timeout) {
    function CFToplistCardController($element, $scope) {
       var vm = this;
       
       vm.element = $element;
        
       $scope.$on('$destroy', function() {
           delete vm.element;
       });
    }   

    CFToplistCardController.$inject = ['$element', '$scope'];

    return CFToplistCardController;
}]
);

cf-toplist-card.html

<div id="{{ vm.cfCardId }}" class="cf-toplist-card col-xs-12 col-md-12 col-lg-12">
    <div class="toplist row">
        <!--{{vm.cfColor}} should be used for border color!!! -->
        <div class="col-xs-6 col-md-2 col-lg-2 toplist-col1" style="border-left-color: {{vm.cfColor}}">
            <h1>{{vm.cfRank}}</h1>
        </div>
        <div class="col-xs-6 col-md-2 col-lg-2 toplist-col2">
            <div class="toplist-picture-block">
                <i class="toplist-picture-bg toplist-picture-radius"></i>
                <img alt=" " class="toplist-picture toplist-picture-radius" ng-src="{{ $root.backendBaseURL + vm.cfPicUrl + vm.cfId}} "/>
            </div>
        </div>
        <div class="col-xs-6 col-sm-6 col-md-4 col-lg-4 toplist-data">
            <div class="toplist-name toplist-value">
                {{vm.cfName}}
            </div>
            <div class="toplist-desc">
                {{ 'common.target' | translate }}
            </div>
            <div class="toplist-value">
                {{ vm.cfTargetValue | cfNumberFormat }}
            </div>
        </div> 
        <div class="col-xs-6 col-sm-6 col-md-4 col-lg-4 toplist-data toplist-float-right-td">
            <div class="toplist-desc">
                {{vm.cfCurrentValueDesc}}
            </div>
            <div class="toplist-value highlight">
                {{ vm.cfCurrentValue | cfNumberFormat }}
            </div>
            <div class="toplist-desc">
                {{ 'common.change' | translate }}
            </div>
            <div class="toplist-value">
                {{ vm.cfChange | cfNumberFormat }}
            </div>
        </div> 
    </div>
</div>     

And the test I've writen looks like this:

describe("test.spec.presentation.directives.toplistcard.cf-toplist-card", function () {

    var toplistController;
    var element;
    var $scope;
    var http;
    var template1;
    var url1 = "src/presentation/directives/toplistcard/cf-toplist-card.html";
    var $timeout;
    var $compile;
    var cache;
    
    beforeEach(module("cfPresentation.directives"));
    beforeEach(angular.mock.module("cfPresentation.services"));
    beforeEach(angular.mock.module("cfPresentation.filters"));
    beforeEach(angular.mock.module('ui.router'));
    var mockTranslateFilter;

    beforeEach(function() {
        module(function($provide) {
            $provide.value('translateFilter', mockTranslateFilter);
        });

        mockTranslateFilter = function(value) {
            return value;
        };
    });
    beforeEach(module('templates'));

    beforeEach(angular.mock.inject(['$timeout','$injector', '$compile', '$rootScope',  '$templateCache', function(_$timeout_, $injector,_$compile_, $rootScope, $templateCache) {
        $scope = $rootScope;
        $timeout = _$timeout_;
        http = $injector.get('$httpBackend');
        $compile = _$compile_;
        cache = $templateCache;
        
        element = $compile("<cf-toplist-card></cf-toplist-card>")($scope);
        
        template1 = cache.get('app/src/presentation/directives/toplistcard/cf-toplist-card.html');
        
        http.when('GET', url1).respond(template1);
        
        http.flush(); 

        $scope.$apply();
    }]));

    describe('CFToplistCardController', function() {
        beforeEach(function() {
            toplistController = element.find('.cf-toplist-card').controller('cfToplistCard');
        });
        
        it('should be defined', function() {
            expect(toplistController).toBeDefined();
        });
        
        it('should destroy on scope destroy', function() {
            expect(toplistController.element).toBeDefined();
            var isolateScope = element.find('.cf-toplist-card').scope();
            isolateScope.$destroy();
            expect(toplistController.element).not.toBeDefined();
        });
    });
});

So I've been reading on the articles on this site, and I've found some sort of solution to my question here. This is already in use in my test code above, and it runs successfully (I've tried lots of things, but this is the only which made my tests run).

My only problem is, that I have to run an eslint syntax check before commiting, and it gives me an error: You should use the array syntax for DI. I know it's a trivial problem, but even after I've read the Angular Docs, and tried thousand of implementation types, I couldn't find a proper solution, and I can't proceed without this.

So to make my question more specific: I'm in need of injecting this translate with the dependency injection's array syntax, instead of this:

var mockTranslateFilter;

    beforeEach(function() {
        module(function($provide) {
            $provide.value('translateFilter', mockTranslateFilter);
        });

        mockTranslateFilter = function(value) {
            return value;
        };
    });

Any help is highly appreciated!

Thanks, Szkíta

Community
  • 1
  • 1
Szkíta
  • 161
  • 1
  • 8

1 Answers1

1

So finally after a few hours of desperation, I've found a solution:

beforeEach(function() {
    module(['$provide', function($provide) {
        $provide.value('translateFilter', [function(value) {
            return value;
        }][0]
        );
    }]);
});

The problem was that eslint needed an array syntax for DI, but the actual function was not executed correctly, it always gave me a ... is not a function error. So in the working solution, I am putting the function inside an array, and right after I'm getting it out of it with [0], so everyone is happy.

Szkíta
  • 161
  • 1
  • 8