vp_arth
vp_arth

Reputation: 14982

How to test angular $compile result?

I write simplified test to research how can I test compiled directives.
But I can't make it work:

    fit('debug compile', function(){
        var el = compile('<div></div>')(scope);

        backend.expectGET('/index.tpl');

        scope.name = 'World';
        scope.$digest();

        http.get('/index.tpl').success(function(html){
            expect(html).toBe('<h1>Hello, {{name}}!</h1>'); //ok
            var compiled = compile(html)(scope);
            expect(scope.name).toBe('World'); // ok
            expect(compiled.text()).toBe('Hello, World!'); // Expected 'Hello, {{name}}!' to be 'Hello, World!'
        });
        backend.flush();
    });

What happened here: $http receives correct template from $httpBackend.
But when I compile it with $compile it rendered without scope substitutions.

How achieve correct behavior here?

As you can see, scope variables not substitute here.
I tried to add scope.$digest after compile, but it gives me another error digest in progress.
I assume, this from $http scope.$apply call.

Upvotes: 0

Views: 1367

Answers (2)

Raulucco
Raulucco

Reputation: 3426

I Created a codepen with a directive test:

  it('assigns "anonimous" to the name', function() {
    var $scope = $rootScope.$new();
    var $el = $compile('<div test-dir></div>')(scope);
    $scope.$digest();
    expect($el.text()).toBe("Hello anonymous");
  });

Upvotes: 1

Estus Flask
Estus Flask

Reputation: 222493

Since it is not asynchronous code, unwrap the promise

var html;
http.get('/index.tpl').then(function(result){
    html = result;
});
backend.flush();

And only then

        var compiled = compile(html)(scope);
        scope.$digest();
        expect(scope.name).toBe('World');
        expect(compiled.text()).toBe('Hello, World!');

$http is redundant and doesn't have to be here at all, unless you wish to test Angular service (and you most probably don't).

Upvotes: 1

Related Questions