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-security.strategy'; |
||||
export * from './content.strategy'; |
export * from './content.strategy'; |
||||
|
export * from './context.strategy'; |
||||
export * from './cross-origin.strategy'; |
export * from './cross-origin.strategy'; |
||||
export * from './dom.strategy'; |
export * from './dom.strategy'; |
||||
export * from './loading.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