Skip to content

Commit

Permalink
[refactored] threshold to use named args
Browse files Browse the repository at this point in the history
Summary: Closes #193

Reviewers: O2 Material Motion, O3 Material JavaScript platform reviewers, #material_motion, vietanh

Reviewed By: #material_motion, vietanh

Tags: #material_motion

Differential Revision: http://codereview.cc/D3419
  • Loading branch information
appsforartists committed Oct 11, 2017
1 parent 25cd2f0 commit a2dea49
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 30 deletions.
6 changes: 4 additions & 2 deletions packages/core/src/interactions/Swipeable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class Swipeable {
})
});

this.direction$ = draggedX$.threshold(0).isAnyOf({ candidates: [ ThresholdRegion.ABOVE ] }).rewrite({
this.direction$ = draggedX$.threshold({ limit$: 0 }).isAnyOf({ candidates: [ ThresholdRegion.ABOVE ] }).rewrite({
mapping: {
true: Direction.RIGHT,
false: Direction.LEFT,
Expand All @@ -176,7 +176,9 @@ export class Swipeable {

this.isThresholdMet$ = draggedX$.distanceFrom({
origin$: 0,
}).threshold(Swipeable.VISUAL_THRESHOLD).isAnyOf({ candidates: [ThresholdRegion.ABOVE, ThresholdRegion.WITHIN] });
}).threshold({ limit$: Swipeable.VISUAL_THRESHOLD }).isAnyOf({
candidates: [ThresholdRegion.ABOVE, ThresholdRegion.WITHIN]
});
this.whenThresholdCrossed$ = when(this.isThresholdMet$.dedupe());
this.whenThresholdFirstCrossed$ = when(tossable.resistanceFactor$.dedupe().isAnyOf({ candidates: [ DISABLED_RESISTANCE_FACTOR ] }));

Expand Down
42 changes: 20 additions & 22 deletions packages/core/src/operators/__tests__/threshold.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,78 +43,76 @@ import {

describe('motionObservable.threshold',
() => {
const limitSubject = new MemorylessMotionSubject();
let stream;
let mockObserver;
const limit$ = new MemorylessMotionSubject();
let subject;
let listener;

beforeEach(
() => {
mockObserver = createMockObserver();
stream = new MotionObservable(mockObserver.connect);
subject = new MemorylessMotionSubject();
listener = stub();
}
);

it('should dispatch BELOW when it receives a value below the limit',
() => {
stream.threshold(7).subscribe(listener);
subject.threshold({ limit$: 7 }).subscribe(listener);

mockObserver.next(3);
subject.next(3);

expect(listener).to.have.been.calledWith(ThresholdRegion.BELOW);
}
);

it('should dispatch WITHIN when it receives a value that matches the limit',
() => {
stream.threshold(7).subscribe(listener);
subject.threshold({ limit$: 7 }).subscribe(listener);

mockObserver.next(7);
subject.next(7);

expect(listener).to.have.been.calledWith(ThresholdRegion.WITHIN);
}
);

it('should dispatch ABOVE when it receives a value above the limit',
() => {
stream.threshold(7).subscribe(listener);
subject.threshold({ limit$: 7 }).subscribe(listener);

mockObserver.next(10);
subject.next(10);

expect(listener).to.have.been.calledWith(ThresholdRegion.ABOVE);
}
);

it('should support reactive limits',
() => {
stream.threshold(limitSubject).subscribe(listener);
subject.threshold({ limit$: limit$ }).subscribe(listener);

mockObserver.next(10);
subject.next(10);

limitSubject.next(5);
limit$.next(5);
expect(listener).to.have.been.calledOnce.and.to.have.been.calledWith(ThresholdRegion.ABOVE);

limitSubject.next(15);
limit$.next(15);
expect(listener).to.have.been.calledTwice.and.to.have.been.calledWith(ThresholdRegion.BELOW);

limitSubject.next(10);
limit$.next(10);
expect(listener).to.have.been.calledThrice.and.to.have.been.calledWith(ThresholdRegion.WITHIN);
}
);

it('should support reactive limits and onlyDispatchWithUpstream',
it('should support reactive limits and onlyDispatchWithUpsubject',
() => {
stream.threshold(limitSubject, { onlyDispatchWithUpstream: true }).subscribe(listener);
subject.threshold({ limit$, onlyDispatchWithUpstream: true }).subscribe(listener);

mockObserver.next(10);
subject.next(10);

limitSubject.next(5);
limitSubject.next(15);
limit$.next(5);
limit$.next(15);

expect(listener).to.have.been.calledOnce.and.to.have.been.calledWith(ThresholdRegion.ABOVE);

mockObserver.next(12);
subject.next(12);

expect(listener).to.have.been.calledTwice.and.to.have.been.calledWith(ThresholdRegion.BELOW);
}
Expand Down
14 changes: 8 additions & 6 deletions packages/core/src/operators/threshold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import {
Constructor,
MaybeReactive,
MotionReactiveMappable,
Observable,
ObservableWithMotionOperators,
Expand All @@ -29,16 +30,17 @@ import {
_ReactiveMapOptions,
} from './foundation/_reactiveMap';

export type ThresholdArgs = _ReactiveMapOptions & MaybeReactive<{
limit$: number,
}>;

export interface MotionThresholdable {
threshold(
limit$: number | Observable<number>,
options?: _ReactiveMapOptions,
): ObservableWithMotionOperators<ThresholdRegion>;
threshold(kwargs: ThresholdArgs): ObservableWithMotionOperators<ThresholdRegion>;
}

export function withThreshold<T, S extends Constructor<MotionReactiveMappable<T>>>(superclass: S): S & Constructor<MotionThresholdable> {
return class extends superclass implements MotionThresholdable {
threshold(limit$: number | Observable<number>, options?: _ReactiveMapOptions): ObservableWithMotionOperators<ThresholdRegion> {
threshold({ limit$, ...reactiveMapOptions }: ThresholdArgs): ObservableWithMotionOperators<ThresholdRegion> {
return (this as any as MotionReactiveMappable<number>)._reactiveMap({
transform: ({ upstream, limit }) => {
if (upstream < limit) {
Expand All @@ -53,7 +55,7 @@ export function withThreshold<T, S extends Constructor<MotionReactiveMappable<T>
inputs: {
limit: limit$,
},
...options,
...reactiveMapOptions,
});
}
};
Expand Down

0 comments on commit a2dea49

Please sign in to comment.