Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

docs(guide/unit-testing): add info on testing element transclude directives #8197

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions docs/content/guide/unit-testing.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,80 @@ We inject the $compile service and $rootScope before each jasmine test. The $com
to render the aGreatEye directive. After rendering the directive we ensure that the directive has
replaced the content and "lidless, wreathed in flame, 2 times" is present.

### Testing Transclusion Directives

Directives that use transclusion are treated specially by the compiler. Before their compile
function is called, the contents of the directive's element are removed from the element and
provided via a transclusion function. The directive's template is then appended to the directive's
element, to which it can then insert the transcluded content into its template.


Before compilation:
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should include html after ```; same with below.

<div translude-directive>
Some transcluded content
</div>
```

After transclusion extraction:
```
<div transclude-directive></div>
```

After compilation:
```
<div transclude-directive>
Some Template
<span ng-transclude>Some transcluded content</span>
</div>
```

If the directive is using 'element' transclusion then the compiler will actually remove the
directive's entire element from the DOM and replace it with a comment node. The template is
then inserted "after" this comment node.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The template is then inserted "after" this comment node.

This is really just a convention we have in core, this isn't really enforced by anything. Explaining that might be a bit too complicated, though


Before compilation
```
<div element-transclude>
Some Content
</div>
```

After transclusion extraction
```
<!-- elementTransclude -->
```

After compilation:
```
<!-- elementTransclude -->
<div element-transclude>
Some Template
<span ng-transclude>Some transcluded content</span>
</div>
```

It is important to be aware of this when writing tests for directives that use 'element'
transclusion. If you place the directive on the root element of the DOM fragment that you
pass to {@link $compile}, then the DOM node returned from the linking function will be the
comment node and you will lose the ability to access the template and transcluded content.

```
var node = $compile('<div element-transclude></div>')($rootScope);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should include javascript after ```.

expect(node[0].nodeType).toEqual(node.COMMENT_NODE);
expect(node[1]).toBeUndefined();
```

To cope with this you simply ensure that your 'element' transclude directive is wrapped in an
element, such as a `<div>`.

```
var node = $compile('<div><div element-transclude></div></div>')($rootScope);
var contents = node.contents();
expect(contents[0].nodeType).toEqual(node.COMMENT_NODE);
expect(contents[1].nodeType).toEqual(node.ELEMENT_NODE);
```

### Testing Directives With External Templates

If your directive uses `templateUrl`, consider using
Expand Down
5 changes: 5 additions & 0 deletions src/ng/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,11 @@
* * `true` - transclude the content of the directive.
* * `'element'` - transclude the whole element including any directives defined at lower priority.
*
* <div class="alert alert-warning">
* **Note:** When testing an element transclude directive you must not place the directive at the root of the
* DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives
* Testing Transclusion Directives}.
* </div>
*
* #### `compile`
*
Expand Down