/** Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. */ Rx.TestScheduler = (function (__super__) { inherits(TestScheduler, __super__); function baseComparer(x, y) { return x > y ? 1 : (x < y ? -1 : 0); } function TestScheduler() { __super__.call(this, 0, baseComparer); } /** * Schedules an action to be executed at the specified virtual time. * * @param state State passed to the action to be executed. * @param dueTime Absolute virtual time at which to execute the action. * @param action Action to be executed. * @return Disposable object used to cancel the scheduled action (best effort). */ TestScheduler.prototype.scheduleAbsoluteWithState = function (state, dueTime, action) { dueTime <= this.clock && (dueTime = this.clock + 1); return __super__.prototype.scheduleAbsoluteWithState.call(this, state, dueTime, action); }; /** * Adds a relative virtual time to an absolute virtual time value. * * @param absolute Absolute virtual time value. * @param relative Relative virtual time value to add. * @return Resulting absolute virtual time sum value. */ TestScheduler.prototype.add = function (absolute, relative) { return absolute + relative; }; /** * Converts the absolute virtual time value to a DateTimeOffset value. * * @param absolute Absolute virtual time value to convert. * @return Corresponding DateTimeOffset value. */ TestScheduler.prototype.toDateTimeOffset = function (absolute) { return new Date(absolute).getTime(); }; /** * Converts the TimeSpan value to a relative virtual time value. * * @param timeSpan TimeSpan value to convert. * @return Corresponding relative virtual time value. */ TestScheduler.prototype.toRelative = function (timeSpan) { return timeSpan; }; /** * Starts the test scheduler and uses the specified virtual times to invoke the factory function, subscribe to the resulting sequence, and dispose the subscription. * * @param create Factory method to create an observable sequence. * @param created Virtual time at which to invoke the factory to create an observable sequence. * @param subscribed Virtual time at which to subscribe to the created observable sequence. * @param disposed Virtual time at which to dispose the subscription. * @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active. */ TestScheduler.prototype.startWithTiming = function (create, created, subscribed, disposed) { var observer = this.createObserver(), source, subscription; this.scheduleAbsoluteWithState(null, created, function () { source = create(); return disposableEmpty; }); this.scheduleAbsoluteWithState(null, subscribed, function () { subscription = source.subscribe(observer); return disposableEmpty; }); this.scheduleAbsoluteWithState(null, disposed, function () { subscription.dispose(); return disposableEmpty; }); this.start(); return observer; }; /** * Starts the test scheduler and uses the specified virtual time to dispose the subscription to the sequence obtained through the factory function. * Default virtual times are used for factory invocation and sequence subscription. * * @param create Factory method to create an observable sequence. * @param disposed Virtual time at which to dispose the subscription. * @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active. */ TestScheduler.prototype.startWithDispose = function (create, disposed) { return this.startWithTiming(create, ReactiveTest.created, ReactiveTest.subscribed, disposed); }; /** * Starts the test scheduler and uses default virtual times to invoke the factory function, to subscribe to the resulting sequence, and to dispose the subscription. * * @param create Factory method to create an observable sequence. * @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active. */ TestScheduler.prototype.startWithCreate = function (create) { return this.startWithTiming(create, ReactiveTest.created, ReactiveTest.subscribed, ReactiveTest.disposed); }; /** * Creates a hot observable using the specified timestamped notification messages either as an array or arguments. * @param messages Notifications to surface through the created sequence at their specified absolute virtual times. * @return Hot observable sequence that can be used to assert the timing of subscriptions and notifications. */ TestScheduler.prototype.createHotObservable = function () { var len = arguments.length, args; if (Array.isArray(arguments[0])) { args = arguments[0]; } else { args = new Array(len); for (var i = 0; i < len; i++) { args[i] = arguments[i]; } } return new HotObservable(this, args); }; /** * Creates a cold observable using the specified timestamped notification messages either as an array or arguments. * @param messages Notifications to surface through the created sequence at their specified virtual time offsets from the sequence subscription time. * @return Cold observable sequence that can be used to assert the timing of subscriptions and notifications. */ TestScheduler.prototype.createColdObservable = function () { var len = arguments.length, args; if (Array.isArray(arguments[0])) { args = arguments[0]; } else { args = new Array(len); for (var i = 0; i < len; i++) { args[i] = arguments[i]; } } return new ColdObservable(this, args); }; /** * Creates a resolved promise with the given value and ticks * @param {Number} ticks The absolute time of the resolution. * @param {Any} value The value to yield at the given tick. * @returns {MockPromise} A mock Promise which fulfills with the given value. */ TestScheduler.prototype.createResolvedPromise = function (ticks, value) { return new MockPromise(this, [Rx.ReactiveTest.onNext(ticks, value), Rx.ReactiveTest.onCompleted(ticks)]); }; /** * Creates a rejected promise with the given reason and ticks * @param {Number} ticks The absolute time of the resolution. * @param {Any} reason The reason for rejection to yield at the given tick. * @returns {MockPromise} A mock Promise which rejects with the given reason. */ TestScheduler.prototype.createRejectedPromise = function (ticks, reason) { return new MockPromise(this, [Rx.ReactiveTest.onError(ticks, reason)]); }; /** * Creates an observer that records received notification messages and timestamps those. * @return Observer that can be used to assert the timing of received notifications. */ TestScheduler.prototype.createObserver = function () { return new MockObserver(this); }; return TestScheduler; })(VirtualTimeScheduler);