0

I'm using Videogular in an Angular app I'm working on. I wrote a plugin directive for it that listens to an event broadcast from $rootScope, and, if a video is playing, automatically pauses it when the event is broadcast.

omgYesDirectives.directive('vgAutoPause',
        ['$rootScope',
                function($rootScope) {
                        return {
                                restrict: 'E',
                                require: '^videogular',
                                link: function($scope, $elem, $attr, $API) {

                                        $rootScope.$on('onGameEnable', onGameEnable);

                                        function onGameEnable(event, data)
                                        {
                                                $API.pause();
                                        }
                                }
                        }
                }
        ]);

But I'm having trouble figuring out how to unit test it. I can't seem to properly inject Videogular itself into my test. I've tried variations on this:

describe('vgAutoPause', function () {
        var scope, compile, elm, videogular;

        beforeEach(inject(function ($compile, $rootScope, videogularDirective) {
                videogular = videogularDirective;
                scope = $rootScope.$new();
                compile = $compile;
        }));

        it('should instantiate as an HTML element', function () {
                elm = compile('<videogular><vg-auto-pause></vg-auto-pause></videogular>')(scope);
                scope.$digest();
                expect(elm.html()).toContain('vg-auto-pause');
        });
});

but Karma keeps complaining about it:

Error: [$injector:unpr] Unknown provider: videogularDirectiveProvider <- videogularDirective

Am I doing it wrong? Do you have any thoughts or suggestions on what I ought to be doing instead?

kage23
  • 51
  • 3

1 Answers1

0

In AngularJS You can't inject a directive, you must create the HTML and then $compile it to start the $digest cycle.

For example, this is a simple videogular testing:

'use strict';
describe('Directive: Videogular', function () {
    var element;
    var scope;

    beforeEach(module('myApp'));

    beforeEach(inject(function ($compile, $rootScope) {
        scope = $rootScope;
        element = angular.element("<div><videogular><video></video></videogular></div>");
        $compile(element)($rootScope);
    }));

    describe("videogular", function() {
        it("should have videogular", function() {
            scope.$digest();
            expect(element.html()).toContain('<video></video>');
        });
    });
});

Maybe you need to understand first how to test directives, there's a lot of good info out there. You can start with this links:

elecash
  • 925
  • 7
  • 11
  • Maybe I'm still missing something. I am creating and $compiling HTML; I'm just doing it in the it() block instead of the beforeEach(). That shouldn't make any difference, though, should it? The problem is that my directive is a plugin for videogular, but I don't know how to provide videogular to the unit test. If I don't inject Videogular, Karma complains: > Error: [$compile:ctreq] Controller 'videogular', required by directive 'vgAutoPause', can't be found! But if I do inject Videogular, it still complains: > Error: [$injector:unpr] Unknown provider: videogularProvider <- videogular – kage23 Mar 17 '14 at 17:52
  • You probably need to $compile videogular in the beforeEach() and add your directive (plugin) to videogular in the it(). You should add the HTML first and then $compile to start the $digest cycle correctly. – elecash Mar 18 '14 at 09:58
  • `$compile` function doesn't start a digest cycle per se. You need to call `scope.$digest` explicitly for that. – demisx Oct 26 '14 at 16:54