Skip to content

Commit

Permalink
fix: fix importMaps to work even when no System.import was called
Browse files Browse the repository at this point in the history
  • Loading branch information
Felipe dos Santos committed Oct 3, 2020
1 parent b90cec3 commit 7f1298a
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';

import { LazyElementDynamicDirective } from './lazy-element-dynamic.directive';

Expand Down Expand Up @@ -36,12 +36,14 @@ describe('LazyElementDirectiveDynamic', () => {
let fixture: ComponentFixture<TestHostComponent>;
let appendChildSpy: jasmine.Spy;

beforeEach(async(() => {
TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [TestHostComponent, LazyElementDynamicDirective],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [TestHostComponent, LazyElementDynamicDirective],
}).compileComponents();
})
);

beforeEach(() => {
fixture = TestBed.createComponent(TestHostComponent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import {
ChangeDetectorRef,
ComponentFactoryResolver,
Directive,
EmbeddedViewRef,
Inject,
Input,
OnInit,
Renderer2,
TemplateRef,
ViewContainerRef,
ComponentFactoryResolver,
ChangeDetectorRef,
Renderer2,
Inject,
EmbeddedViewRef,
} from '@angular/core';
import { DOCUMENT } from '@angular/common';

import {
LazyElementsLoaderService,
ElementConfig,
LazyElementsLoaderService,
} from '../lazy-elements-loader.service';

const LOG_PREFIX = '@angular-extensions/elements';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { Component, CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {
ComponentFixture,
fakeAsync,
flushMicrotasks,
TestBed,
waitForAsync,
} from '@angular/core/testing';

import { LazyElementsModule } from '../lazy-elements.module';

Expand Down Expand Up @@ -86,24 +92,26 @@ describe('LazyElementDirective', () => {
let appendChildSpy: jasmine.Spy;
let whenDefinedSpy: jasmine.Spy;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
TestModule,
LazyElementsModule.forRoot({
elementConfigs: [
{
tag: 'some-configured-element',
url: 'http://elements.com/some-configured-element-module',
loadingComponent: SpinnerTestComponent,
},
],
}),
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [TestHostComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
TestModule,
LazyElementsModule.forRoot({
elementConfigs: [
{
tag: 'some-configured-element',
url: 'http://elements.com/some-configured-element-module',
loadingComponent: SpinnerTestComponent,
},
],
}),
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [TestHostComponent],
}).compileComponents();
})
);

beforeEach(() => {
fixture = TestBed.createComponent(TestHostComponent);
Expand Down Expand Up @@ -224,7 +232,7 @@ describe('LazyElementDirective', () => {
expect(appendChildSpy.calls.argsFor(1)[0].type).toBe('module');
});

it('uses import map when specified', () => {
it('uses import map when specified', fakeAsync(() => {
fixture.detectChanges();

expect(appendChildSpy).toHaveBeenCalledTimes(1);
Expand All @@ -234,16 +242,18 @@ describe('LazyElementDirective', () => {
expect(appendChildSpy.calls.argsFor(0)[0].type).toBe('');

(window as any).System = {
prepareImport: () => null,
resolve: () => `http://elements.com/element-using-import-map`,
};
testHostComponent.useImportMap = true;
fixture.detectChanges();
flushMicrotasks();

expect(appendChildSpy).toHaveBeenCalledTimes(2);
expect(appendChildSpy.calls.argsFor(1)[0].src).toBe(
'http://elements.com/element-using-import-map'
);
});
}));

it('uses elementConfig for the tag', () => {
testHostComponent.useElementConfig = true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import {
ChangeDetectorRef,
ComponentFactoryResolver,
Directive,
EmbeddedViewRef,
Input,
OnInit,
TemplateRef,
ViewContainerRef,
ComponentFactoryResolver,
ChangeDetectorRef,
EmbeddedViewRef,
} from '@angular/core';

import {
LazyElementsLoaderService,
ElementConfig,
LazyElementsLoaderService,
} from '../lazy-elements-loader.service';

const LOG_PREFIX = '@angular-extensions/elements';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { TestBed, waitForAsync } from '@angular/core/testing';

import {
LazyElementsLoaderService,
HooksConfig,
LazyElementsLoaderService,
} from './lazy-elements-loader.service';
import { LazyElementsModule } from './lazy-elements.module';

Expand Down Expand Up @@ -360,15 +360,18 @@ describe('LazyElementsLoaderService preconfigured with LazyElementsModule', () =
})
);

it('should call has and resolve SystemJS methods', (done) => {
it('should call SystemJS prepareImport hook and resolve method', (done) => {
(window as any).System = {
prepareImport: () => null,
resolve: () => `http://elements.com/element-using-import-map`,
};
const System = (window as any).System;
const prepareImportSpy = spyOn(System, 'prepareImport').and.callThrough();
const resolveSpy = spyOn(System, 'resolve').and.callThrough();
service
.loadElement('element', 'element-using-import-map', false, true)
.then(() => {
expect(prepareImportSpy).toHaveBeenCalledTimes(1);
expect(resolveSpy).toHaveBeenCalledTimes(1);
expect(resolveSpy).toHaveBeenCalledWith('element');
done();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable, Type, Optional, Inject } from '@angular/core';
import { Inject, Injectable, Optional, Type } from '@angular/core';

import { LazyElementRootOptions } from './lazy-elements.module';
import {
Expand Down Expand Up @@ -100,20 +100,8 @@ export class LazyElementsLoaderService {
hooksConfig?: HooksConfig
): Promise<void> {
const config = this.getElementConfig(tag);

if (isModule === undefined) {
isModule =
config && config.isModule !== undefined
? config.isModule
: this.options.isModule;
}

if (importMap === undefined) {
importMap =
config && config.importMap !== undefined
? config.importMap
: this.options.importMap;
}
isModule ??= config?.isModule ?? this.options.isModule;
importMap ??= config?.importMap ?? this.options.importMap;

if (!tag) {
throw new Error(
Expand All @@ -122,7 +110,7 @@ export class LazyElementsLoaderService {
}

if (!url) {
if ((!config || !config.url) && !importMap) {
if (!config?.url && !importMap) {
throw new Error(`${LOG_PREFIX} - url for <${tag}> not found`);
} else if (importMap) {
url = tag;
Expand All @@ -144,7 +132,7 @@ export class LazyElementsLoaderService {
this.options?.hooks?.afterLoad;

if (importMap) {
url = this.resolveImportMap(url);
url = await this.resolveImportMap(url);
}

const script = document.createElement('script') as HTMLScriptElement;
Expand Down Expand Up @@ -190,26 +178,18 @@ export class LazyElementsLoaderService {
return url.replace(/https?:\/\//, '');
}

private isPromise<T>(obj: T | Promise<T>): obj is Promise<T> {
return typeof (obj as any)?.then === 'function';
}

private handleHook(hook: Hook, tag: string): Promise<void> {
try {
const result = hook(tag);
if (this.isPromise(result)) {
return result;
} else {
return Promise.resolve();
}
return Promise.resolve(hook(tag));
} catch (err) {
return Promise.reject(err);
}
}

private resolveImportMap(url: string) {
private async resolveImportMap(url: string) {
const System = (window as any).System;
if (System) {
await System.prepareImport();
url = System.resolve(url);
} else {
throw new Error(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Router } from '@angular/router';
import { NgModule } from '@angular/core';
import { RouterTestingModule } from '@angular/router/testing';
import { TestBed, fakeAsync, tick } from '@angular/core/testing';
import { fakeAsync, TestBed, tick } from '@angular/core/testing';

import { LazyElementsModule } from './lazy-elements.module';

Expand Down
10 changes: 5 additions & 5 deletions projects/elements/src/lib/lazy-elements/lazy-elements.module.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import {
NgModule,
Optional,
Inject,
ModuleWithProviders,
Type,
NgModule,
Optional,
SkipSelf,
Type,
} from '@angular/core';
import { CommonModule } from '@angular/common';

import { LazyElementDirective } from './lazy-element/lazy-element.directive';
import { LazyElementDynamicDirective } from './lazy-element-dynamic/lazy-element-dynamic.directive';
import {
ElementConfig,
LazyElementsLoaderService,
HooksConfig,
LazyElementsLoaderService,
} from './lazy-elements-loader.service';
import {
LAZY_ELEMENT_ROOT_OPTIONS,
LAZY_ELEMENT_CONFIGS,
LAZY_ELEMENT_ROOT_GUARD,
LAZY_ELEMENT_ROOT_OPTIONS,
} from './lazy-elements.tokens';

export function createLazyElementRootGuard(
Expand Down

0 comments on commit 7f1298a

Please sign in to comment.