Skip to content

Commit

Permalink
Expose effectMetadata() useful in testing
Browse files Browse the repository at this point in the history
This PR exposes a method to get metadata supplied
through @effect() decorator.

This method is useful for when we want to test
that an effect was properly decorated/registered
in the store.

Related issue: ngrx#491
  • Loading branch information
Denis Loginov committed Oct 17, 2017
1 parent 100a8ef commit 2b9cc50
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
42 changes: 41 additions & 1 deletion docs/effects/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,46 @@ describe('My Effects', () => {
effects.someSource$.subscribe(result => {
expect(result).toEqual(AnotherAction);
});
});
});
});
```

### effectMetadata
Returns decorator configuration for an effect in an instance of effects.
Use this function to ensure that an effect has been properly decorated.

If the decorator was not supplied, the result is `undefined`.

Usage:
```ts
import { TestBed } from '@angular/core/testing';
import { effectMetadata } from '@ngrx/effects';
import { MyEffects } from './my-effects';

describe('My Effects', () => {
let effects: MyEffects;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [
MyEffects,
// other providers
],
});

effects = TestBed.get(MyEffects);
});

it('should register someSource$', () => {
expect(effectMetadata(effects, 'someSource$')).toEqual({
dispatch: true,
});
});

it('should register someOtherSource$', () => {
expect(effectMetadata(effects, 'someOtherSource$')).toEqual({
dispatch: false,
});
});
});
```
29 changes: 29 additions & 0 deletions modules/effects/spec/effects_metadata.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Effect,
effectMetadata,
getSourceMetadata,
getSourceForInstance,
} from '../src/effects_metadata';
Expand Down Expand Up @@ -46,4 +47,32 @@ describe('Effect Metadata', () => {
expect(proto).toBe(Fixture.prototype);
});
});

describe('effectMetadata', () => {
it('should get the effect metadata for a class instance with known effect name', () => {
class Fixture {
@Effect() a$: any;
@Effect({ dispatch: true })
b$: any;
@Effect({ dispatch: false })
c$: any;
}

const mock = new Fixture();

expect(effectMetadata(mock, 'a$')).toEqual({ dispatch: true });
expect(effectMetadata(mock, 'b$')).toEqual({ dispatch: true });
expect(effectMetadata(mock, 'c$')).toEqual({ dispatch: false });
});

it('should return "undefined" if the effect has not been decorated', () => {
class Fixture {
a$: any;
}

const mock = new Fixture();

expect(effectMetadata(mock, 'a$')).toBeUndefined();
});
});
});
13 changes: 13 additions & 0 deletions modules/effects/src/effects_metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,16 @@ export const getSourceMetadata = compose(
getEffectMetadataEntries,
getSourceForInstance
);

export interface PartialEffectMetadata {
dispatch: boolean;
}

export function effectMetadata(
instance: any,
effectName: string
): PartialEffectMetadata {
return getSourceMetadata(instance)
.filter(({ propertyName }) => propertyName === effectName)
.map(({ dispatch }) => ({ dispatch }))[0];
}
2 changes: 1 addition & 1 deletion modules/effects/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { Effect } from './effects_metadata';
export { Effect, effectMetadata } from './effects_metadata';
export { mergeEffects } from './effects_resolver';
export { Actions } from './actions';
export { EffectsModule } from './effects_module';
Expand Down

0 comments on commit 2b9cc50

Please sign in to comment.