@@ 41,3 41,30 @@ test('assigns to scope', () => {
'Unable to find an element with the text: Hello World.',
)
})
+
+test('throws on unknown custom elements', () => {
+ angular.module('atl').component('atlParent', {
+ template: `
+ <h1>Hi</hz>
+ <atl-child></atl-child>
+ `,
+ })
+
+ expect(() => render(`<atl-parent></atl-parent>`)).toThrow(
+ 'Unknown component/directive "ATL-CHILD"',
+ )
+})
+
+test('suppresses unknown custom elements error', () => {
+ angular.module('atl').component('atlParent', {
+ template: `
+ <h1>Hi</hz>
+ <atl-child></atl-child>
+ `,
+ })
+
+ const {container} = render(`<atl-parent></atl-parent>`, {
+ ignoreUnknownElements: true,
+ })
+ expect(container.querySelector('atl-child')).toBeDefined()
+})
@@ 10,7 10,16 @@ import {
const mountedContainers = new Set()
const mountedScopes = new Set()
-function render(ui, {container, baseElement = container, queries, scope} = {}) {
+function render(
+ ui,
+ {
+ container,
+ baseElement = container,
+ queries,
+ scope,
+ ignoreUnknownElements,
+ } = {},
+) {
if (!baseElement) {
// default to document.body instead of documentElement to avoid output of potentially-large
// head elements (such as JSS style blocks) in debug output
@@ 37,6 46,10 @@ function render(ui, {container, baseElement = container, queries, scope} = {}) {
$scope.$digest()
+ if (!ignoreUnknownElements) {
+ assertNoUnknownElements(container)
+ }
+
return {
container,
baseElement,
@@ 85,6 98,26 @@ function cleanupScope(scope) {
mountedScopes.delete(scope)
}
+function toCamel(s) {
+ return s
+ .toLowerCase()
+ .replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())
+}
+
+function assertNoUnknownElements(element) {
+ const {tagName} = element
+ if (tagName.includes('-')) {
+ const $injector = getAngularService('$injector')
+ const directiveName = `${toCamel(tagName)}Directive`
+ if (!$injector.has(directiveName)) {
+ throw Error(
+ `Unknown component/directive "${tagName}". Are you missing an import?`,
+ )
+ }
+ }
+ Array.from(element.children).forEach(assertNoUnknownElements)
+}
+
function getAngularService(name) {
let service
angular.mock.inject([