1
|
/**
|
2
|
* @license Angular v4.4.6
|
3
|
* (c) 2010-2017 Google, Inc. https://angular.io/
|
4
|
* License: MIT
|
5
|
*/
|
6
|
import { COMPILER_OPTIONS, Compiler, CompilerFactory, Component, Directive, Injectable, Injector, NgModule, Pipe, SecurityContext, createPlatformFactory, ɵstringify } from '@angular/core';
|
7
|
import { CompileMetadataResolver, CompileReflector, DirectiveResolver, NgModuleResolver, PipeResolver, platformCoreDynamic } from '@angular/compiler';
|
8
|
import { ɵTestingCompilerFactory } from '@angular/core/testing';
|
9
|
|
10
|
/**
|
11
|
* @license
|
12
|
* Copyright Google Inc. All Rights Reserved.
|
13
|
*
|
14
|
* Use of this source code is governed by an MIT-style license that can be
|
15
|
* found in the LICENSE file at https://angular.io/license
|
16
|
*/
|
17
|
class MockSchemaRegistry {
|
18
|
constructor(existingProperties, attrPropMapping, existingElements, invalidProperties, invalidAttributes) {
|
19
|
this.existingProperties = existingProperties;
|
20
|
this.attrPropMapping = attrPropMapping;
|
21
|
this.existingElements = existingElements;
|
22
|
this.invalidProperties = invalidProperties;
|
23
|
this.invalidAttributes = invalidAttributes;
|
24
|
}
|
25
|
hasProperty(tagName, property, schemas) {
|
26
|
const value = this.existingProperties[property];
|
27
|
return value === void 0 ? true : value;
|
28
|
}
|
29
|
hasElement(tagName, schemaMetas) {
|
30
|
const value = this.existingElements[tagName.toLowerCase()];
|
31
|
return value === void 0 ? true : value;
|
32
|
}
|
33
|
allKnownElementNames() { return Object.keys(this.existingElements); }
|
34
|
securityContext(selector, property, isAttribute) {
|
35
|
return SecurityContext.NONE;
|
36
|
}
|
37
|
getMappedPropName(attrName) { return this.attrPropMapping[attrName] || attrName; }
|
38
|
getDefaultComponentElementName() { return 'ng-component'; }
|
39
|
validateProperty(name) {
|
40
|
if (this.invalidProperties.indexOf(name) > -1) {
|
41
|
return { error: true, msg: `Binding to property '${name}' is disallowed for security reasons` };
|
42
|
}
|
43
|
else {
|
44
|
return { error: false };
|
45
|
}
|
46
|
}
|
47
|
validateAttribute(name) {
|
48
|
if (this.invalidAttributes.indexOf(name) > -1) {
|
49
|
return {
|
50
|
error: true,
|
51
|
msg: `Binding to attribute '${name}' is disallowed for security reasons`
|
52
|
};
|
53
|
}
|
54
|
else {
|
55
|
return { error: false };
|
56
|
}
|
57
|
}
|
58
|
normalizeAnimationStyleProperty(propName) { return propName; }
|
59
|
normalizeAnimationStyleValue(camelCaseProp, userProvidedProp, val) {
|
60
|
return { error: null, value: val.toString() };
|
61
|
}
|
62
|
}
|
63
|
|
64
|
/**
|
65
|
* @license
|
66
|
* Copyright Google Inc. All Rights Reserved.
|
67
|
*
|
68
|
* Use of this source code is governed by an MIT-style license that can be
|
69
|
* found in the LICENSE file at https://angular.io/license
|
70
|
*/
|
71
|
/**
|
72
|
* An implementation of {@link DirectiveResolver} that allows overriding
|
73
|
* various properties of directives.
|
74
|
*/
|
75
|
class MockDirectiveResolver extends DirectiveResolver {
|
76
|
constructor(_injector, reflector) {
|
77
|
super(reflector);
|
78
|
this._injector = _injector;
|
79
|
this._directives = new Map();
|
80
|
this._providerOverrides = new Map();
|
81
|
this._viewProviderOverrides = new Map();
|
82
|
this._views = new Map();
|
83
|
this._inlineTemplates = new Map();
|
84
|
}
|
85
|
get _compiler() { return this._injector.get(Compiler); }
|
86
|
_clearCacheFor(component) { this._compiler.clearCacheFor(component); }
|
87
|
resolve(type, throwIfNotFound = true) {
|
88
|
let metadata = this._directives.get(type) || null;
|
89
|
if (!metadata) {
|
90
|
metadata = super.resolve(type, throwIfNotFound);
|
91
|
}
|
92
|
if (!metadata) {
|
93
|
return null;
|
94
|
}
|
95
|
const providerOverrides = this._providerOverrides.get(type);
|
96
|
const viewProviderOverrides = this._viewProviderOverrides.get(type);
|
97
|
let providers = metadata.providers;
|
98
|
if (providerOverrides != null) {
|
99
|
const originalViewProviders = metadata.providers || [];
|
100
|
providers = originalViewProviders.concat(providerOverrides);
|
101
|
}
|
102
|
if (metadata instanceof Component) {
|
103
|
let viewProviders = metadata.viewProviders;
|
104
|
if (viewProviderOverrides != null) {
|
105
|
const originalViewProviders = metadata.viewProviders || [];
|
106
|
viewProviders = originalViewProviders.concat(viewProviderOverrides);
|
107
|
}
|
108
|
let view = this._views.get(type) || metadata;
|
109
|
let animations = view.animations;
|
110
|
let templateUrl = view.templateUrl;
|
111
|
let inlineTemplate = this._inlineTemplates.get(type);
|
112
|
if (inlineTemplate) {
|
113
|
templateUrl = undefined;
|
114
|
}
|
115
|
else {
|
116
|
inlineTemplate = view.template;
|
117
|
}
|
118
|
return new Component({
|
119
|
selector: metadata.selector,
|
120
|
inputs: metadata.inputs,
|
121
|
outputs: metadata.outputs,
|
122
|
host: metadata.host,
|
123
|
exportAs: metadata.exportAs,
|
124
|
moduleId: metadata.moduleId,
|
125
|
queries: metadata.queries,
|
126
|
changeDetection: metadata.changeDetection,
|
127
|
providers: providers,
|
128
|
viewProviders: viewProviders,
|
129
|
entryComponents: metadata.entryComponents,
|
130
|
template: inlineTemplate,
|
131
|
templateUrl: templateUrl,
|
132
|
animations: animations,
|
133
|
styles: view.styles,
|
134
|
styleUrls: view.styleUrls,
|
135
|
encapsulation: view.encapsulation,
|
136
|
interpolation: view.interpolation,
|
137
|
preserveWhitespaces: view.preserveWhitespaces,
|
138
|
});
|
139
|
}
|
140
|
return new Directive({
|
141
|
selector: metadata.selector,
|
142
|
inputs: metadata.inputs,
|
143
|
outputs: metadata.outputs,
|
144
|
host: metadata.host,
|
145
|
providers: providers,
|
146
|
exportAs: metadata.exportAs,
|
147
|
queries: metadata.queries
|
148
|
});
|
149
|
}
|
150
|
/**
|
151
|
* Overrides the {@link Directive} for a directive.
|
152
|
*/
|
153
|
setDirective(type, metadata) {
|
154
|
this._directives.set(type, metadata);
|
155
|
this._clearCacheFor(type);
|
156
|
}
|
157
|
setProvidersOverride(type, providers) {
|
158
|
this._providerOverrides.set(type, providers);
|
159
|
this._clearCacheFor(type);
|
160
|
}
|
161
|
setViewProvidersOverride(type, viewProviders) {
|
162
|
this._viewProviderOverrides.set(type, viewProviders);
|
163
|
this._clearCacheFor(type);
|
164
|
}
|
165
|
/**
|
166
|
* Overrides the {@link ViewMetadata} for a component.
|
167
|
*/
|
168
|
setView(component, view) {
|
169
|
this._views.set(component, view);
|
170
|
this._clearCacheFor(component);
|
171
|
}
|
172
|
/**
|
173
|
* Overrides the inline template for a component - other configuration remains unchanged.
|
174
|
*/
|
175
|
setInlineTemplate(component, template) {
|
176
|
this._inlineTemplates.set(component, template);
|
177
|
this._clearCacheFor(component);
|
178
|
}
|
179
|
}
|
180
|
MockDirectiveResolver.decorators = [
|
181
|
{ type: Injectable },
|
182
|
];
|
183
|
/** @nocollapse */
|
184
|
MockDirectiveResolver.ctorParameters = () => [
|
185
|
{ type: Injector, },
|
186
|
{ type: CompileReflector, },
|
187
|
];
|
188
|
|
189
|
/**
|
190
|
* @license
|
191
|
* Copyright Google Inc. All Rights Reserved.
|
192
|
*
|
193
|
* Use of this source code is governed by an MIT-style license that can be
|
194
|
* found in the LICENSE file at https://angular.io/license
|
195
|
*/
|
196
|
class MockNgModuleResolver extends NgModuleResolver {
|
197
|
constructor(_injector, reflector) {
|
198
|
super(reflector);
|
199
|
this._injector = _injector;
|
200
|
this._ngModules = new Map();
|
201
|
}
|
202
|
/**
|
203
|
* Overrides the {@link NgModule} for a module.
|
204
|
*/
|
205
|
setNgModule(type, metadata) {
|
206
|
this._ngModules.set(type, metadata);
|
207
|
this._clearCacheFor(type);
|
208
|
}
|
209
|
/**
|
210
|
* Returns the {@link NgModule} for a module:
|
211
|
* - Set the {@link NgModule} to the overridden view when it exists or fallback to the
|
212
|
* default
|
213
|
* `NgModuleResolver`, see `setNgModule`.
|
214
|
*/
|
215
|
resolve(type, throwIfNotFound = true) {
|
216
|
return this._ngModules.get(type) || super.resolve(type, throwIfNotFound);
|
217
|
}
|
218
|
get _compiler() { return this._injector.get(Compiler); }
|
219
|
_clearCacheFor(component) { this._compiler.clearCacheFor(component); }
|
220
|
}
|
221
|
MockNgModuleResolver.decorators = [
|
222
|
{ type: Injectable },
|
223
|
];
|
224
|
/** @nocollapse */
|
225
|
MockNgModuleResolver.ctorParameters = () => [
|
226
|
{ type: Injector, },
|
227
|
{ type: CompileReflector, },
|
228
|
];
|
229
|
|
230
|
/**
|
231
|
* @license
|
232
|
* Copyright Google Inc. All Rights Reserved.
|
233
|
*
|
234
|
* Use of this source code is governed by an MIT-style license that can be
|
235
|
* found in the LICENSE file at https://angular.io/license
|
236
|
*/
|
237
|
class MockPipeResolver extends PipeResolver {
|
238
|
constructor(_injector, refector) {
|
239
|
super(refector);
|
240
|
this._injector = _injector;
|
241
|
this._pipes = new Map();
|
242
|
}
|
243
|
get _compiler() { return this._injector.get(Compiler); }
|
244
|
_clearCacheFor(pipe) { this._compiler.clearCacheFor(pipe); }
|
245
|
/**
|
246
|
* Overrides the {@link Pipe} for a pipe.
|
247
|
*/
|
248
|
setPipe(type, metadata) {
|
249
|
this._pipes.set(type, metadata);
|
250
|
this._clearCacheFor(type);
|
251
|
}
|
252
|
/**
|
253
|
* Returns the {@link Pipe} for a pipe:
|
254
|
* - Set the {@link Pipe} to the overridden view when it exists or fallback to the
|
255
|
* default
|
256
|
* `PipeResolver`, see `setPipe`.
|
257
|
*/
|
258
|
resolve(type, throwIfNotFound = true) {
|
259
|
let metadata = this._pipes.get(type);
|
260
|
if (!metadata) {
|
261
|
metadata = super.resolve(type, throwIfNotFound);
|
262
|
}
|
263
|
return metadata;
|
264
|
}
|
265
|
}
|
266
|
MockPipeResolver.decorators = [
|
267
|
{ type: Injectable },
|
268
|
];
|
269
|
/** @nocollapse */
|
270
|
MockPipeResolver.ctorParameters = () => [
|
271
|
{ type: Injector, },
|
272
|
{ type: CompileReflector, },
|
273
|
];
|
274
|
|
275
|
/**
|
276
|
* @license
|
277
|
* Copyright Google Inc. All Rights Reserved.
|
278
|
*
|
279
|
* Use of this source code is governed by an MIT-style license that can be
|
280
|
* found in the LICENSE file at https://angular.io/license
|
281
|
*/
|
282
|
let _nextReferenceId = 0;
|
283
|
class MetadataOverrider {
|
284
|
constructor() {
|
285
|
this._references = new Map();
|
286
|
}
|
287
|
/**
|
288
|
* Creates a new instance for the given metadata class
|
289
|
* based on an old instance and overrides.
|
290
|
*/
|
291
|
overrideMetadata(metadataClass, oldMetadata, override) {
|
292
|
const props = {};
|
293
|
if (oldMetadata) {
|
294
|
_valueProps(oldMetadata).forEach((prop) => props[prop] = oldMetadata[prop]);
|
295
|
}
|
296
|
if (override.set) {
|
297
|
if (override.remove || override.add) {
|
298
|
throw new Error(`Cannot set and add/remove ${ɵstringify(metadataClass)} at the same time!`);
|
299
|
}
|
300
|
setMetadata(props, override.set);
|
301
|
}
|
302
|
if (override.remove) {
|
303
|
removeMetadata(props, override.remove, this._references);
|
304
|
}
|
305
|
if (override.add) {
|
306
|
addMetadata(props, override.add);
|
307
|
}
|
308
|
return new metadataClass(props);
|
309
|
}
|
310
|
}
|
311
|
function removeMetadata(metadata, remove, references) {
|
312
|
const removeObjects = new Set();
|
313
|
for (const prop in remove) {
|
314
|
const removeValue = remove[prop];
|
315
|
if (removeValue instanceof Array) {
|
316
|
removeValue.forEach((value) => { removeObjects.add(_propHashKey(prop, value, references)); });
|
317
|
}
|
318
|
else {
|
319
|
removeObjects.add(_propHashKey(prop, removeValue, references));
|
320
|
}
|
321
|
}
|
322
|
for (const prop in metadata) {
|
323
|
const propValue = metadata[prop];
|
324
|
if (propValue instanceof Array) {
|
325
|
metadata[prop] = propValue.filter((value) => !removeObjects.has(_propHashKey(prop, value, references)));
|
326
|
}
|
327
|
else {
|
328
|
if (removeObjects.has(_propHashKey(prop, propValue, references))) {
|
329
|
metadata[prop] = undefined;
|
330
|
}
|
331
|
}
|
332
|
}
|
333
|
}
|
334
|
function addMetadata(metadata, add) {
|
335
|
for (const prop in add) {
|
336
|
const addValue = add[prop];
|
337
|
const propValue = metadata[prop];
|
338
|
if (propValue != null && propValue instanceof Array) {
|
339
|
metadata[prop] = propValue.concat(addValue);
|
340
|
}
|
341
|
else {
|
342
|
metadata[prop] = addValue;
|
343
|
}
|
344
|
}
|
345
|
}
|
346
|
function setMetadata(metadata, set) {
|
347
|
for (const prop in set) {
|
348
|
metadata[prop] = set[prop];
|
349
|
}
|
350
|
}
|
351
|
function _propHashKey(propName, propValue, references) {
|
352
|
const replacer = (key, value) => {
|
353
|
if (typeof value === 'function') {
|
354
|
value = _serializeReference(value, references);
|
355
|
}
|
356
|
return value;
|
357
|
};
|
358
|
return `${propName}:${JSON.stringify(propValue, replacer)}`;
|
359
|
}
|
360
|
function _serializeReference(ref, references) {
|
361
|
let id = references.get(ref);
|
362
|
if (!id) {
|
363
|
id = `${ɵstringify(ref)}${_nextReferenceId++}`;
|
364
|
references.set(ref, id);
|
365
|
}
|
366
|
return id;
|
367
|
}
|
368
|
function _valueProps(obj) {
|
369
|
const props = [];
|
370
|
// regular public props
|
371
|
Object.keys(obj).forEach((prop) => {
|
372
|
if (!prop.startsWith('_')) {
|
373
|
props.push(prop);
|
374
|
}
|
375
|
});
|
376
|
// getters
|
377
|
let proto = obj;
|
378
|
while (proto = Object.getPrototypeOf(proto)) {
|
379
|
Object.keys(proto).forEach((protoProp) => {
|
380
|
const desc = Object.getOwnPropertyDescriptor(proto, protoProp);
|
381
|
if (!protoProp.startsWith('_') && desc && 'get' in desc) {
|
382
|
props.push(protoProp);
|
383
|
}
|
384
|
});
|
385
|
}
|
386
|
return props;
|
387
|
}
|
388
|
|
389
|
/**
|
390
|
* @license
|
391
|
* Copyright Google Inc. All Rights Reserved.
|
392
|
*
|
393
|
* Use of this source code is governed by an MIT-style license that can be
|
394
|
* found in the LICENSE file at https://angular.io/license
|
395
|
*/
|
396
|
/**
|
397
|
* @module
|
398
|
* @description
|
399
|
* Entry point for all APIs of the compiler package.
|
400
|
*
|
401
|
* <div class="callout is-critical">
|
402
|
* <header>Unstable APIs</header>
|
403
|
* <p>
|
404
|
* All compiler apis are currently considered experimental and private!
|
405
|
* </p>
|
406
|
* <p>
|
407
|
* We expect the APIs in this package to keep on changing. Do not rely on them.
|
408
|
* </p>
|
409
|
* </div>
|
410
|
*/
|
411
|
class TestingCompilerFactoryImpl {
|
412
|
constructor(_compilerFactory) {
|
413
|
this._compilerFactory = _compilerFactory;
|
414
|
}
|
415
|
createTestingCompiler(options) {
|
416
|
const compiler = this._compilerFactory.createCompiler(options);
|
417
|
return new TestingCompilerImpl(compiler, compiler.injector.get(MockDirectiveResolver), compiler.injector.get(MockPipeResolver), compiler.injector.get(MockNgModuleResolver), compiler.injector.get(CompileMetadataResolver));
|
418
|
}
|
419
|
}
|
420
|
TestingCompilerFactoryImpl.decorators = [
|
421
|
{ type: Injectable },
|
422
|
];
|
423
|
/** @nocollapse */
|
424
|
TestingCompilerFactoryImpl.ctorParameters = () => [
|
425
|
{ type: CompilerFactory, },
|
426
|
];
|
427
|
class TestingCompilerImpl {
|
428
|
constructor(_compiler, _directiveResolver, _pipeResolver, _moduleResolver, _metadataResolver) {
|
429
|
this._compiler = _compiler;
|
430
|
this._directiveResolver = _directiveResolver;
|
431
|
this._pipeResolver = _pipeResolver;
|
432
|
this._moduleResolver = _moduleResolver;
|
433
|
this._metadataResolver = _metadataResolver;
|
434
|
this._overrider = new MetadataOverrider();
|
435
|
}
|
436
|
get injector() { return this._compiler.injector; }
|
437
|
compileModuleSync(moduleType) {
|
438
|
return this._compiler.compileModuleSync(moduleType);
|
439
|
}
|
440
|
compileModuleAsync(moduleType) {
|
441
|
return this._compiler.compileModuleAsync(moduleType);
|
442
|
}
|
443
|
compileModuleAndAllComponentsSync(moduleType) {
|
444
|
return this._compiler.compileModuleAndAllComponentsSync(moduleType);
|
445
|
}
|
446
|
compileModuleAndAllComponentsAsync(moduleType) {
|
447
|
return this._compiler.compileModuleAndAllComponentsAsync(moduleType);
|
448
|
}
|
449
|
getNgContentSelectors(component) {
|
450
|
return this._compiler.getNgContentSelectors(component);
|
451
|
}
|
452
|
getComponentFactory(component) {
|
453
|
return this._compiler.getComponentFactory(component);
|
454
|
}
|
455
|
checkOverrideAllowed(type) {
|
456
|
if (this._compiler.hasAotSummary(type)) {
|
457
|
throw new Error(`${ɵstringify(type)} was AOT compiled, so its metadata cannot be changed.`);
|
458
|
}
|
459
|
}
|
460
|
overrideModule(ngModule, override) {
|
461
|
this.checkOverrideAllowed(ngModule);
|
462
|
const oldMetadata = this._moduleResolver.resolve(ngModule, false);
|
463
|
this._moduleResolver.setNgModule(ngModule, this._overrider.overrideMetadata(NgModule, oldMetadata, override));
|
464
|
}
|
465
|
overrideDirective(directive, override) {
|
466
|
this.checkOverrideAllowed(directive);
|
467
|
const oldMetadata = this._directiveResolver.resolve(directive, false);
|
468
|
this._directiveResolver.setDirective(directive, this._overrider.overrideMetadata(Directive, oldMetadata, override));
|
469
|
}
|
470
|
overrideComponent(component, override) {
|
471
|
this.checkOverrideAllowed(component);
|
472
|
const oldMetadata = this._directiveResolver.resolve(component, false);
|
473
|
this._directiveResolver.setDirective(component, this._overrider.overrideMetadata(Component, oldMetadata, override));
|
474
|
}
|
475
|
overridePipe(pipe, override) {
|
476
|
this.checkOverrideAllowed(pipe);
|
477
|
const oldMetadata = this._pipeResolver.resolve(pipe, false);
|
478
|
this._pipeResolver.setPipe(pipe, this._overrider.overrideMetadata(Pipe, oldMetadata, override));
|
479
|
}
|
480
|
loadAotSummaries(summaries) { this._compiler.loadAotSummaries(summaries); }
|
481
|
clearCache() { this._compiler.clearCache(); }
|
482
|
clearCacheFor(type) { this._compiler.clearCacheFor(type); }
|
483
|
}
|
484
|
/**
|
485
|
* Platform for dynamic tests
|
486
|
*
|
487
|
* @experimental
|
488
|
*/
|
489
|
const platformCoreDynamicTesting = createPlatformFactory(platformCoreDynamic, 'coreDynamicTesting', [
|
490
|
{
|
491
|
provide: COMPILER_OPTIONS,
|
492
|
useValue: {
|
493
|
providers: [
|
494
|
MockPipeResolver,
|
495
|
{ provide: PipeResolver, useExisting: MockPipeResolver },
|
496
|
MockDirectiveResolver,
|
497
|
{ provide: DirectiveResolver, useExisting: MockDirectiveResolver },
|
498
|
MockNgModuleResolver,
|
499
|
{ provide: NgModuleResolver, useExisting: MockNgModuleResolver },
|
500
|
]
|
501
|
},
|
502
|
multi: true
|
503
|
},
|
504
|
{ provide: ɵTestingCompilerFactory, useClass: TestingCompilerFactoryImpl }
|
505
|
]);
|
506
|
|
507
|
/**
|
508
|
* @license
|
509
|
* Copyright Google Inc. All Rights Reserved.
|
510
|
*
|
511
|
* Use of this source code is governed by an MIT-style license that can be
|
512
|
* found in the LICENSE file at https://angular.io/license
|
513
|
*/
|
514
|
/**
|
515
|
* @module
|
516
|
* @description
|
517
|
* Entry point for all public APIs of the compiler/testing package.
|
518
|
*/
|
519
|
|
520
|
export { TestingCompilerFactoryImpl, TestingCompilerImpl, platformCoreDynamicTesting, MockSchemaRegistry, MockDirectiveResolver, MockNgModuleResolver, MockPipeResolver };
|
521
|
//# sourceMappingURL=testing.js.map
|