From a46ddf5db19c541f6a0c06edca8b7cd338dda306 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Fri, 10 Apr 2020 00:13:51 +0300 Subject: [PATCH] feat: add projectContent method to DomInsertionService --- .../src/lib/services/dom-insertion.service.ts | 14 +++- .../lib/tests/dom-insertion.service.spec.ts | 66 +++++++++++++++++-- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts b/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts index f1a59e4e43..5e53a64995 100644 --- a/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/dom-insertion.service.ts @@ -1,10 +1,13 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Injector, TemplateRef, Type } from '@angular/core'; import { ContentStrategy } from '../strategies/content.strategy'; +import { ProjectionStrategy } from '../strategies/projection.strategy'; import { generateHash } from '../utils'; @Injectable({ providedIn: 'root' }) export class DomInsertionService { - readonly inserted = new Set(); + readonly inserted = new Set(); + + constructor(private injector: Injector) {} insertContent(contentStrategy: ContentStrategy) { const hash = generateHash(contentStrategy.content); @@ -14,4 +17,11 @@ export class DomInsertionService { contentStrategy.insertElement(); this.inserted.add(hash); } + + projectContent | TemplateRef>( + projectionStrategy: ProjectionStrategy, + injector = this.injector, + ) { + return projectionStrategy.injectContent(injector); + } } diff --git a/npm/ng-packs/packages/core/src/lib/tests/dom-insertion.service.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/dom-insertion.service.spec.ts index 2570636197..8ae75c2f15 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/dom-insertion.service.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/dom-insertion.service.spec.ts @@ -1,15 +1,71 @@ +import { Component, ComponentRef, NgModule } from '@angular/core'; import { createServiceFactory, SpectatorService } from '@ngneat/spectator'; import { DomInsertionService } from '../services'; -import { CONTENT_STRATEGY } from '../strategies'; +import { CONTENT_STRATEGY, PROJECTION_STRATEGY } from '../strategies'; describe('DomInsertionService', () => { + @Component({ template: '
bar
' }) + class TestComponent {} + + // createServiceFactory does not accept entryComponents directly + @NgModule({ + declarations: [TestComponent], + entryComponents: [TestComponent], + }) + class TestModule {} + let spectator: SpectatorService; - const createService = createServiceFactory(DomInsertionService); + const createService = createServiceFactory({ + service: DomInsertionService, + imports: [TestModule], + }); + let styleElements: NodeListOf; beforeEach(() => (spectator = createService())); - it('should be insert an element', () => { - spectator.service.insertContent(CONTENT_STRATEGY.AppendStyleToHead('.test {}')); - expect(spectator.service.inserted.has(1437348290)).toBe(true); + afterEach(() => styleElements.forEach(element => element.remove())); + + describe('#insertContent', () => { + it('should be able to insert given content', () => { + spectator.service.insertContent(CONTENT_STRATEGY.AppendStyleToHead('.test {}')); + styleElements = document.head.querySelectorAll('style'); + expect(styleElements.length).toBe(1); + expect(styleElements[0].textContent).toBe('.test {}'); + }); + + it('should insert only once', () => { + expect(spectator.service.inserted.has(1437348290)).toBe(false); + + spectator.service.insertContent(CONTENT_STRATEGY.AppendStyleToHead('.test {}')); + styleElements = document.head.querySelectorAll('style'); + + expect(styleElements.length).toBe(1); + expect(styleElements[0].textContent).toBe('.test {}'); + expect(spectator.service.inserted.has(1437348290)).toBe(true); + + spectator.service.insertContent(CONTENT_STRATEGY.AppendStyleToHead('.test {}')); + styleElements = document.head.querySelectorAll('style'); + + expect(styleElements.length).toBe(1); + expect(styleElements[0].textContent).toBe('.test {}'); + expect(spectator.service.inserted.has(1437348290)).toBe(true); + }); + + it('should be able to insert given content', () => { + spectator.service.insertContent(CONTENT_STRATEGY.AppendStyleToHead('.test {}')); + expect(spectator.service.inserted.has(1437348290)).toBe(true); + }); + }); + + describe('#projectContent', () => { + it('should call injectContent of given projectionStrategy and return what it returns', () => { + const strategy = PROJECTION_STRATEGY.AppendComponentToBody(TestComponent); + const componentRef = spectator.service.projectContent(strategy); + const foo = document.querySelector('body > ng-component > div.foo'); + + expect(componentRef).toBeInstanceOf(ComponentRef); + expect(foo.textContent).toBe('bar'); + componentRef.destroy(); + }); }); });