feat(pipes): changed .append to .extend
BREAKING CHANGE: Pipes.append has been renamed into Pipes.extend. Pipes.extend prepends pipe factories instead of appending them.
This commit is contained in:
parent
e94270946a
commit
4c8ea12903
|
@ -40,18 +40,18 @@ export class Pipes {
|
|||
}
|
||||
|
||||
/**
|
||||
* Takes a {@link Pipes} config object and returns a binding used to append the
|
||||
* provided config to an inherited {@link Pipes} instance and return a new
|
||||
* Takes a {@link Pipes} config object and returns a binding used to extend the
|
||||
* inherited {@link Pipes} instance with the provided config and return a new
|
||||
* {@link Pipes} instance.
|
||||
*
|
||||
* If the provided config contains a key that is not yet present in the
|
||||
* inherited {@link Pipes}' config, a new {@link PipeFactory} list will be created
|
||||
* for that key. Otherwise, the provided config will be merged with the inherited
|
||||
* {@link Pipes} instance by appending pipes to their respective keys, without mutating
|
||||
* {@link Pipes} instance by prepending pipes to their respective keys, without mutating
|
||||
* the inherited {@link Pipes}.
|
||||
*
|
||||
* The following example shows how to append a new {@link PipeFactory} to the
|
||||
* existing list of `async` factories, which will only be applied to the injector
|
||||
* The following example shows how to extend an existing list of `async` factories
|
||||
* with a new {@link PipeFactory}, which will only be applied to the injector
|
||||
* for this component and its children. This step is all that's required to make a new
|
||||
* pipe available to this component's template.
|
||||
*
|
||||
|
@ -60,44 +60,42 @@ export class Pipes {
|
|||
* ```
|
||||
* @Component({
|
||||
* viewInjector: [
|
||||
* Pipes.append({
|
||||
* Pipes.extend({
|
||||
* async: [newAsyncPipe]
|
||||
* })
|
||||
* ]
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
static append(config): Binding {
|
||||
static extend(config): Binding {
|
||||
return new Binding(Pipes, {
|
||||
toFactory: (pipes: Pipes) => {
|
||||
if (!isPresent(pipes)) {
|
||||
// Typically would occur when calling Pipe.append inside of dependencies passed to
|
||||
// bootstrap(), which would override default pipes instead of append.
|
||||
throw new BaseException('Cannot append to Pipes without a parent injector');
|
||||
if (isBlank(pipes)) {
|
||||
// Typically would occur when calling Pipe.extend inside of dependencies passed to
|
||||
// bootstrap(), which would override default pipes instead of extending them.
|
||||
throw new BaseException('Cannot extend Pipes without a parent injector');
|
||||
}
|
||||
var mergedConfig: StringMap<string, PipeFactory[]> = <StringMap<string, PipeFactory[]>>{};
|
||||
|
||||
// Manual deep copy of existing Pipes config,
|
||||
// so that lists of PipeFactories don't get mutated.
|
||||
StringMapWrapper.forEach(pipes.config, (v: PipeFactory[], k: string) => {
|
||||
var localPipeList: PipeFactory[] = mergedConfig[k] = [];
|
||||
v.forEach((p: PipeFactory) => { localPipeList.push(p); });
|
||||
});
|
||||
|
||||
StringMapWrapper.forEach(config, (v: PipeFactory[], k: string) => {
|
||||
if (isListLikeIterable(mergedConfig[k])) {
|
||||
mergedConfig[k] = ListWrapper.concat(mergedConfig[k], config[k]);
|
||||
} else {
|
||||
mergedConfig[k] = config[k];
|
||||
}
|
||||
});
|
||||
return new Pipes(mergedConfig);
|
||||
return Pipes.create(config, pipes);
|
||||
},
|
||||
// Dependency technically isn't optional, but we can provide a better error message this way.
|
||||
deps: [[Pipes, new UnboundedMetadata(), new OptionalMetadata()]]
|
||||
});
|
||||
}
|
||||
|
||||
static create(config, pipes: Pipes = null): Pipes {
|
||||
if (isPresent(pipes)) {
|
||||
StringMapWrapper.forEach(pipes.config, (v: PipeFactory[], k: string) => {
|
||||
if (StringMapWrapper.contains(config, k)) {
|
||||
var configFactories: PipeFactory[] = config[k];
|
||||
config[k] = configFactories.concat(v);
|
||||
} else {
|
||||
config[k] = ListWrapper.clone(v);
|
||||
}
|
||||
});
|
||||
}
|
||||
return new Pipes(config);
|
||||
}
|
||||
|
||||
private _getListOfFactories(type: string, obj: any): PipeFactory[] {
|
||||
var listOfFactories = this.config[type];
|
||||
if (isBlank(listOfFactories)) {
|
||||
|
|
|
@ -76,13 +76,47 @@ export function main() {
|
|||
.toThrowError(`Cannot find 'type' pipe supporting object 'some object'`);
|
||||
});
|
||||
|
||||
describe('.append()', () => {
|
||||
it('should create a factory that appends new pipes to old', () => {
|
||||
firstPipeFactory.spy("supports").andReturn(false);
|
||||
describe('.create()', () => {
|
||||
it("should create a new Pipes object", () => {
|
||||
firstPipeFactory.spy("supports").andReturn(true);
|
||||
firstPipeFactory.spy("create").andReturn(firstPipe);
|
||||
|
||||
var pipes = Pipes.create({'async': [firstPipeFactory]});
|
||||
expect(pipes.get("async", "first")).toBe(firstPipe);
|
||||
});
|
||||
|
||||
it("should prepend passed it config in existing registry", () => {
|
||||
firstPipeFactory.spy("supports").andReturn(true);
|
||||
secondPipeFactory.spy("supports").andReturn(true);
|
||||
secondPipeFactory.spy("create").andReturn(secondPipe);
|
||||
|
||||
var pipes1 = Pipes.create({'async': [firstPipeFactory]});
|
||||
var pipes2 = Pipes.create({'async': [secondPipeFactory]}, pipes1);
|
||||
|
||||
expect(pipes2.get("async", "first")).toBe(secondPipe);
|
||||
});
|
||||
|
||||
it("should use inherited pipes when no overrides support the provided object", () => {
|
||||
firstPipeFactory.spy("supports").andReturn(true);
|
||||
firstPipeFactory.spy("create").andReturn(firstPipe);
|
||||
secondPipeFactory.spy("supports").andReturn(false);
|
||||
|
||||
var pipes1 = Pipes.create({'async': [firstPipeFactory], 'date': [firstPipeFactory]});
|
||||
var pipes2 = Pipes.create({'async': [secondPipeFactory]}, pipes1);
|
||||
|
||||
expect(pipes2.get("async", "first")).toBe(firstPipe);
|
||||
expect(pipes2.get("date", "first")).toBe(firstPipe);
|
||||
});
|
||||
});
|
||||
|
||||
describe(".extend()", () => {
|
||||
it('should create a factory that prepend new pipes to old', () => {
|
||||
firstPipeFactory.spy("supports").andReturn(true);
|
||||
secondPipeFactory.spy("supports").andReturn(true);
|
||||
secondPipeFactory.spy("create").andReturn(secondPipe);
|
||||
|
||||
var originalPipes = new Pipes({'async': [firstPipeFactory]});
|
||||
var binding = Pipes.append({'async':<PipeFactory[]>[secondPipeFactory]});
|
||||
var binding = Pipes.extend({'async':<PipeFactory[]>[secondPipeFactory]});
|
||||
var pipes: Pipes = binding.toFactory(originalPipes);
|
||||
|
||||
expect(pipes.config['async'].length).toBe(2);
|
||||
|
@ -90,33 +124,34 @@ export function main() {
|
|||
expect(pipes.get('async', 'second plz')).toBe(secondPipe);
|
||||
});
|
||||
|
||||
|
||||
it('should append to di-inherited pipes', () => {
|
||||
firstPipeFactory.spy("supports").andReturn(false);
|
||||
secondPipeFactory.spy("supports").andReturn(true);
|
||||
secondPipeFactory.spy("create").andReturn(secondPipe);
|
||||
|
||||
var originalPipes: Pipes = new Pipes({'async': [firstPipeFactory]});
|
||||
var injector: Injector = Injector.resolveAndCreate([bind(Pipes).toValue(originalPipes)]);
|
||||
var childInjector: Injector =
|
||||
injector.resolveAndCreateChild([Pipes.append({'async': [secondPipeFactory]})]);
|
||||
var parentPipes: Pipes = injector.get(Pipes);
|
||||
var childPipes: Pipes = childInjector.get(Pipes);
|
||||
expect(childPipes.config['async'].length).toBe(2);
|
||||
expect(parentPipes.config['async'].length).toBe(1);
|
||||
expect(childPipes.get('async', 'second plz')).toBe(secondPipe);
|
||||
});
|
||||
|
||||
|
||||
it('should throw if calling append when creating root injector', () => {
|
||||
it('should throw if calling extend when creating root injector', () => {
|
||||
secondPipeFactory.spy("supports").andReturn(true);
|
||||
secondPipeFactory.spy("create").andReturn(secondPipe);
|
||||
|
||||
var injector: Injector =
|
||||
Injector.resolveAndCreate([Pipes.append({'async': [secondPipeFactory]})]);
|
||||
Injector.resolveAndCreate([Pipes.extend({'async': [secondPipeFactory]})]);
|
||||
|
||||
expect(() => injector.get(Pipes))
|
||||
.toThrowError(/Cannot append to Pipes without a parent injector/g);
|
||||
.toThrowError(/Cannot extend Pipes without a parent injector/g);
|
||||
});
|
||||
|
||||
it('should extend di-inherited pipes', () => {
|
||||
firstPipeFactory.spy("supports").andReturn(true);
|
||||
firstPipeFactory.spy("create").andReturn(firstPipe);
|
||||
|
||||
secondPipeFactory.spy("supports").andReturn(false);
|
||||
|
||||
var originalPipes: Pipes = new Pipes({'async': [firstPipeFactory]});
|
||||
var injector: Injector = Injector.resolveAndCreate([bind(Pipes).toValue(originalPipes)]);
|
||||
var childInjector: Injector =
|
||||
injector.resolveAndCreateChild([Pipes.extend({'async': [secondPipeFactory]})]);
|
||||
|
||||
var parentPipes: Pipes = injector.get(Pipes);
|
||||
var childPipes: Pipes = childInjector.get(Pipes);
|
||||
|
||||
expect(childPipes.config['async'].length).toBe(2);
|
||||
expect(parentPipes.config['async'].length).toBe(1);
|
||||
expect(childPipes.get('async', 'second plz')).toBe(firstPipe);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue