Here is the actual directive:
.directive('flattenTree', function () { return { restrict: 'E', template: "<li ng-repeat='node in tree' ng-transclude></li>", transclude: true, scope: { root: '=' }, link: function (scope) { scope.tree = []; var index = 0; var queue = []; queue.push(scope.root); while (queue.length != 0) { var node = queue.shift(); if (node['left']) { queue.unshift( node.right, node.left); } else { scope.tree.push(node); } } } }; });
When writing the tests I wanted to validate a few things.
1. If the root node is null then it doesn't display anything
2. That the root node is traversed correctly and all leaf nodes are displayed in order
3. That each node has a corresponding <li> tag and the html in the transclude is displayed for each one.
Here is what I came up for my test that is written with Jasmine.
My setup code in which I grab the angular objects that I need to run the tests.
var $compile, $rootScope; // Store references to $rootScope and $compile // so they are available to all tests in this describe block beforeEach(inject(function(_$compile_, _$rootScope_){ // The injector unwraps the underscores (_) from around the parameter names when matching $compile = _$compile_; $rootScope = _$rootScope_; }));
1. Setting up the data and the template I want to use (always using <flatten-tree> since that is my directive).
2. Compiling the template and calling $digest to make the angular magic work.
3. Validating the result & DOM with the jqlite that comes with angular.
it('replaces the element with null when empty', function() { // Compile a piece of HTML containing the directive var template = "<flatten-tree><span>{{node}}</span></flatten-tree>"; var element = $compile(template)($rootScope); // fire all the watches, so the scope expression will be evaluated $rootScope.$digest(); // Check that the compiled element contains the templated content expect(element.children().length).toBe(0); }); it('replaces the element with a single li when one node', function() { $rootScope.node = "foobar"; var template = "<ul><flatten-tree root='node'><span>{{node}}</span></flatten-tree></ul>"; // Compile a piece of HTML containing the directive var element = $compile(template)($rootScope); // fire all the watches, so the scope expression will be evaluated $rootScope.$digest(); // Check that the compiled element contains the templated content expect(element.find("li").length).toBe(1); expect(element.find("span").length).toBe(1); expect(element.find("span").text()).toBe("foobar"); }); it('traverses the tree and replaces the element with a list', function() { $rootScope.node = { right:{ right:1, left:2 }, left:{ right:{ right:3, left:4 }, left:{ right:5, left:6 } } }; var template = "<ul><flatten-tree root='node'><span>{{node}}</span></flatten-tree></ul>"; // Compile a piece of HTML containing the directive var element = $compile(template)($rootScope); // fire all the watches, so the scope expression will be evaluated $rootScope.$digest(); // Check that the compiled element contains the templated content expect(element.find("li").length).toBe(6); expect(element.find("span").length).toBe(6); var spanElements = element.find("span"); for (var i = 0; i < spanElements.length; i++) { expect(spanElements[i].innerText).toBe((i+1).toString()); } });Easy as pie!
No comments:
Post a Comment