All files / common/testing/src testing-context.global.ts

94.44% Statements 34/36
75% Branches 3/4
80% Functions 8/10
94.28% Lines 33/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 1029x               9x   9x 9x 9x 9x   9x 9x         9x     9x       108x 108x           128x 119x 4x   4x       128x   128x                                         108x 1x 1x     108x 108x     108x           108x       9x         117x 117x 108x   9x   117x 117x   117x    
import {
  AnnotationContext,
  AnnotationContextRegistry,
  ReflectContext,
  ReflectModuleConfiguration,
  _setReflectContext,
  reflectContext,
} from '@aspectjs/common';
import { ConstructorType, setDebug } from '@aspectjs/common/utils';
 
export class ReflectTestingContext extends ReflectContext {
  private testedModules: Set<ConstructorType> = new Set();
  private permanentAnnotations: AnnotationContext[] = [];
  private isInit = false;
  constructor(c: ReflectContext = new ReflectContext()) {
    super();
    this.permanentAnnotations = c
      .get(AnnotationContextRegistry)
      .select()
      .all()
      .find();
    this.permanentAnnotations.forEach((c) =>
      this.get(AnnotationContextRegistry).register(c),
    );
    this.isInit = true;
  }
 
  public override assign(context: ReflectContext) {
    super.assign(context);
    return this;
  }
 
  public override registerModules(
    ...modules: ConstructorType<unknown>[]
  ): ReflectContext {
    if (this.isInit) {
      modules
        .filter((m) => !this.modules.has(m))
        .forEach((m) => {
          this.testedModules.add(m);
        });
    }
 
    super.registerModules(...modules);
 
    return this;
  }
 
  public reset(): this {
    // remove all providers registered by modules in extraModules
    // [...this.testedModules]
    //   .flatMap((m) => getProviders(m))
    //   .forEach((p) => {
    //     this.addedProviders.delete(p);
 
    //     removeArray(
    //       this.providersRegistry.get(getProviderName(p.provide)) ?? [],
    //       (el) => p == el.provider,
    //     );
    //     removeArray(
    //       this.providersToResolve.get(getProviderName(p.provide)) ?? [],
    //       (el) => p === el,
    //     );
    //   });
 
    // undo side-effects of factories (eg: DecoratorHookRegistry.add())
    this.testedModules.forEach((m) => {
      (m as any)[Symbol.for('@ajs:ttd')]?.();
      this.modules.delete(m);
    });
 
    this.testedModules.clear();
    this.assign(new ReflectContext());
 
    // restore permanent annotations
    this.permanentAnnotations.forEach((c) =>
      this.get(AnnotationContextRegistry).register(c),
    );
 
    // this.registerModules(...this.testedModules)
 
    return this;
  }
}
 
export const configureTesting = <
  T extends ReflectModuleConfiguration = ReflectModuleConfiguration,
>(
  ...modules: ConstructorType<unknown>[]
) => {
  let context = reflectContext();
  if (context instanceof ReflectTestingContext) {
    context.reset();
  } else {
    context = _setReflectContext(new ReflectTestingContext(context));
  }
  context.registerModules(...modules);
  setDebug(true);
 
  return reflectContext() as ReflectTestingContext & T;
};