From 7a566a00f124d931317c53d9563c70969bb7e702 Mon Sep 17 00:00:00 2001 From: Anthony Gubler Date: Mon, 19 Dec 2016 19:15:52 +0000 Subject: [PATCH] Update to shim Observables and remove legacy mixins (#109) --- package.json | 1 - src/bases/createStateful.ts | 52 +-- src/main.ts | 6 +- src/mixins/createDestroyable.ts | 87 ----- src/mixins/createEvented.ts | 187 ----------- src/mixins/createStateful.ts | 254 --------------- src/mixins/interfaces.ts | 57 ---- tests/unit/all.ts | 1 - tests/unit/bases/createStateful.ts | 90 +++--- tests/unit/mixins/all.ts | 3 - tests/unit/mixins/createDestroyable.ts | 68 ---- tests/unit/mixins/createEvented.ts | 221 ------------- tests/unit/mixins/createStateful.ts | 426 ------------------------- tsconfig.json | 8 - typings.json | 2 +- 15 files changed, 59 insertions(+), 1404 deletions(-) delete mode 100644 src/mixins/createDestroyable.ts delete mode 100644 src/mixins/createEvented.ts delete mode 100644 src/mixins/createStateful.ts delete mode 100644 src/mixins/interfaces.ts delete mode 100644 tests/unit/mixins/all.ts delete mode 100644 tests/unit/mixins/createDestroyable.ts delete mode 100644 tests/unit/mixins/createEvented.ts delete mode 100644 tests/unit/mixins/createStateful.ts diff --git a/package.json b/package.json index 9c94f30..fba5fb0 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "dojo-core": ">=2.0.0-alpha.16" }, "devDependencies": { - "@reactivex/rxjs": "5.0.0-beta.6", "@types/chai": "~3.4.0", "@types/glob": "~5.0.0", "@types/grunt": "~0.4.0", diff --git a/src/bases/createStateful.ts b/src/bases/createStateful.ts index 77895c8..989e1b8 100644 --- a/src/bases/createStateful.ts +++ b/src/bases/createStateful.ts @@ -3,35 +3,18 @@ import { Handle } from 'dojo-interfaces/core'; import { Evented, Stateful, - State, StatefulOptions, StatefulMixin } from 'dojo-interfaces/bases'; -import { Observable, Subscription } from 'dojo-interfaces/observables'; -import Promise from 'dojo-shim/Promise'; +import { StoreObservablePatchable } from 'dojo-interfaces/abilities'; +import { Subscription } from 'dojo-shim/Observable'; import WeakMap from 'dojo-shim/WeakMap'; import createEvented from './createEvented'; import { ComposeFactory } from '../compose'; import createCancelableEvent from './createCancelableEvent'; -export interface ObservableState { - /** - * A method that allows the return of an `Observable` interface for a particular `id` - * @param id The ID to observe - */ - observe(id: string): Observable; - - /** - * A method that allows the `Stateful` to provide a change to its state, instead of - * changing its state directly. - * @param partial The partial state to be *patched* - * @param options A map of options, which includes the `id` being observed - */ - patch(partial: any, options?: { id?: string }): Promise; -} - -export interface StatefulFactory extends ComposeFactory, StatefulOptions> { - (options?: StatefulOptions): Stateful; +export interface StatefulFactory extends ComposeFactory, StatefulOptions> { + (options?: StatefulOptions): Stateful; } /** @@ -39,7 +22,7 @@ export interface StatefulFactory extends ComposeFactory, Statefu */ interface ObservedState { id: string; - observable: ObservableState; + observable: StoreObservablePatchable; subscription: Subscription; handle: Handle; } @@ -47,7 +30,7 @@ interface ObservedState { /** * A weak map of stateful instances to their obseved state references */ -const observedStateMap = new WeakMap, ObservedState>(); +const observedStateMap = new WeakMap, ObservedState>(); /** * Internal function to unobserve the state of a `Stateful`. It emits a `statecomplete` event which can be @@ -55,7 +38,7 @@ const observedStateMap = new WeakMap, ObservedState>(); * * @param stateful The `Stateful` object to unobserve */ -function completeStatefulState(stateful: Stateful): void { +function completeStatefulState(stateful: Stateful): void { const observedState = observedStateMap.get(stateful); if (observedState) { observedState.handle.destroy(); @@ -77,7 +60,7 @@ function completeStatefulState(stateful: Stateful): void { * @param stateful The Stateful instance * @param state The State to be set */ -function setStatefulState(target: Stateful, state: State): void { +function setStatefulState(target: Stateful, state: Object): void { const previousState = stateWeakMap.get(target); if (!previousState) { throw new Error('Unable to set destroyed state'); @@ -95,7 +78,7 @@ function setStatefulState(target: Stateful, state: State): void { /** * A weak map that contains the stateful's state */ -const stateWeakMap = new WeakMap, State>(); +const stateWeakMap = new WeakMap, Object>(); /** * Create an instance of a stateful object @@ -104,18 +87,18 @@ const createStateful: StatefulFactory = createEvented .mixin({ className: 'Stateful', mixin: { - get stateFrom(this: Stateful): ObservableState | undefined { + get stateFrom(this: Stateful): StoreObservablePatchable | undefined { const observedState = observedStateMap.get(this); if (observedState) { return observedState.observable; } }, - get state(this: Stateful): State { + get state(this: Stateful): Object { return stateWeakMap.get(this); }, - setState(this: Stateful, value: State): void { + setState(this: Stateful, value: Object) { const observedState = observedStateMap.get(this); if (observedState) { observedState.observable.patch(value, { id: observedState.id }); @@ -125,7 +108,7 @@ const createStateful: StatefulFactory = createEvented } }, - observeState(this: Stateful, id: string, observable: ObservableState): Handle { + observeState(this: Stateful, id: string, observable: StoreObservablePatchable): Handle { let observedState = observedStateMap.get(this); if (observedState) { if (observedState.id === id && observedState.observable === observable) { @@ -157,11 +140,11 @@ const createStateful: StatefulFactory = createEvented } ); - observedStateMap.set(stateful, { id, observable, subscription, handle }); + observedStateMap.set(stateful, { id, observable, subscription: subscription, handle }); return handle; } }, - initialize(instance: StatefulMixin & Evented, options: StatefulOptions) { + initialize(instance: StatefulMixin & Evented, options: StatefulOptions) { stateWeakMap.set(instance, Object.create(null)); instance.own({ destroy() { @@ -169,16 +152,13 @@ const createStateful: StatefulFactory = createEvented } }); if (options) { - const { id, stateFrom, state } = options; + const { id, stateFrom } = options; if (typeof id !== 'undefined' && stateFrom) { instance.own(instance.observeState(id, stateFrom)); } else if (stateFrom) { throw new TypeError('When "stateFrom" option is supplied, factory also requires "id" option.'); } - if (state) { - instance.setState(state); - } } } }); diff --git a/src/main.ts b/src/main.ts index 4962a71..349adb1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,7 @@ import compose, { isComposeFactory } from './compose'; -import createDestroyable from './mixins/createDestroyable'; -import createEvented from './mixins/createEvented'; -import createStateful from './mixins/createStateful'; +import createDestroyable from './bases/createDestroyable'; +import createEvented from './bases/createEvented'; +import createStateful from './bases/createStateful'; export { compose, diff --git a/src/mixins/createDestroyable.ts b/src/mixins/createDestroyable.ts deleted file mode 100644 index 92f6c00..0000000 --- a/src/mixins/createDestroyable.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Handle } from 'dojo-core/interfaces'; -import Promise from 'dojo-shim/Promise'; -import WeakMap from 'dojo-shim/WeakMap'; -import compose, { ComposeFactory } from '../compose'; - -export interface DestroyableOptions { } - -export interface Destroyable { - /** - * Take a handle and *own* it, which ensures that the handle's `destroy()` method is called when the - * *owner* is destroyed. - * - * @param handle The handle to own - * @returns A handle to *unown* the passed handle - */ - own(handle: Handle): Handle; - - /** - * Invoke `destroy()` on any owned handles. - * - * @returns A promise that resolves to `true` if successful, otherwise `false` - */ - destroy(): Promise; -} - -export interface DestroyableFactory extends ComposeFactory { } - -/** - * A reference to a function that always returns a promise which resolves to false - */ -function noop(): Promise { - return Promise.resolve(false); -}; - -/** - * A reference to a function that throws, used to replace the `own()` method after - * destruction - */ -function destroyed(): never { - throw new Error('Call made to destroyed method'); -}; - -/** - * A weak map for *owning* handles on instances - */ -const handlesWeakMap = new WeakMap(); - -/** - * A type guard that determines if the value is a Destroyable - * - * @param value The value to guard for - */ -export function isDestroyable(value: any): value is Destroyable { - return Boolean(value && 'destroy' in value && typeof value.destroy === 'function'); -} - -/** - * A mixin which adds the concepts of being able to *destroy* handles which the instance - * *owns* - */ -const createDestroyable: DestroyableFactory = compose('Destroyable', { - own(this: Destroyable, handle: Handle): Handle { - const handles = handlesWeakMap.get(this); - handles.push(handle); - return { - destroy() { - handles.splice(handles.indexOf(handle)); - handle.destroy(); - } - }; - }, - - destroy(this: Destroyable) { - return new Promise((resolve) => { - handlesWeakMap.get(this).forEach((handle) => { - handle && handle.destroy && handle.destroy(); - }); - this.destroy = noop; - this.own = destroyed; - resolve(true); - }); - } -}, (instance) => { - handlesWeakMap.set(instance, []); -}); - -export default createDestroyable; diff --git a/src/mixins/createEvented.ts b/src/mixins/createEvented.ts deleted file mode 100644 index f5cd798..0000000 --- a/src/mixins/createEvented.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { on } from 'dojo-core/aspect'; -import { EventObject, Handle } from 'dojo-core/interfaces'; -import Map from 'dojo-shim/Map'; -import WeakMap from 'dojo-shim/WeakMap'; -import compose, { ComposeFactory } from '../compose'; -import createDestroyable, { Destroyable } from './createDestroyable'; - -export interface TargettedEventObject extends EventObject { - /** - * The target of the event - */ - target: any; -} - -export interface ActionableOptions { - [ option: string ]: any; - /** - * An event object - */ - event?: E; -} - -export interface Actionable { - /** - * The *do* method of an Action, which can take a `options` property of an `event` - * - * @param options Options passed which includes an `event` object - */ - do(options?: ActionableOptions): any; -} - -export interface EventedCallback { - /** - * A callback that takes an `event` argument - * - * @param event The event object - */ - (event: E): boolean | void; -} - -/** - * Either an `EventedCallback` or something that is `Actionable` - */ -export type EventedListener = EventedCallback | Actionable; - -/** - * Either a single `EventedListener` or an array - */ -export type EventedListenerOrArray = EventedListener | EventedListener[]; - -/** - * A map of listeners where the key is the event `type` - */ -export interface EventedListenersMap { - [type: string]: EventedListenerOrArray; -} - -/** - * A map of callbacks where the key is the event `type` - */ -type EventedCallbackMap = Map>; - -export interface EventedOptions { - /** - * Any listeners that should be attached during construction - */ - listeners?: EventedListenersMap; -} - -export interface EventedMixin { - /** - * Emit an event. - * - * The event is determined by the `event.type`, if there are no listeners for an event type, - * `emit` is essentially a noop. - * - * @param event The `EventObject` to be delivered to listeners based on `event.type` - */ - emit(event: E): void; - - /** - * Attach a `listener` to a particular event `type`. - * - * @param type The event to attach the listener to - * @param listener Either a function which takes an emitted `event` object, something that is `Actionable`, - * or an array of of such listeners. - * @returns A handle which can be used to remove the listener - */ - on(type: string, listener: EventedListenerOrArray): Handle; - - /** - * Attach a `listener` to a particular event `type`. - * - * @param type The event to attach the listener to - * @param listeners An object which contains key value pairs of event types and listeners. - */ - on(listeners: EventedListenersMap): Handle; -} - -export type Evented = EventedMixin & Destroyable; - -export interface EventedFactory extends ComposeFactory { } - -/** - * A weak map that contains a map of the listeners for an `Evented` - */ -const listenersMap = new WeakMap(); - -/** - * A guard which determines if the value is `Actionable` - * - * @param value The value to guard against - */ -function isActionable(value: any): value is Actionable { - return Boolean(value && typeof value.do === 'function'); -} - -/** - * An internal function that always returns an EventedCallback - * - * @param listener Either a `EventedCallback` or an `Actionable` - */ -export function resolveListener(listener: EventedListener): EventedCallback { - return isActionable(listener) ? (event: E) => listener.do({ event }) : listener; -} - -/** - * Internal function to convert an array of handles to a single handle - * - * @param handles The array of handles to convert into a signle handle - * @return The single handle - */ -function handlesArraytoHandle(handles: Handle[]): Handle { - return { - destroy() { - handles.forEach((handle) => handle.destroy()); - } - }; -} - -/** - * Creates a new instance of an `Evented` - */ -const createEvented: EventedFactory = compose({ - emit(this: Evented, event: E): void { - const method = listenersMap.get(this).get(event.type); - if (method) { - method.call(this, event); - } - }, - - on(this: Evented, ...args: any[]): Handle { - const listenerMap = listenersMap.get(this); - if (args.length === 2) { /* overload: on(type, listener) */ - const [ type, listeners ] = <[ string, EventedListenerOrArray]> args; - if (Array.isArray(listeners)) { - const handles = listeners.map((listener) => on(listenerMap, type, resolveListener(listener))); - return handlesArraytoHandle(handles); - } - else { - return on(listenerMap, type, resolveListener(listeners)); - } - } - else if (args.length === 1) { /* overload: on(listeners) */ - const [ listenerMapArg ] = <[EventedListenersMap]> args; - const handles = Object.keys(listenerMapArg).map((type) => this.on(type, listenerMapArg[type])); - return handlesArraytoHandle(handles); - } - else { /* unexpected signature */ - throw new TypeError('Invalid arguments'); - } - } - }) - .mixin({ - className: 'Evented', - mixin: createDestroyable, - initialize(instance, options) { - /* Initialise listener map */ - listenersMap.set(instance, new Map>()); - - if (options && options.listeners) { - instance.own(instance.on(options.listeners)); - } - } - }); - -export default createEvented; diff --git a/src/mixins/createStateful.ts b/src/mixins/createStateful.ts deleted file mode 100644 index 66fa084..0000000 --- a/src/mixins/createStateful.ts +++ /dev/null @@ -1,254 +0,0 @@ -import { Handle } from 'dojo-core/interfaces'; -import { deepAssign } from 'dojo-core/lang'; -import Promise from 'dojo-shim/Promise'; -import WeakMap from 'dojo-shim/WeakMap'; -import { Observable, Subscription } from './interfaces'; -import createEvented, { Evented, EventedOptions, EventedListener, TargettedEventObject } from './createEvented'; -import { ComposeFactory } from '../compose'; -import createCancelableEvent, { CancelableEvent } from './../util/createCancelableEvent'; - -/** - * Base State interface - */ -export interface State { - [prop: string]: any; -} - -export interface ObservableState { - /** - * A method that allows the return of an `Observable` interface for a particular `id` - * @param id The ID to observe - */ - observe(id: string): Observable; - - /** - * A method that allows the `Stateful` to provide a change to its state, instead of - * changing its state directly. - * @param partial The partial state to be *patched* - * @param options A map of options, which includes the `id` being observed - */ - patch(partial: any, options?: { id?: string }): Promise; -} - -export interface StatefulOptions extends EventedOptions { - /** - * State that should be set during creation - */ - state?: S; - - /** - * An ID to be used in conjunction with the `stateFrom` option to observe the state - */ - id?: string; - - /** - * An object that the Stateful should observe its state from, which supplies an `observe` and - * `patch` methods to be able to manage its state - */ - stateFrom?: ObservableState; -} - -export interface StateChangeEvent extends TargettedEventObject { - /** - * The event type - */ - type: string; - - /** - * The state of the target - */ - state: S; - - /** - * A Stateful instance - */ - target: Stateful; -} - -export interface StatefulMixin{ - /** - * A read only view of the state - */ - readonly state: S; - - /** - * Set the state on the instance. - * - * Set state can take a partial value, therefore if a key is ommitted from the value, it will not be changed. - * To *clear* a value, set a key to `undefined` - * - * @param value The state (potentially partial) to be set - */ - setState(value: S): void; - - /** - * Observe (and update) the state from an Observable - * @param id The ID to be observed on the Observable - * @param observable An object which provides a `observe` and `patch` methods which allow `Stateful` to be able to - * manage its state. - */ - observeState(id: string, observable: ObservableState): Handle; -} - -export type Stateful = StatefulMixin & Evented & { - /** - * Add a listener for a `statecomplete` event, which occures when state is observed - * and is completed. If the event is not cancelled, the instance will continue and - * call `target.destroy()`. - * - * @param type The event type to listen for - * @param listener The listener that will be called when the event occurs - */ - on(type: 'statecomplete', listener: EventedListener>>): Handle; - - /** - * Add a listener for a `statechange` event, which occures whenever the state changes on the instance. - * - * @param type The event type to listen for - * @param listener The listener that will be called when the event occurs - */ - on(type: 'statechange', listener: EventedListener>): Handle; - on(type: string, listener: EventedListener): Handle; -} - -export interface StatefulFactory extends ComposeFactory, StatefulOptions> { - (options?: StatefulOptions): Stateful; -} - -/** - * Internal interface which contains references to an observed state - */ -interface ObservedState { - id: string; - observable: ObservableState; - subscription: Subscription; - handle: Handle; -} - -/** - * A weak map of stateful instances to their obseved state references - */ -const observedStateMap = new WeakMap, ObservedState>(); - -/** - * Internal function to unobserve the state of a `Stateful`. It emits a `statecomplete` event which can be - * cancelled. - * - * @param stateful The `Stateful` object to unobserve - */ -function unobserve(stateful: Stateful): void { - const observedState = observedStateMap.get(stateful); - if (observedState) { - observedState.handle.destroy(); - const statecomplete = createCancelableEvent({ - type: 'statecomplete', - target: stateful - }); - stateful.emit(statecomplete); - if (!statecomplete.defaultPrevented) { - stateful.destroy(); - } - } -} - -/** - * Internal function that actually applies the state to the Stateful's state and - * emits the `statechange` event. - * - * @param stateful The Stateful instance - * @param state The State to be set - */ -function setStatefulState(stateful: Stateful, state: State): void { - state = deepAssign(stateWeakMap.get(stateful), state); - stateful.emit({ - type: 'statechange', - state, - target: stateful - }); -} - -/** - * A weak map that contains the stateful's state - */ -const stateWeakMap = new WeakMap, State>(); - -/** - * Create an instance of a stateful object - */ -const createStateful: StatefulFactory = createEvented - .mixin({ - className: 'Stateful', - mixin: { - get state(this: Stateful): State { - return stateWeakMap.get(this); - }, - - setState(this: Stateful, value: State): void { - const observedState = observedStateMap.get(this); - if (observedState) { - observedState.observable.patch(value, { id: observedState.id }); - } - else { - setStatefulState(this, value); - } - }, - - observeState(this: Stateful, id: string, observable: ObservableState): Handle { - let observedState = observedStateMap.get(this); - if (observedState) { - if (observedState.id === id && observedState.observable === observable) { - return observedState.handle; - } - throw new Error(`Already observing state with ID '${observedState.id}'`); - } - const stateful = this; - observedState = { - id, - observable, - subscription: observable - .observe(id) - .subscribe( - (item) => setStatefulState(stateful, item), /* next handler */ - (err) => { - /* TODO: Should we emit an error, instead of throwing? */ - throw err; - }, /* error handler */ - () => unobserve(stateful)), /* completed handler */ - handle: { - destroy() { - const observedState = observedStateMap.get(stateful); - if (observedState) { - observedState.subscription.unsubscribe(); - observedStateMap.delete(stateful); - } - } - } - }; - observedStateMap.set(stateful, observedState); - return observedState.handle; - } - }, - initialize(instance: StatefulMixin & Evented, options: StatefulOptions) { - /* Using Object.create(null) will improve performance when looking up properties in state */ - stateWeakMap.set(instance, Object.create(null)); - instance.own({ - destroy() { - stateWeakMap.delete(instance); - } - }); - if (options) { - const { id, stateFrom, state } = options; - if (typeof id !== 'undefined' && stateFrom) { - instance.own(instance.observeState(id, stateFrom)); - } - else if (stateFrom) { - throw new TypeError('When "stateFrom" option is supplied, factory also requires "id" option.'); - } - if (state) { - instance.setState(state); - } - } - } - }); - -export default createStateful; diff --git a/src/mixins/interfaces.ts b/src/mixins/interfaces.ts deleted file mode 100644 index 62c932e..0000000 --- a/src/mixins/interfaces.ts +++ /dev/null @@ -1,57 +0,0 @@ -/** - * We have copied the interfaces from RxJS that we are dependent upon in order to decouple the need - * to install RxJS to consume this package. These were derived from @reactivex/rxjs@5.0.0-beta.6. - * - * Hopefully these will mirror what eventually becomes the ES Observable interfaces and will become - * part of a standard library. - */ - -export interface NextObserver { - isUnsubscribed?: boolean; - next: (value: T) => void; - error?: (err: any) => void; - complete?: () => void; -} - -export interface ErrorObserver { - isUnsubscribed?: boolean; - next?: (value: T) => void; - error: (err: any) => void; - complete?: () => void; -} -export interface CompletionObserver { - isUnsubscribed?: boolean; - next?: (value: T) => void; - error?: (err: any) => void; - complete: () => void; -} - -export type PartialObserver = NextObserver | ErrorObserver | CompletionObserver; - -export interface Observable { - /** - * Registers handlers for handling emitted values, error and completions from the observable, and - * executes the observable's subscriber function, which will take action to set up the underlying data stream - * @method subscribe - * @param {PartialObserver|Function} observerOrNext (optional) either an observer defining all functions to be called, - * or the first of three possible handlers, which is the handler for each value emitted from the observable. - * @param {Function} error (optional) a handler for a terminal event resulting from an error. If no error handler is provided, - * the error will be thrown as unhandled - * @param {Function} complete (optional) a handler for a terminal event resulting from successful completion. - * @return {ISubscription} a subscription reference to the registered handlers - */ - subscribe(observerOrNext?: PartialObserver | ((value: T) => void), error?: (error: any) => void, complete?: () => void): Subscription; -} - -export interface AnonymousSubscription { - unsubscribe(): void; -} - -export type TeardownLogic = AnonymousSubscription | Function | void; - -export interface Subscription extends AnonymousSubscription { - unsubscribe(): void; - isUnsubscribed: boolean; - add(teardown: TeardownLogic): Subscription; - remove(sub: Subscription): void; -} diff --git a/tests/unit/all.ts b/tests/unit/all.ts index 9b0a2df..ae88460 100644 --- a/tests/unit/all.ts +++ b/tests/unit/all.ts @@ -2,5 +2,4 @@ import './aspect'; import './compose'; import './main'; import './bases/all'; -import './mixins/all'; import './util/all'; diff --git a/tests/unit/bases/createStateful.ts b/tests/unit/bases/createStateful.ts index 73060ed..6549036 100644 --- a/tests/unit/bases/createStateful.ts +++ b/tests/unit/bases/createStateful.ts @@ -2,8 +2,7 @@ import * as registerSuite from 'intern!object'; import * as assert from 'intern/chai!assert'; import { hasToStringTag } from '../../support/util'; import Promise from 'dojo-shim/Promise'; -import { State } from 'dojo-interfaces/bases'; -import { Observable, Observer } from 'rxjs/Rx'; +import Observable, { SubscriptionObserver } from 'dojo-shim/Observable'; import createStateful from '../../../src/bases/createStateful'; registerSuite({ @@ -13,25 +12,18 @@ registerSuite({ const stateful = createStateful(); assert.isUndefined(stateful.stateFrom); assert.deepEqual(stateful.state, {}, 'stateful should have empty state'); - assert.isFunction(stateful.setState, 'stateful should have `setState` function'); - }, - 'with state'() { - const stateful = createStateful({ - state: { foo: 'bar' } - }); - assert.deepEqual(stateful.state.foo, 'bar', 'state should have been set'); }, 'with id and stateFrom'() { let called = 0; const observer = { - observe(id: string): Observable { + observe(id: string): Observable { called++; - return new Observable(function subscribe(observer: Observer) { + return new Observable(function subscribe(observer: SubscriptionObserver) { observer.next({ foo: 'bar' }); observer.complete(); }); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { assert.strictEqual(options && options.id, 'foo'); return Promise.resolve(value); } @@ -52,14 +44,14 @@ registerSuite({ * 0 should be halnded gracefully */ let called = 0; const observer = { - observe(id: string): Observable { + observe(id: string): Observable { called++; - return new Observable(function subscribe(observer: Observer) { + return new Observable(function subscribe(observer: SubscriptionObserver) { observer.next({ foo: 'bar' }); observer.complete(); }); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { assert.strictEqual(options && options.id, 0); return Promise.resolve(value); } @@ -75,10 +67,10 @@ registerSuite({ }, 'with only stateForm throws'() { const observer = { - observe(id: string): Observable { + observe(id: string): Observable { return new Observable(() => {}); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { return Promise.resolve(value); } }; @@ -92,13 +84,13 @@ registerSuite({ }, 'destroy()'() { const observer = { - observe(id: string): Observable { - return new Observable(function subscribe(observer: Observer) { + observe(id: string): Observable { + return new Observable(function subscribe(observer: SubscriptionObserver) { observer.next({ foo: 'bar' }); observer.complete(); }); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { throw Error('Should not have been called!'); } }; @@ -142,17 +134,17 @@ registerSuite({ 'observeState()'() { let called = 0; let patchCalled = 0; - let observerRef: Observer; + let observerRef: SubscriptionObserver; const observer = { - observe(id: string): Observable { + observe(id: string): Observable { assert.strictEqual(id, 'foo'); called++; - return new Observable(function subscribe(observer: Observer) { + return new Observable(function subscribe(observer: SubscriptionObserver) { observerRef = observer; observerRef.next({ foo: 'bar' }); }); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { patchCalled++; observerRef.next(value); assert.strictEqual(options && options.id, 'foo'); @@ -180,16 +172,16 @@ registerSuite({ 'observeState() - completed/destroyed'() { let called = 0; let destroyed = 0; - let observerRef: Observer = undefined; + let observerRef: SubscriptionObserver = undefined; const observer = { - observe(id: string): Observable { + observe(id: string): Observable { assert.strictEqual(id, 'foo'); - return new Observable(function subscribe(observer: Observer) { + return new Observable(function subscribe(observer: SubscriptionObserver) { observerRef = observer; observerRef.next({ foo: 'bar' }); }); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { throw new Error('Should not have been called'); } }; @@ -225,16 +217,16 @@ registerSuite({ 'observeState() - completed but preventDefaut'() { let called = 0; let destroyed = 0; - let observerRef: Observer = undefined; + let observerRef: SubscriptionObserver = undefined; const observer = { - observe(id: string): Observable { + observe(id: string): Observable { assert.strictEqual(id, 'foo'); - return new Observable(function subscribe(observer: Observer) { + return new Observable(function subscribe(observer: SubscriptionObserver) { observerRef = observer; observerRef.next({ foo: 'bar' }); }); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { throw new Error('Should not have been called'); } }; @@ -271,12 +263,12 @@ registerSuite({ }, 'observeState() - error'() { const observer = { - observe(id: string): Observable { - return new Observable(function subscribe(observer: Observer) { + observe(id: string): Observable { + return new Observable(function subscribe(observer: SubscriptionObserver) { observer.error(new Error('Ooops...')); }); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { return Promise.resolve(value); } }; @@ -289,19 +281,19 @@ registerSuite({ }, 'observeState() - again'() { const observer1 = { - observe(id: string): Observable { + observe(id: string): Observable { return new Observable(() => {}); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { return Promise.resolve(value); } }; const observer2 = { - observe(id: string): Observable { - return new Observable(); + observe(id: string): Observable { + return new Observable(() => {}); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { return Promise.resolve(value); } }; @@ -326,15 +318,15 @@ registerSuite({ }, Error); }, 'observeState() - destroy handle'() { - let observerRef: Observer; + let observerRef: SubscriptionObserver; const observer = { - observe(id: string): Observable { - return new Observable(function subscribe(observer: Observer) { + observe(id: string): Observable { + return new Observable(function subscribe(observer: SubscriptionObserver) { observerRef = observer; observerRef.next({ foo: 'bar' }); }); }, - patch(value: any, options?: { id?: string }): Promise { + patch(value: any, options?: { id?: string }): Promise { observerRef.next(value); return Promise.resolve(value); } @@ -361,11 +353,7 @@ registerSuite({ foo?: string; } - const stateful = createStateful({ - state: { - foo: 'foo' - } - }); + const stateful = createStateful({}); stateful.on('state:changed', (event) => { count++; @@ -389,11 +377,11 @@ registerSuite({ foo?: string; } - let observerRef: Observer; + let observerRef: SubscriptionObserver; const observer = { observe(id: string): Observable { - return new Observable(function subscribe(observer: Observer) { + return new Observable(function subscribe(observer: SubscriptionObserver) { observerRef = observer; observerRef.next({ foo: 'bar' }); }); diff --git a/tests/unit/mixins/all.ts b/tests/unit/mixins/all.ts deleted file mode 100644 index 70b24df..0000000 --- a/tests/unit/mixins/all.ts +++ /dev/null @@ -1,3 +0,0 @@ -import './createDestroyable'; -import './createEvented'; -import './createStateful'; diff --git a/tests/unit/mixins/createDestroyable.ts b/tests/unit/mixins/createDestroyable.ts deleted file mode 100644 index 646499e..0000000 --- a/tests/unit/mixins/createDestroyable.ts +++ /dev/null @@ -1,68 +0,0 @@ -import * as registerSuite from 'intern!object'; -import * as assert from 'intern/chai!assert'; -import { hasToStringTag } from '../../support/util'; -import createDestroyable, { isDestroyable } from '../../../src/mixins/createDestroyable'; - -registerSuite({ - name: 'mixins/createDestroyable', - 'own/destroy handle'() { - let count = 0; - - const destroyable = createDestroyable(); - destroyable.own({ - destroy() { - count++; - } - }); - - assert.strictEqual(count, 0, 'handle should not be called yet'); - return destroyable.destroy().then(() => { - assert.strictEqual(count, 1, 'handle should have been called'); - return destroyable.destroy().then(() => { - assert.strictEqual(count, 1, 'handle should not have been called again'); - }); - }); - }, - 'own after destruction throws'() { - const destroyable = createDestroyable(); - destroyable.own({ - destroy() {} - }); - return destroyable.destroy().then(() => { - assert.throws(() => { - destroyable.own({ - destroy() {} - }); - }, Error); - }); - }, - 'own handle destruction'() { - let count = 0; - const destroyable = createDestroyable(); - const handle = destroyable.own({ - destroy() { - count++; - } - }); - assert.strictEqual(count, 0, 'destroy not called yet'); - handle.destroy(); - assert.strictEqual(count, 1, 'handle was destroyed'); - destroyable.destroy(); - assert.strictEqual(count, 1, 'destroy was not called again'); - }, - 'isDestroyable()'() { - const destroyable = createDestroyable(); - assert.isTrue(isDestroyable(destroyable)); - assert.isFalse(isDestroyable({})); - assert.isFalse(isDestroyable(undefined)); - assert.isFalse(isDestroyable(/foo/)); - assert.isFalse(isDestroyable(() => { })); - }, - 'toString()'(this: any) { - if (!hasToStringTag()) { - this.skip('Environment doesn\'t support Symbol.toStringTag'); - } - const destroyable = createDestroyable(); - assert.strictEqual(( destroyable).toString(), '[object Destroyable]'); - } -}); diff --git a/tests/unit/mixins/createEvented.ts b/tests/unit/mixins/createEvented.ts deleted file mode 100644 index 113dc31..0000000 --- a/tests/unit/mixins/createEvented.ts +++ /dev/null @@ -1,221 +0,0 @@ -import * as registerSuite from 'intern!object'; -import * as assert from 'intern/chai!assert'; -import { hasToStringTag } from '../../support/util'; -import createEvented from '../../../src/mixins/createEvented'; - -registerSuite({ - name: 'mixins/createEvented', - creation() { - const evented = createEvented(); - assert(evented); - assert.isFunction(evented.on); - assert.isFunction(evented.emit); - }, - 'listeners at creation'() { - const eventStack: string[] = []; - const evented = createEvented({ - listeners: { - 'foo'(event) { - eventStack.push(event.type); - }, - 'bar'(event) { - eventStack.push(event.type); - } - } - }); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - evented.emit({ type: 'baz' }); - - evented.destroy(); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - evented.emit({ type: 'baz' }); - - assert.deepEqual(eventStack, [ 'foo', 'bar' ]); - }, - 'listener array at creation'() { - const eventStack: string[] = []; - const evented = createEvented({ - listeners: { - foo: [ - function (event) { - eventStack.push('foo1-' + event.type); - }, - function (event) { - eventStack.push('foo2-' + event.type); - } - ], - bar(event) { - eventStack.push(event.type); - } - } - }); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - - evented.destroy(); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - - assert.deepEqual(eventStack, [ 'foo1-foo', 'foo2-foo', 'bar' ]); - }, - 'on': { - 'on()'() { - const eventStack: string[] = []; - const evented = createEvented(); - const handle = evented.on('foo', (event) => { - eventStack.push(event.type); - }); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - - handle.destroy(); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - - assert.deepEqual(eventStack, [ 'foo' ]); - }, - 'listener on creation, plus on'() { - const eventStack: string[] = []; - const evented = createEvented({ - listeners: { - foo(event) { - eventStack.push('listener:' + event.type); - } - } - }); - - const handle = evented.on('foo', (event) => { - eventStack.push('on:' + event.type); - }); - - evented.emit({ type: 'foo' }); - handle.destroy(); - evented.emit({ type: 'foo' }); - evented.destroy(); - evented.emit({ type: 'foo' }); - - assert.deepEqual(eventStack, [ 'listener:foo', 'on:foo', 'listener:foo' ]); - }, - 'multiple listeners, same event'() { - const eventStack: string[] = []; - const evented = createEvented(); - - const handle1 = evented.on('foo', () => { - eventStack.push('one'); - }); - const handle2 = evented.on('foo', () => { - eventStack.push('two'); - }); - - evented.emit({ type: 'foo' }); - handle1.destroy(); - evented.emit({ type: 'foo' }); - handle2.destroy(); - evented.emit({ type: 'foo' }); - - assert.deepEqual(eventStack, [ 'one', 'two', 'two' ]); - }, - 'on(map)'() { - const eventStack: string[] = []; - const evented = createEvented(); - - const handle = evented.on({ - foo(event) { - eventStack.push(event.type); - }, - bar(event) { - eventStack.push(event.type); - } - }); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - handle.destroy(); - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - - assert.deepEqual(eventStack, [ 'foo', 'bar' ]); - }, - 'on(type, listener[])'() { - const eventStack: string[] = []; - const evented = createEvented(); - - const handle = evented.on({ - foo: [ - function (event) { - eventStack.push('foo1'); - }, - function (event) { - eventStack.push('foo2'); - } - ] - }); - - evented.emit({ type: 'foo' }); - handle.destroy(); - evented.emit({ type: 'foo' }); - - assert.deepEqual(eventStack, [ 'foo1', 'foo2' ]); - }, - 'on throws'() { - const evented = createEvented(); - assert.throws(() => { - ( evented).on(); - }, TypeError); - assert.throws(() => { - ( evented).on('type', () => {}, () => {}); - }, TypeError); - } - }, - 'actions': { - 'listener'() { - const eventStack: string[] = []; - const action = { - do(options: { event: { type: string; target: any; } }): void { - eventStack.push(options.event.type); - } - }; - - const evented = createEvented({ - listeners: { - foo: action - } - }); - - const handle = evented.on('bar', action); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - evented.emit({ type: 'baz' }); - - evented.destroy(); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - evented.emit({ type: 'baz' }); - - handle.destroy(); - - evented.emit({ type: 'foo' }); - evented.emit({ type: 'bar' }); - evented.emit({ type: 'baz' }); - - assert.deepEqual(eventStack, [ 'foo', 'bar', 'bar' ]); - } - }, - 'toString()'(this: any) { - if (!hasToStringTag()) { - this.skip('Environment doesn\'t support Symbol.toStringTag'); - } - const evented = createEvented(); - assert.strictEqual(( evented).toString(), '[object Evented]'); - } -}); diff --git a/tests/unit/mixins/createStateful.ts b/tests/unit/mixins/createStateful.ts deleted file mode 100644 index dd742a9..0000000 --- a/tests/unit/mixins/createStateful.ts +++ /dev/null @@ -1,426 +0,0 @@ -import * as registerSuite from 'intern!object'; -import * as assert from 'intern/chai!assert'; -import { hasToStringTag } from '../../support/util'; -import Promise from 'dojo-shim/Promise'; -import { Observable, Observer } from 'rxjs/Rx'; -import createStateful, { State } from '../../../src/mixins/createStateful'; - -registerSuite({ - name: 'mixins/createStateful', - creation: { - 'no options'() { - const stateful = createStateful(); - assert.deepEqual(stateful.state, {}, 'stateful should have empty state'); - assert.isFunction(stateful.setState, 'stateful should have `setState` function'); - }, - 'with state'() { - const stateful = createStateful({ - state: { foo: 'bar' } - }); - assert.deepEqual(stateful.state.foo, 'bar', 'state should have been set'); - }, - 'with id and stateFrom'() { - let called = 0; - const observer = { - observe(id: string): Observable { - called++; - return new Observable(function subscribe(observer: Observer) { - observer.next({ foo: 'bar' }); - observer.complete(); - }); - }, - patch(value: any, options?: { id?: string }): Promise { - assert.strictEqual(options && options.id, 'foo'); - return Promise.resolve(value); - } - }; - - const stateful = createStateful<{ foo?: string; }>({ - id: 'foo', - stateFrom: observer - }); - - assert.strictEqual(called, 1); - assert.deepEqual(stateful.state, { foo: 'bar' }); - }, - 'with id of 0'() { - /* while the interface specifies a string for an ID, real world usage may very well pass - * a numeric ID which will eventually get coerced into a string, therefore the number of - * 0 should be halnded gracefully */ - let called = 0; - const observer = { - observe(id: string): Observable { - called++; - return new Observable(function subscribe(observer: Observer) { - observer.next({ foo: 'bar' }); - observer.complete(); - }); - }, - patch(value: any, options?: { id?: string }): Promise { - assert.strictEqual(options && options.id, 0); - return Promise.resolve(value); - } - }; - - const stateful = createStateful<{ foo?: string; }>({ - id: 0, - stateFrom: observer - }); - - assert.strictEqual(called, 1); - assert.deepEqual(stateful.state, { foo: 'bar' }); - }, - 'with only stateForm throws'() { - const observer = { - observe(id: string): Observable { - return new Observable(() => {}); - }, - patch(value: any, options?: { id?: string }): Promise { - return Promise.resolve(value); - } - }; - - assert.throws(() => { - createStateful({ - stateFrom: observer - }); - }, TypeError); - } - }, - 'destroy()'() { - const observer = { - observe(id: string): Observable { - return new Observable(function subscribe(observer: Observer) { - observer.next({ foo: 'bar' }); - observer.complete(); - }); - }, - patch(value: any, options?: { id?: string }): Promise { - throw Error('Should not have been called!'); - } - }; - - const stateful = createStateful<{ foo?: string; }>({ - id: 'foo', - stateFrom: observer - }); - - stateful.destroy(); - - assert.isUndefined(stateful.state); - - assert.throws(() => { - stateful.setState({ foo: 'bar' }); - }, TypeError); - }, - 'setState'() { - const stateful = createStateful(); - stateful.setState({ - bar: 'foo' - }); - assert.deepEqual(stateful.state, { bar: 'foo' }); - stateful.setState({ - foo: 1 - }); - assert.deepEqual(stateful.state, { foo: 1, bar: 'foo' }); - const state = { - foo: [ { foo: 'bar' }, { foo: 'baz' } ] - }; - stateful.setState(state); - assert.notStrictEqual(( stateful.state).foo, state.foo, 'state should not be strict equal'); - assert.deepEqual(( stateful.state).foo, state.foo, 'state should be deeply equal'); - stateful.setState({ bar: undefined }); - assert.isUndefined(( stateful.state).bar, 'bar is undefined'); - state.foo.push({ foo: 'qat' }); - assert.strictEqual(( stateful.state).foo.length, 2, 'state should remain untouched'); - }, - 'observe state': { - 'observeState()'() { - let called = 0; - let patchCalled = 0; - let observerRef: Observer; - const observer = { - observe(id: string): Observable { - assert.strictEqual(id, 'foo'); - called++; - return new Observable(function subscribe(observer: Observer) { - observerRef = observer; - observerRef.next({ foo: 'bar' }); - }); - }, - patch(value: any, options?: { id?: string }): Promise { - patchCalled++; - observerRef.next(value); - assert.strictEqual(options && options.id, 'foo'); - return Promise.resolve(value); - } - }; - - const stateful = createStateful(); - - stateful.observeState('foo', observer); - assert.strictEqual(called, 1); - assert.strictEqual(patchCalled, 0); - assert.deepEqual(stateful.state, { foo: 'bar' }); - - observer.patch({ foo: 'qat' }, { id: 'foo' }); - assert.strictEqual(called, 1); - assert.strictEqual(patchCalled, 1); - assert.deepEqual(stateful.state, { foo: 'qat' }); - - stateful.setState({ foo: 'foo'}); - assert.strictEqual(called, 1); - assert.strictEqual(patchCalled, 2); - assert.deepEqual(stateful.state, { foo: 'foo' }); - }, - 'observeState() - completed/destroyed'() { - let called = 0; - let destroyed = 0; - let observerRef: Observer = undefined; - const observer = { - observe(id: string): Observable { - assert.strictEqual(id, 'foo'); - return new Observable(function subscribe(observer: Observer) { - observerRef = observer; - observerRef.next({ foo: 'bar' }); - }); - }, - patch(value: any, options?: { id?: string }): Promise { - throw new Error('Should not have been called'); - } - }; - - const stateful = createStateful(); - - stateful.own({ - destroy() { - destroyed++; - } - }); - - stateful.on('statecomplete', (evt) => { - called++; - assert.strictEqual(evt.target, stateful); - }); - - stateful.observeState('foo', observer); - assert.deepEqual(stateful.state, { foo: 'bar' }); - - assert.strictEqual(called, 0); - assert.strictEqual(destroyed, 0); - - observerRef.complete(); - - assert.strictEqual(called, 1); - assert.strictEqual(destroyed, 1); - - assert.throws(() => { - stateful.setState({ foo: 'qat' }); - }); - }, - 'observeState() - completed but preventDefaut'() { - let called = 0; - let destroyed = 0; - let observerRef: Observer = undefined; - const observer = { - observe(id: string): Observable { - assert.strictEqual(id, 'foo'); - return new Observable(function subscribe(observer: Observer) { - observerRef = observer; - observerRef.next({ foo: 'bar' }); - }); - }, - patch(value: any, options?: { id?: string }): Promise { - throw new Error('Should not have been called'); - } - }; - - const stateful = createStateful(); - - stateful.own({ - destroy() { - destroyed++; - } - }); - - stateful.on('statecomplete', (evt) => { - called++; - assert.strictEqual(evt.target, stateful); - evt.preventDefault(); - }); - - stateful.observeState('foo', observer); - assert.deepEqual(stateful.state, { foo: 'bar' }); - - assert.strictEqual(called, 0); - assert.strictEqual(destroyed, 0); - - observerRef.complete(); - - assert.strictEqual(called, 1); - assert.strictEqual(destroyed, 0); - - stateful.setState({ foo: 'qat' }); - assert.deepEqual(stateful.state, { foo: 'qat' }); - assert.strictEqual(called, 1); - assert.strictEqual(destroyed, 0); - }, - 'observeState() - error'() { - const observer = { - observe(id: string): Observable { - return new Observable(function subscribe(observer: Observer) { - observer.error(new Error('Ooops...')); - }); - }, - patch(value: any, options?: { id?: string }): Promise { - return Promise.resolve(value); - } - }; - - const stateful = createStateful(); - - assert.throws(() => { - stateful.observeState('foo', observer); - }, Error, 'Ooops...'); - }, - 'observeState() - again'() { - const observer1 = { - observe(id: string): Observable { - return new Observable(() => {}); - }, - patch(value: any, options?: { id?: string }): Promise { - return Promise.resolve(value); - } - }; - - const observer2 = { - observe(id: string): Observable { - return new Observable(); - }, - patch(value: any, options?: { id?: string }): Promise { - return Promise.resolve(value); - } - }; - - const stateful = createStateful({ - id: 'foo', - stateFrom: observer1 - }); - - const handle = stateful.observeState('foo', observer1); - - assert(handle); - - assert.strictEqual(stateful.observeState('foo', observer1), handle, 'same handle should be returned'); - - assert.throws(() => { - stateful.observeState('bar', observer1); - }, Error); - - assert.throws(() => { - stateful.observeState('foo', observer2); - }, Error); - }, - 'observeState() - destroy handle'() { - let observerRef: Observer; - const observer = { - observe(id: string): Observable { - return new Observable(function subscribe(observer: Observer) { - observerRef = observer; - observerRef.next({ foo: 'bar' }); - }); - }, - patch(value: any, options?: { id?: string }): Promise { - observerRef.next(value); - return Promise.resolve(value); - } - }; - - const stateful = createStateful(); - - const handle = stateful.observeState('foo', observer); - assert.deepEqual(stateful.state, { foo: 'bar' }); - - handle.destroy(); - observer.patch({ foo: 'qat' }, { id: 'foo' }); - assert.deepEqual(stateful.state, { foo: 'bar' }); - - assert.doesNotThrow(() => { - handle.destroy(); - }); - } - }, - '"statechange" event type': { - 'local state'() { - let count = 0; - interface TestState { - foo?: string; - } - - const stateful = createStateful(); - - stateful.on('statechange', (event) => { - count++; - assert.strictEqual(event.target, stateful); - assert.strictEqual(event.type, 'statechange'); - assert.deepEqual(event.state, { foo: 'bar' }); - assert.strictEqual(event.state, event.target.state); - }); - - assert.strictEqual(count, 0, 'listener not called yet'); - - stateful.setState({ - foo: 'bar' - }); - - assert.strictEqual(count, 1, 'listener called once'); - }, - 'observed state'() { - let count = 0; - let patchCount = 0; - - interface TestState { - foo?: string; - } - - let observerRef: Observer; - - const observer = { - observe(id: string): Observable { - return new Observable(function subscribe(observer: Observer) { - observerRef = observer; - observerRef.next({ foo: 'bar' }); - }); - }, - patch(value: any, options?: { id?: string }): Promise { - patchCount++; - observerRef.next(value); - return Promise.resolve(value); - } - }; - - const stateful = createStateful({ - id: 'foo', - stateFrom: observer, - listeners: { 'statechange'() { count++; } } - }); - - assert.deepEqual(stateful.state, { foo: 'bar' }); - - assert.strictEqual(count, 1, 'listener called once'); - - stateful.setState({ foo: 'qat' }); - - assert.strictEqual(patchCount, 1, 'patch should have been called'); - assert.deepEqual(stateful.state, { foo: 'qat' }); - assert.strictEqual(count, 2, 'listener called again'); - } - }, - 'toString()'(this: any) { - if (!hasToStringTag()) { - this.skip('Environment doesn\'t support Symbol.toStringTag'); - } - const stateful: any = createStateful(); - assert.strictEqual(stateful.toString(), '[object Stateful]'); - } -}); diff --git a/tsconfig.json b/tsconfig.json index c12ef0e..b2fd518 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,14 +2,6 @@ "version": "2.0.3", "compilerOptions": { "declaration": false, - "lib": [ - "dom", - "es5", - "es2015.iterable", - "es2015.promise", - "es2015.symbol", - "es2015.symbol.wellknown" - ], "module": "umd", "moduleResolution": "node", "noImplicitAny": true, diff --git a/typings.json b/typings.json index edfe07a..7513b2d 100644 --- a/typings.json +++ b/typings.json @@ -1,7 +1,7 @@ { "name": "dojo-compose", "globalDependencies": { - "extra-rxjs": "github:dojo/typings/custom/dojo2-extras/rxjs.d.ts#103096ce945dd51a18cc47a9b7cf9191fdac0349" + "symbol-shim": "github:dojo/typings/custom/symbol-shim/symbol-shim.d.ts#003aa24b3448804a2c59e9a1d9740ca56e067e79" }, "globalDevDependencies": { "dojo2-dev": "github:dojo/typings/custom/dev/dev.d.ts#288d3a9868194f0e1ad6687371dffd1d96cb39a1"