-
-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(stats): Add basic stats plugin.
- Loading branch information
Showing
7 changed files
with
253 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/** | ||
* @license Copyright © 2017 Nicholas Jamieson. All Rights Reserved. | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://github.com/cartant/rxjs-spy | ||
*/ | ||
/*tslint:disable:no-unused-expression*/ | ||
|
||
import { expect } from "chai"; | ||
import { Observable } from "rxjs/Observable"; | ||
import { Subject } from "rxjs/Subject"; | ||
import { StatsPlugin } from "./stats-plugin"; | ||
import { spy } from "../spy"; | ||
|
||
import "rxjs/add/observable/timer"; | ||
|
||
describe("StatsPlugin", () => { | ||
|
||
let statsPlugin: StatsPlugin; | ||
let teardown: () => void; | ||
|
||
afterEach(() => { | ||
|
||
if (teardown) { | ||
teardown(); | ||
} | ||
}); | ||
|
||
beforeEach(() => { | ||
|
||
statsPlugin = new StatsPlugin(); | ||
teardown = spy({ plugins: [statsPlugin], warning: false }); | ||
}); | ||
|
||
it("should count subscribes/unsubscribes", () => { | ||
|
||
const subject = new Subject<number>(); | ||
|
||
let stats = statsPlugin.stats; | ||
expect(stats.subscribes).to.equal(0); | ||
expect(stats.unsubscribes).to.equal(0); | ||
|
||
const subscription = subject.subscribe(); | ||
|
||
stats = statsPlugin.stats; | ||
expect(stats.subscribes).to.equal(1); | ||
expect(stats.unsubscribes).to.equal(0); | ||
|
||
subscription.unsubscribe(); | ||
|
||
stats = statsPlugin.stats; | ||
expect(stats.subscribes).to.equal(1); | ||
expect(stats.unsubscribes).to.equal(1); | ||
}); | ||
|
||
it("should count completes", () => { | ||
|
||
const subject = new Subject<number>(); | ||
const subscription = subject.subscribe(); | ||
|
||
let stats = statsPlugin.stats; | ||
expect(stats.completes).to.equal(0); | ||
|
||
subject.complete(); | ||
|
||
stats = statsPlugin.stats; | ||
expect(stats.completes).to.equal(1); | ||
}); | ||
|
||
it("should count errors", () => { | ||
|
||
const subject = new Subject<number>(); | ||
const subscription = subject.subscribe(); | ||
|
||
let stats = statsPlugin.stats; | ||
expect(stats.errors).to.equal(0); | ||
|
||
subject.error(new Error("Boom!")); | ||
|
||
stats = statsPlugin.stats; | ||
expect(stats.errors).to.equal(1); | ||
}); | ||
|
||
it("should count nexts", () => { | ||
|
||
const subject = new Subject<number>(); | ||
const subscription = subject.subscribe(); | ||
|
||
let stats = statsPlugin.stats; | ||
expect(stats.nexts).to.equal(0); | ||
|
||
subject.next(1); | ||
|
||
stats = statsPlugin.stats; | ||
expect(stats.nexts).to.equal(1); | ||
}); | ||
|
||
it("should include the tick", () => { | ||
|
||
const subject = new Subject<number>(); | ||
const subscription = subject.subscribe(); | ||
|
||
subject.next(1); | ||
|
||
const stats = statsPlugin.stats; | ||
expect(stats.tick).to.not.equal(0); | ||
}); | ||
|
||
it("should determine the timespan between the first and last notification", (callback: any) => { | ||
|
||
Observable.timer(10).subscribe( | ||
() => { | ||
const stats = statsPlugin.stats; | ||
expect(stats.timespan).to.not.be.below(10); | ||
}, | ||
callback, | ||
callback | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/** | ||
* @license Copyright © 2017 Nicholas Jamieson. All Rights Reserved. | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://github.com/cartant/rxjs-spy | ||
*/ | ||
|
||
import { Observable } from "rxjs/Observable"; | ||
import { Subscriber } from "rxjs/Subscriber"; | ||
import { BasePlugin, Notification, SubscriberRef, SubscriptionRef } from "./plugin"; | ||
import { tick } from "../tick"; | ||
|
||
export interface Stats { | ||
completes: number; | ||
errors: number; | ||
nexts: number; | ||
subscribes: number; | ||
tick: number; | ||
timespan: number; | ||
unsubscribes: number; | ||
} | ||
|
||
export class StatsPlugin extends BasePlugin { | ||
|
||
private stats_: Stats = { | ||
completes: 0, | ||
errors: 0, | ||
nexts: 0, | ||
subscribes: 0, | ||
tick: 0, | ||
timespan: 0, | ||
unsubscribes: 0 | ||
}; | ||
private time_ = 0; | ||
|
||
beforeComplete(ref: SubscriptionRef): void { | ||
const { stats_ } = this; | ||
++stats_.completes; | ||
this.all_(); | ||
} | ||
|
||
beforeError(ref: SubscriptionRef, error: any): void { | ||
const { stats_ } = this; | ||
++stats_.errors; | ||
this.all_(); | ||
} | ||
|
||
beforeNext(ref: SubscriptionRef, value: any): void { | ||
const { stats_ } = this; | ||
++stats_.nexts; | ||
this.all_(); | ||
} | ||
|
||
beforeSubscribe(ref: SubscriberRef): void { | ||
const { stats_ } = this; | ||
++stats_.subscribes; | ||
this.all_(); | ||
} | ||
|
||
beforeUnsubscribe(ref: SubscriptionRef): void { | ||
const { stats_ } = this; | ||
++stats_.unsubscribes; | ||
this.all_(); | ||
} | ||
|
||
public get stats(): Stats { | ||
const { stats_ } = this; | ||
return { ...stats_ }; | ||
} | ||
|
||
private all_(): void { | ||
const { stats_, time_ } = this; | ||
if (time_ === 0) { | ||
this.time_ = Date.now(); | ||
} else { | ||
stats_.timespan = Date.now() - time_; | ||
} | ||
stats_.tick = tick(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters