Skip to content

Commit

Permalink
feat(Effects): Add getEffectsMetadata() helper for verifying metadata
Browse files Browse the repository at this point in the history
Closes #491
  • Loading branch information
dinvlad authored and MikeRyanDev committed Oct 18, 2017
1 parent aae4064 commit 628b865
Show file tree
Hide file tree
Showing 4 changed files with 97 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);
});
});
});
});
```

### getEffectsMetadata
Returns decorator configuration for all effects in a class instance.
Use this function to ensure that effects have been properly decorated.

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

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

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

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

it('should register someSource$ that dispatches an action', () => {
expect(metadata.someSource$).toEqual({ dispatch: true });
});

it('should register someOtherSource$ that does not dispatch an action', () => {
expect(metadata.someOtherSource$).toEqual({ dispatch: false });
});

it('should not register undecoratedSource$', () => {
expect(metadata.undecoratedSource$).toBeUndefined();
});
});
```
33 changes: 33 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,
getEffectsMetadata,
getSourceMetadata,
getSourceForInstance,
} from '../src/effects_metadata';
Expand Down Expand Up @@ -46,4 +47,36 @@ describe('Effect Metadata', () => {
expect(proto).toBe(Fixture.prototype);
});
});

describe('getEffectsMetadata', () => {
it('should get map of metadata for all decorated effects in a class instance', () => {
class Fixture {
@Effect() a: any;
@Effect({ dispatch: true })
b: any;
@Effect({ dispatch: false })
c: any;
}

const mock = new Fixture();

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

it('should return an empty map if the class has not been decorated', () => {
class Fixture {
a: any;
b: any;
c: any;
}

const mock = new Fixture();

expect(getEffectsMetadata(mock)).toEqual({});
});
});
});
18 changes: 18 additions & 0 deletions modules/effects/src/effects_metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,21 @@ export const getSourceMetadata = compose(
getEffectMetadataEntries,
getSourceForInstance
);

export type EffectsMetadata<T> = {
[key in keyof T]?:
| undefined
| {
dispatch: boolean;
}
};

export function getEffectsMetadata<T>(instance: T): EffectsMetadata<T> {
const metadata: EffectsMetadata<T> = {};

getSourceMetadata(instance).forEach(({ propertyName, dispatch }) => {
metadata[propertyName] = { dispatch };
});

return metadata;
}
6 changes: 5 additions & 1 deletion modules/effects/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export { Effect } from './effects_metadata';
export {
Effect,
EffectsMetadata,
getEffectsMetadata,
} from './effects_metadata';
export { mergeEffects } from './effects_resolver';
export { Actions } from './actions';
export { EffectsModule } from './effects_module';
Expand Down

0 comments on commit 628b865

Please sign in to comment.