1

When writing a Mocha/Chai test for an angular view, I've discovered that jqlite (since I'm not using jQuery), won't find top-level elements.

I've boiled this down to a simple example:

/* jshint expr:true */
describe( "View", function() {
    'use strict';

    var $compile, $rootScope;
    beforeEach( inject( function( _$compile_, _$rootScope_ ) {
            $compile = _$compile_;
            $rootScope = _$rootScope_;
    } ) );

    var view;
    beforeEach( function() {
        var html = "<div><span>div[0].span</span><p>div[0].p</p></div><div><h1>div[1].h1</h1><p>div[1].p</div>";
        view = $compile( angular.element( html ) )( $rootScope );
    } );

    it( "should find two p tags", function() {
        expect( view.find( "p" ).length ).to.equal( 2 );
    } );

    it( "should find one span tag", function() {
        expect( view.find( "span" ).length ).to.equal( 1 );
    } );

    it( "should find two div tags", function() {
        expect( view.find( "div" ).length ).to.equal( 2 );
    } );


} );

In this example, the first two tests pass, the third fails:

View
    ✓ should find two p tags
    ✓ should find one span tag
    ✗ should find two div tags
    AssertionError: expected 0 to equal 2
        at ...

This seems to be because the divs are top-level elements, the span and p tags are beneath them. If I enclose the whole thing in another tag, the third test will start to pass.

Why?

Geoffrey Wiseman
  • 5,459
  • 3
  • 34
  • 52
  • Note: With jQuery, at least, you would use [`.filter()`](http://api.jquery.com/filter/) to search elements within the collection (top-level). jqlite doesn't appear to define an equivalent of that method, by default. – Jonathan Lonowski Oct 09 '14 at 15:47

1 Answers1

1

.find only searches descendants so the answer will be 0.

From http://api.jquery.com/find/

Given a jQuery object that represents a set of DOM elements, the .find() method allows us to search through the descendants of these elements in the DOM tree and construct a new jQuery object from the matching elements. The .find() and .children() methods are similar, except that the latter only travels a single level down the DOM tree

Dreamwalker
  • 3,032
  • 4
  • 30
  • 60
  • Yeah, I knew .find() searches descendants, but I guess I was thinking of the view above more like a document than a set of matched elements -- so all of the tags feel like descendants. Changing perspectives helps -- it's really more like all of the top level elements in the compiled view are items in a set of matched elements, and .find() is searching its children. – Geoffrey Wiseman Oct 09 '14 at 16:01
  • So if I'm doing a view test and I want to locate a top-level element, I'm going to have to iterate through all the items in the angular.element and check their tag name, I guess? I don't see another way of getting what I want out of jqlite. – Geoffrey Wiseman Oct 09 '14 at 16:05
  • Yes I guess so. Or wrap test test template each time in a seperate div – Dreamwalker Oct 09 '14 at 18:46