diff --git a/modules/eslint-plugin/spec/rules/avoid-dispatching-multiple-actions-sequentially.spec.ts b/modules/eslint-plugin/spec/rules/avoid-dispatching-multiple-actions-sequentially.spec.ts index be228407e3..59ea92a24e 100644 --- a/modules/eslint-plugin/spec/rules/avoid-dispatching-multiple-actions-sequentially.spec.ts +++ b/modules/eslint-plugin/spec/rules/avoid-dispatching-multiple-actions-sequentially.spec.ts @@ -13,31 +13,106 @@ type MessageIds = ESLintUtils.InferMessageIdsTypeFromRule; type Options = ESLintUtils.InferOptionsTypeFromRule; type RunTests = TSESLint.RunTests; -const valid: () => RunTests['valid'] = () => [ +const validConstructor: () => RunTests['valid'] = () => [ ` -import { Store } from '@ngrx/store' + import { Store } from '@ngrx/store' + + class Ok { + ngOnInit() { + this.dispatch(UserActions.add()) + } + }`, + ` + import { Store } from '@ngrx/store' + + class Ok1 { + constructor(private store: Store) {} + + ping() { + this.store.dispatch(GameActions.ping()) + } + }`, + // https://github.com/timdeschryver/eslint-plugin-ngrx/issues/47 + ` + import { Store } from '@ngrx/store' + + class Ok2 { + constructor(private store: Store) {} + + pingPong() { + if (condition) { + this.store.dispatch(GameActions.ping()) + } else { + this.store.dispatch(GameActions.pong()) + } + } + }`, + // https://github.com/timdeschryver/eslint-plugin-ngrx/issues/86 + ` + import { Store } from '@ngrx/store' + + class Ok3 { + constructor(private store: Store) {} + + ngOnInit() { + this.store.subscribe(() => { + this.store.dispatch(one()); + }); + this.store.subscribe(() => { + this.store.dispatch(anotherOne()); + }); + } + }`, + // https://github.com/ngrx/platform/issues/3513 + ` + import { Store } from '@ngrx/store' + + class Ok4 { + constructor(private store: Store) {} + + ngOnInit() { + this.store.dispatch(one()); + + this.store.subscribe(() => { + this.store.dispatch(anotherOne()); + }); + } + }`, + // https://github.com/ngrx/platform/issues/3513 + ` + import { Store } from '@ngrx/store' + + class Ok5 { + constructor(private store: Store) {} + + ngOnInit() { + this.store.dispatch(anotherOne()); + + this.store.subscribe(() => { + this.store.dispatch(one()); + }); + } + }`, +]; -class Ok { -ngOnInit() { - this.dispatch(UserActions.add()) -} -}`, +const validInject: () => RunTests['valid'] = () => [ ` import { Store } from '@ngrx/store' +import { inject } from '@angular/core' -class Ok1 { -constructor(private store: Store) {} +class Ok6 { +private readonly store = inject(Store) ping() { this.store.dispatch(GameActions.ping()) } }`, - // https://github.com/timdeschryver/eslint-plugin-ngrx/issues/47 ` import { Store } from '@ngrx/store' +import { inject } from '@angular/core' -class Ok2 { -constructor(private store: Store) {} +class Ok7 { +private readonly store = inject(Store) pingPong() { if (condition) { @@ -47,12 +122,12 @@ pingPong() { } } }`, - // https://github.com/timdeschryver/eslint-plugin-ngrx/issues/86 ` import { Store } from '@ngrx/store' +import { inject } from '@angular/core' -class Ok3 { -constructor(private store: Store) {} +class Ok8 { +private readonly store = inject(Store) ngOnInit() { this.store.subscribe(() => { @@ -63,12 +138,12 @@ ngOnInit() { }); } }`, - // https://github.com/ngrx/platform/issues/3513 ` import { Store } from '@ngrx/store' +import { inject } from '@angular/core' -class Ok { -constructor(private store: Store) {} +class Ok9 { +private readonly store = inject(Store) ngOnInit() { this.store.dispatch(one()); @@ -78,12 +153,12 @@ ngOnInit() { }); } }`, - // https://github.com/ngrx/platform/issues/3513 ` import { Store } from '@ngrx/store' +import { inject } from '@angular/core' -class Ok { -constructor(private store: Store) {} +class Ok10 { +private readonly store = inject(Store) ngOnInit() { this.store.dispatch(anotherOne()); @@ -95,12 +170,75 @@ ngOnInit() { }`, ]; -const invalid: () => RunTests['invalid'] = () => [ +const invalidConstructor: () => RunTests['invalid'] = () => [ + fromFixture(` + import { Store } from '@ngrx/store' + + class NotOk { + constructor(private store: Store) {} + + pingPong() { + this.store.dispatch(GameActions.ping()) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] + this.store.dispatch(GameActions.pong()) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] + } + }`), + fromFixture(` + import { Store } from '@ngrx/store' + + class NotOk1 { + constructor(store: Store, private readonly store$: Store) { + store.dispatch(GameActions.ping()) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] + this.ping(); + this.name = 'Bob' + this.store$.dispatch(GameActions.pong()) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] + } + }`), + fromFixture(` + import { Store } from '@ngrx/store' + + class NotOk2 { + constructor(private store: Store) {} + + pingPongPong() { + this.store.dispatch(GameActions.ping()) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] + this.store.dispatch(GameActions.pong()) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] + this.store.dispatch(GameActions.pong()) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] + } + }`), + // https://github.com/timdeschryver/eslint-plugin-ngrx/issues/44 + fromFixture(` + import { Store } from '@ngrx/store' + + class NotOk3 { + constructor(private customName: Store) {} + + ngOnInit() { + customName.dispatch() + } + + pingPong() { + this.customName.dispatch(GameActions.ping()) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] + this.customName.dispatch(GameActions.pong()) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] + } + }`), +]; + +const invalidInject: () => RunTests['invalid'] = () => [ fromFixture(` import { Store } from '@ngrx/store' +import { inject } from '@angular/core' -class NotOk { -constructor(private store: Store) {} +class NotOk4 { +private readonly store = inject(Store) pingPong() { this.store.dispatch(GameActions.ping()) @@ -111,9 +249,12 @@ pingPong() { }`), fromFixture(` import { Store } from '@ngrx/store' +import { inject } from '@angular/core' -class NotOk1 { -constructor(store: Store, private readonly store$: Store) { +class NotOk5 { +private readonly store = inject(Store) +private readonly store$ = inject(Store) +constructor() { store.dispatch(GameActions.ping()) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] this.ping(); @@ -124,9 +265,10 @@ constructor(store: Store, private readonly store$: Store) { }`), fromFixture(` import { Store } from '@ngrx/store' +import { inject } from '@angular/core' -class NotOk2 { -constructor(private store: Store) {} +class NotOk6 { +private readonly store = inject(Store) pingPongPong() { this.store.dispatch(GameActions.ping()) @@ -137,12 +279,12 @@ pingPongPong() { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [${messageId}] } }`), - // https://github.com/timdeschryver/eslint-plugin-ngrx/issues/44 fromFixture(` import { Store } from '@ngrx/store' +import { inject } from '@angular/core' -class NotOk3 { -constructor(private customName: Store) {} +class NotOk7 { +private readonly customName = inject(Store) ngOnInit() { customName.dispatch() @@ -158,6 +300,6 @@ pingPong() { ]; ruleTester().run(path.parse(__filename).name, rule, { - valid: valid(), - invalid: invalid(), + valid: [...validConstructor(), ...validInject()], + invalid: [...invalidConstructor(), ...invalidInject()], });