mirror of https://github.com/abpframework/abp.git
3 changed files with 127 additions and 0 deletions
@ -0,0 +1,47 @@ |
|||
import { ComponentRef, TemplateRef, Type } from '@angular/core'; |
|||
import { InferedContextOf, InferedInstanceOf } from '../models'; |
|||
|
|||
export abstract class ContextStrategy<T = any> { |
|||
constructor(public context: Partial<ContextType<T>>) {} |
|||
|
|||
/* tslint:disable-next-line:no-unused-variable */ |
|||
setContext(componentRef?: ComponentRef<InferedInstanceOf<T>>): Partial<ContextType<T>> { |
|||
return this.context; |
|||
} |
|||
} |
|||
|
|||
export class NoContextStrategy< |
|||
T extends Type<any> | TemplateRef<any> = any |
|||
> extends ContextStrategy<T> { |
|||
constructor() { |
|||
super(undefined); |
|||
} |
|||
} |
|||
|
|||
export class ComponentContextStrategy<T extends Type<any> = any> extends ContextStrategy<T> { |
|||
setContext(componentRef: ComponentRef<InferedInstanceOf<T>>): Partial<InferedInstanceOf<T>> { |
|||
Object.keys(this.context).forEach(key => (componentRef.instance[key] = this.context[key])); |
|||
componentRef.changeDetectorRef.detectChanges(); |
|||
return this.context; |
|||
} |
|||
} |
|||
|
|||
export class TemplateContextStrategy<T extends TemplateRef<any> = any> extends ContextStrategy<T> { |
|||
setContext(): Partial<InferedContextOf<T>> { |
|||
return this.context; |
|||
} |
|||
} |
|||
|
|||
export const CONTEXT_STRATEGY = { |
|||
None<T extends Type<any> | TemplateRef<any> = any>() { |
|||
return new NoContextStrategy<T>(); |
|||
}, |
|||
Component<T extends Type<any> = any>(context: Partial<InferedInstanceOf<T>>) { |
|||
return new ComponentContextStrategy<T>(context); |
|||
}, |
|||
Template<T extends TemplateRef<any> = any>(context: Partial<InferedContextOf<T>>) { |
|||
return new TemplateContextStrategy<T>(context); |
|||
}, |
|||
}; |
|||
|
|||
type ContextType<T> = T extends Type<infer U> | TemplateRef<infer U> ? U : never; |
|||
@ -1,5 +1,6 @@ |
|||
export * from './content-security.strategy'; |
|||
export * from './content.strategy'; |
|||
export * from './context.strategy'; |
|||
export * from './cross-origin.strategy'; |
|||
export * from './dom.strategy'; |
|||
export * from './loading.strategy'; |
|||
|
|||
@ -0,0 +1,79 @@ |
|||
import { ComponentRef } from '@angular/core'; |
|||
import { |
|||
ComponentContextStrategy, |
|||
CONTEXT_STRATEGY, |
|||
NoContextStrategy, |
|||
TemplateContextStrategy, |
|||
} from '../strategies'; |
|||
import { uuid } from '../utils'; |
|||
|
|||
describe('ComponentContextStrategy', () => { |
|||
describe('#setContext', () => { |
|||
let componentRef: ComponentRef<any>; |
|||
|
|||
beforeEach( |
|||
() => |
|||
(componentRef = { |
|||
instance: { |
|||
x: '', |
|||
y: '', |
|||
z: '', |
|||
}, |
|||
changeDetectorRef: { |
|||
detectChanges: jest.fn(), |
|||
}, |
|||
} as any), |
|||
); |
|||
|
|||
test.each` |
|||
props | values |
|||
${['x']} | ${[uuid()]} |
|||
${['x', 'y']} | ${[uuid(), uuid()]} |
|||
${['x', 'y', 'z']} | ${[uuid(), uuid(), uuid()]} |
|||
`(
|
|||
'should set $props as $values and call detectChanges once', |
|||
({ props, values }: { props: string[]; values: string[] }) => { |
|||
const context = {}; |
|||
props.forEach((prop, i) => { |
|||
context[prop] = values[i]; |
|||
}); |
|||
|
|||
const strategy = new ComponentContextStrategy(context); |
|||
strategy.setContext(componentRef); |
|||
|
|||
expect(props.every(prop => componentRef.instance[prop] === context[prop])).toBe(true); |
|||
expect(componentRef.changeDetectorRef.detectChanges).toHaveBeenCalledTimes(1); |
|||
}, |
|||
); |
|||
}); |
|||
}); |
|||
|
|||
describe('NoContextStrategy', () => { |
|||
describe('#setContext', () => { |
|||
it('should return undefined', () => { |
|||
const strategy = new NoContextStrategy(); |
|||
expect(strategy.setContext(null)).toBeUndefined(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
describe('TemplateContextStrategy', () => { |
|||
describe('#setContext', () => { |
|||
it('should return context', () => { |
|||
const context = { x: uuid() }; |
|||
const strategy = new TemplateContextStrategy(context); |
|||
expect(strategy.setContext()).toEqual(context); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
describe('CONTEXT_STRATEGY', () => { |
|||
test.each` |
|||
name | Strategy |
|||
${'Component'} | ${ComponentContextStrategy} |
|||
${'None'} | ${NoContextStrategy} |
|||
${'Template'} | ${TemplateContextStrategy} |
|||
`('should successfully map $name to $Strategy.name', ({ name, Strategy }) => {
|
|||
expect(CONTEXT_STRATEGY[name](undefined)).toEqual(new Strategy(undefined)); |
|||
}); |
|||
}); |
|||
Loading…
Reference in new issue