diff --git a/package.json b/package.json index 8f7da02..3d5894c 100644 --- a/package.json +++ b/package.json @@ -20,13 +20,12 @@ "@cycle/run": "*" }, "peerDependencies": { - "@cycle/run": "^3.1.0", "electron-prebuilt": "^0.36.0", - "rxjs": "^5.4.0" + "xstream": "^10.8.0" }, "devDependencies": { "@cycle/run": "^3.1.0", - "@cycle/rxjs-run": "^7.0.0", + "babel-cli": "^6.5.1", "babel-preset-es2015": "^6.5.0", "babel-register": "^6.5.0", @@ -35,9 +34,9 @@ "electron-prebuilt": "^0.36.7", "istanbul": "^1.0.0-alpha.2", "mocha": "^2.4.5", - "rxjs": "^5.4.0", "sinon": "^1.17.3", - "sinon-chai": "^2.8.0" + "sinon-chai": "^2.8.0", + "xstream": "^10.8.0" }, "scripts": { "test": "mocha --compilers js:babel-register --recursive ./test/specs", diff --git a/src/AppConfigDriver.js b/src/AppConfigDriver.js index 4cc75ce..c8a7b0a 100644 --- a/src/AppConfigDriver.js +++ b/src/AppConfigDriver.js @@ -1,5 +1,5 @@ -import { Observable } from 'rxjs'; -import { adapt } from '@cycle/run/lib/adapt'; +import xs from 'xstream'; +import dropRepeats from 'xstream/extra/dropRepeats'; import pathNames from './pathNames'; @@ -8,12 +8,16 @@ export default function AppPathsDriver(app) { const config$ = Observable.from(configXs$); const task$ = config$.map(config => config.tasks).filter(Boolean); - task$.forEach(tasks => app.setUserTasks(tasks)); + task$.addListener({ + next: tasks => app.setUserTasks(tasks) + }); const allowNTMLForNonIntranet$ = config$ .map(config => config.allowNTMLForNonIntranet) .filter(value => typeof(value) === 'boolean'); - allowNTMLForNonIntranet$.forEach(value => app.allowNTLMCredentialsForAllDomains(value)); + allowNTMLForNonIntranet$.addListener({ + next: value => app.allowNTLMCredentialsForAllDomains(value) + }); return { allowNTMLForNonIntranet$: allowNTMLForNonIntranet$.startWith(false), @@ -23,19 +27,19 @@ export default function AppPathsDriver(app) { .map(config => config.paths && config.paths[name]) .filter(Boolean); - pathChange$.forEach(path => app.setPath(name, path)); + pathChange$.addListener({ + next: path => app.setPath(name, path) + }); return Object.defineProperty(sources, name + '$', { get() { - return adapt(Observable - .of(app.getPath(name)) - .concat(pathChange$) - .distinct() - ); + return pathChange$ + .startWith(app.getPath(name)) + .compose(dropRepeats()); } }) }, { - app$: adapt(Observable.of(app.getAppPath())) + app$: xs.of(app.getAppPath()) }) }; } diff --git a/src/AppEventsDriver.js b/src/AppEventsDriver.js index c699446..350380d 100644 --- a/src/AppEventsDriver.js +++ b/src/AppEventsDriver.js @@ -1,6 +1,5 @@ -import { Observable } from 'rxjs'; -import { adapt } from '@cycle/run/lib/adapt'; - +import xs from 'xstream'; +import fromEvent from 'xstream/extra/fromEvent'; const eventParams = { 'open-file': ['path'], 'open-url': ['url'], @@ -15,11 +14,17 @@ const eventParams = { }; export default function AppEventsDriver(app) { - const events = Object.keys(eventParams).map(type => Observable - .fromEvent(app, type, (event, ...args) => eventParams[type].reduce( - (event, param, i) => Object.assign(event, { [param]: args[i] }), - Object.assign(event, { type }))) + const events = Object.keys(eventParams).map(type => + fromEvent(app, type) + .map(arg => { + arg = Array.isArray(arg) ? arg : [arg]; + const [event, ...paramValues] = arg; + return eventParams[type].reduce( + (ev, param, i) => Object.assign(ev, { [param]: paramValues[i] }), + Object.assign(event, { type }) + ) + }) ); - return () => adapt(Observable.merge(...events)); + return () => xs.merge(...events); } diff --git a/src/AppLifecycleDriver.js b/src/AppLifecycleDriver.js index ce90306..a70d42e 100644 --- a/src/AppLifecycleDriver.js +++ b/src/AppLifecycleDriver.js @@ -1,5 +1,5 @@ -import { Observable } from 'rxjs'; -import { adapt } from '@cycle/run/lib/adapt'; +import xs from 'xstream'; +import fromEvent from 'xstream/extra/fromEvent'; const eventMapping = { willFinishLaunching$: 'will-finish-launching', @@ -10,35 +10,41 @@ const eventMapping = { }; export default function AppLifecycleDriver(app) { - return cfgXs$ => { - const cfg$ = Observable.from(cfgXs$); + return cfg$ => { const source = Object.keys(eventMapping).reduce((obj, prop) => Object.defineProperty(obj, prop, { get() { - return adapt(Observable.fromEvent(app, eventMapping[prop])); + return fromEvent(app, eventMapping[prop]) } }), {}); Object.defineProperty(source, 'quit$', { get() { - return Observable.fromEvent(app, 'quit', (e, exitCode) => Object.assign({ exitCode }, e)); + return fromEvent(app, 'quit') + .map(([ev, exitCode]) => Object.assign(ev, { exitCode })); } }); let subscriptions = []; cfg$ .startWith({}) - .forEach(({ state = 'started', exitCode, isQuittingEnabled = true, isAutoExitEnabled = true } = {}) => { - subscriptions.filter(Boolean).forEach(s => s.dispose()); - subscriptions = [ - !isQuittingEnabled && source.beforeQuit$.forEach(e => e.preventDefault()), - !isAutoExitEnabled && source.willQuit$.forEach(e => e.preventDefault()) - ]; + .addListener({ + next: ({ state = 'started', exitCode, isQuittingEnabled = true, isAutoExitEnabled = true } = {}) => { + subscriptions.filter(Boolean).forEach(s => s.dispose()); + subscriptions = [ + !isQuittingEnabled && source.beforeQuit$.addListener({ + next: e => e.preventDefault() + }), + !isAutoExitEnabled && source.willQuit$.addListener({ + next: e => e.preventDefault() + }) + ]; - if (state === 'quitting') { - app.quit(); - } else if (state === 'exiting') { - app.exit(exitCode); + if (state === 'quitting') { + app.quit(); + } else if (state === 'exiting') { + app.exit(exitCode); + } } }); diff --git a/src/AppMetadataDriver.js b/src/AppMetadataDriver.js index ecbe26a..05e99bc 100644 --- a/src/AppMetadataDriver.js +++ b/src/AppMetadataDriver.js @@ -1,8 +1,7 @@ -import { Observable } from 'rxjs'; -import { adapt } from '@cycle/run/lib/adapt'; +import xs from 'xstream'; export default function AppMetadataDriver(app) { - return () => adapt(Observable.of({ + return () => xs.of({ get name() { return app.getName(); }, get version() { return app.getVersion(); }, get locale() { return app.getLocale(); } diff --git a/src/AppVisibilityDriver.js b/src/AppVisibilityDriver.js index 30768a4..56b66af 100644 --- a/src/AppVisibilityDriver.js +++ b/src/AppVisibilityDriver.js @@ -1,8 +1,9 @@ -import { Observable } from 'rxjs'; -import { adapt } from '@cycle/run/lib/adapt'; +import xs from 'xstream'; export default function AppVisibilityDriver(app) { return visibility$ => { - adapt(Observable.from(visibility$).forEach(isVisible => isVisible ? app.show() : app.hide())); + visibility$.addListener({ + next: isVisible => isVisible ? app.show() : app.hide() + }); }; } diff --git a/src/BasicAuthDriver.js b/src/BasicAuthDriver.js index a4918af..7c348af 100644 --- a/src/BasicAuthDriver.js +++ b/src/BasicAuthDriver.js @@ -1,17 +1,19 @@ -import { Observable } from 'rxjs'; -import { adapt } from '@cycle/run/lib/adapt'; +import xs from 'xstream'; +import fromEvent from 'xstream/extra/fromEvent'; export default function BasicAuthDriver(app) { return login$ => { - Observable.from(login$) - .filter(({ event }) => event.callback) - .forEach(({ event, username, password }) => event.callback(username, password)); + login$ + .filter(({event}) => event.callback) + .addListener({ + next: ({event, username, password}) => event.callback(username, password) + }); - return adapt(Observable.fromEvent( - app, - 'login', - (e, webContents, request, authInfo, callback) => { - e.preventDefault && e.preventDefault(); + return fromEvent(app, 'login') + .map(arg => { + arg = Array.isArray(arg) ? arg : [arg]; + const [ev, webContents, request, authInfo, callback] = arg; + ev.preventDefault && ev.preventDefault(); return { webContents, request, authInfo, callback }; })); }; diff --git a/src/CertErrorOverrideDriver.js b/src/CertErrorOverrideDriver.js index 9031b40..a8e5d37 100644 --- a/src/CertErrorOverrideDriver.js +++ b/src/CertErrorOverrideDriver.js @@ -1,22 +1,22 @@ -import { Observable } from 'rxjs'; -import { adapt } from '@cycle/run/lib/adapt'; +import fromEvent from 'xstream/extra/fromEvent'; export default function CertErrorOverrideDriver(app) { return (override$) => { Observable.from(override$) .filter(({ event }) => event && event.callback) - .forEach(({ event: { callback }, allow = false }) => callback(allow)); + .addListener({ + next: ({ event: { callback }, allow = false }) => callback(allow) + }); - return adapt(Observable.fromEvent( - app, - 'certificate-error', - (event, webContents, url, error, certificate, callback) => { + return fromEvent(app, 'certificate-error') + .map(arg => { + arg = Array.isArray(arg) ? arg : [arg]; + const [event, webContents, url, error, certificate, callback] = arg; event.preventDefault && event.preventDefault(); return Object.assign( event, { webContents, url, error, certificate, callback } - ) - } - )); - } + ); + }); + }; } diff --git a/src/ClientCertDriver.js b/src/ClientCertDriver.js index 74de45b..92e4ecd 100644 --- a/src/ClientCertDriver.js +++ b/src/ClientCertDriver.js @@ -1,18 +1,19 @@ -import { Observable } from 'rxjs'; -import { adapt } from '@cycle/run/lib/adapt'; +import fromEvent from 'xstream/extra/fromEvent'; export default function ClientCertDriver(app) { return prompt$ => { Observable.from(prompt$) .filter(({ event: { callback } }) => callback) - .forEach(({ event: { callback }, cert }) => callback(cert)); + .addListener({ + next: ({ event: { callback }, cert }) => callback(cert) + }); - return adapt(Observable.fromEvent( - app, - 'select-client-certificate', - ({ preventDefault }, webContents, url, certificateList, callback) => { + return fromEvent(app, 'select-client-certificate') + .map(arg => { + arg = Array.isArray(arg) ? arg : [arg]; + const [{ preventDefault }, webContents, url, certificateList, callback] = arg; preventDefault && preventDefault(); return { webContents, url, certificateList, callback }; - })); - } + }); + }; } diff --git a/src/MainDriver.js b/src/MainDriver.js index b51466b..174eb04 100644 --- a/src/MainDriver.js +++ b/src/MainDriver.js @@ -1,29 +1,30 @@ -import { Observable, Subject } from 'rxjs'; -import { adapt } from '@cycle/run/lib/adapt'; +import xs from 'xstream'; +import fromEvent from 'xstream/extra/fromEvent'; export default function AppDriver(app, opts = {}) { let extraLaunch$ = null; if (opts.isSingleInstance) { - extraLaunch$ = new Subject(); - const shouldQuit = app.makeSingleInstance((argv, cwd) => extraLaunch$.next({ argv, cwd })); + extraLaunch$ = xs.never(); + const shouldQuit = app.makeSingleInstance((argv, cwd) => extraLaunch$.shamefullySendNext({ argv, cwd })); if (shouldQuit) { app.quit(); } } else { - extraLaunch$ = Observable.empty(); + extraLaunch$ = xs.empty(); } - return stateXs$ => { - const state$ = Observable.from(stateXs$); + return state$ => { let subscriptions = []; - state$.forEach(state => { - subscriptions.filter(Boolean).forEach(s => s.dispose()); - subscriptions = setupSinkSubscriptions(app, state); + state$.addListener({ + next: state => { + subscriptions.filter(Boolean).forEach(s => s.dispose()); + subscriptions = setupSinkSubscriptions(app, state); + } }); return { @@ -32,16 +33,16 @@ export default function AppDriver(app, opts = {}) { }, events: setupEventSources(app, extraLaunch$), get badgeLabel$() { - return adapt(Observable - .of(app.dock.getBadge()) - .concat(state$.flatMap(({ dock: { badgeLabel$ = Observable.empty() } = {} } = {}) => badgeLabel$))); + return state$.map(({ dock: { badgeLabel$ = xs.empty() } = {} } = {}) => badgeLabel$) + .flatten() + .startWith(app.dock.getBadge()); } } }; } function setupEventSources(app, extraLaunch$) { - return Object.assign(eventName => Observable.fromEvent(app, eventName), { extraLaunch$ }); + return Object.assign(eventName => fromEvent(app, eventName), { extraLaunch$ }); } function setupSinkSubscriptions(app, state) { @@ -52,20 +53,24 @@ function setupSinkSubscriptions(app, state) { } function subscribeToAppUserModelIdChanges(app, id$) { - return id$ && id$.forEach(id => app.setAppUserModelId(id)); + return id$ && id$.addListener({ + next: id => app.setAppUserModelId(id) + }); } function subscribeToNewChromiumParams(app, param$) { - return param$ && param$.forEach(({ switches = [], args = [] } = {}) => { - switches.forEach(obj => { - const applyArgs = [obj.switch]; - if ('value' in obj) { - applyArgs.push(obj.value); - } - app.appendSwitch.apply(app, applyArgs); - }); - - args.forEach(arg => app.appendArgument(arg)); + return param$ && param$.addListener({ + next: ({ switches = [], args = [] } = {}) => { + switches.forEach(obj => { + const applyArgs = [obj.switch]; + if ('value' in obj) { + applyArgs.push(obj.value); + } + app.appendSwitch.apply(app, applyArgs); + }); + + args.forEach(arg => app.appendArgument(arg)); + } }); } @@ -89,21 +94,27 @@ function subscribeToDockBounceSinks(app, bounce) { const nativeIds = {}; return [ - bounce.start$ && bounce.start$.forEach(({ id, type = 'informational' } = {}) => { - nativeIds[id] = app.dock.bounce(type); + bounce.start$ && bounce.start$.addListener({ + next: ({ id, type = 'informational' } = {}) => { + nativeIds[id] = app.dock.bounce(type); + } }), - bounce.cancel$ && bounce.cancel$.forEach(id => { - const nativeId = nativeIds[id]; - if (nativeId) { - app.dock.cancelBounce(nativeId); + bounce.cancel$ && bounce.cancel$.addListener({ + next: id => { + const nativeId = nativeIds[id]; + if (nativeId) { + app.dock.cancelBounce(nativeId); + } + delete nativeIds[id]; } - delete nativeIds[id]; }) ]; } function subscribeToDockBadgeLabels(app, badgeLabel$) { - return badgeLabel$ && badgeLabel$.forEach(label => app.dock.setBadge(label)); + return badgeLabel$ && badgeLabel$.addListener({ + next: label => app.dock.setBadge(label) + }); } function subscribeToDockVisibility(app, visibility$) { @@ -112,15 +123,23 @@ function subscribeToDockVisibility(app, visibility$) { } return [ - visibility$.filter(value => value === false).forEach(() => app.dock.hide()), - visibility$.filter(value => value === true).forEach(() => app.dock.show()) + visibility$.filter(value => value === false).addListener({ + next: () => app.dock.hide() + }), + visibility$.filter(value => value === true).addListener({ + next: () => app.dock.show() + }) ]; } function subscribeToDockMenus(app, menu$) { - return menu$ && menu$.forEach(menu => app.dock.setMenu(menu)); + return menu$ && menu$.addListener({ + next: menu => app.dock.setMenu(menu) + }); } function subscribeToDockIcons(app, icon$) { - return icon$ && icon$.forEach(icon => app.dock.setIcon(icon)); + return icon$ && icon$.addListener({ + next: icon => app.dock.setIcon(icon) + }); } diff --git a/src/RecentDocsDriver.js b/src/RecentDocsDriver.js index 6e311e1..43edc09 100644 --- a/src/RecentDocsDriver.js +++ b/src/RecentDocsDriver.js @@ -3,12 +3,14 @@ import { adapt } from '@cycle/run/lib/adapt'; export default function RecentDocsDriver(app) { return recentDoc$ => { - adapt(Observable.from(recentDoc$).forEach(ops => { - if (ops.clear) { - app.clearRecentDocuments(); - } - if (ops.add) { - app.addRecentDocument(ops.add); + recentDoc$.addListener({ + next: ops => { + if (ops.clear) { + app.clearRecentDocuments(); + } + if (ops.add) { + app.addRecentDocument(ops.add); + } } })); }; diff --git a/test/specs/AppConfigDriver.tests.js b/test/specs/AppConfigDriver.tests.js index b7ed780..ec9b4b9 100644 --- a/test/specs/AppConfigDriver.tests.js +++ b/test/specs/AppConfigDriver.tests.js @@ -3,8 +3,8 @@ import pathNames from '../../src/pathNames'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import xs from 'xstream'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -24,7 +24,7 @@ describe('The AppConfigDriver', () => { app.getPath.withArgs(name).returns('/some/path'); run(({ config: { paths } }) => ({ - output: paths[source].first().forEach(assert) + output: paths[source].take(1).addListener({ next: assert }) }), { config: AppConfigDriver(app) }); @@ -41,22 +41,24 @@ describe('The AppConfigDriver', () => { app.getPath.withArgs(name).onFirstCall().returns(originalPath); run(({ config: { paths } }) => { - const path$ = paths[source]; + const path$ = paths[source].remember(); return { - config: Observable.of({ paths: { [name]: newPath } }), - output1: path$.first(), - output2: path$.skip(1).first() + config: xs.of({ paths: { [name]: newPath } }), + output1: path$.take(1), + output2: path$.drop(1).take(1) } }, { config: AppConfigDriver(app), - output1: path$ => Observable.from(path$).forEach(path => { - expect(path).to.equal('/original/path') + output1: path$ => path$.addListener({ + next: path => expect(path).to.equal('/original/path') }), - output2: path$ => Observable.from(path$).forEach(path => { - expect(app.setPath).to.have.been.calledWith(name, newPath); - expect(path).to.equal(newPath); - done(); + output2: path$ => path$.addListener({ + next: path => { + expect(app.setPath).to.have.been.calledWith(name, newPath); + expect(path).to.equal(newPath); + done(); + } }) }); }); @@ -68,7 +70,7 @@ describe('The AppConfigDriver', () => { app.getAppPath.returns('/some/path'); run(({ config: { paths } }) => ({ - output: paths.app$.first().forEach(assert) + output: paths.app$.take(1).addListener({ next: assert }) }), { config: AppConfigDriver(app) }); @@ -84,20 +86,24 @@ describe('The AppConfigDriver', () => { describe('allowNTMLForNonIntranet$', () => { it('reflects changes to the allowNTMLForNonIntranet config setting', done => { run(({ config }) => ({ - config: Observable.of({ + config: xs.of({ allowNTMLForNonIntranet: true }), output: config.allowNTMLForNonIntranet$ }), { config: AppConfigDriver(app), output: value$ => { - Observable.from(value$).first().forEach(value => { - expect(value).to.be.false; + value$.take(1).addListener({ + next: value => { + expect(value).to.be.false; + } }); - Observable.from(value$).skip(1).first().forEach(value => { - expect(value).to.be.true; - expect(app.allowNTLMCredentialsForAllDomains).to.have.been.calledWith(true); - done(); + value$.drop(1).take(1).addListener({ + next: value => { + expect(value).to.be.true; + expect(app.allowNTLMCredentialsForAllDomains).to.have.been.calledWith(true); + done(); + } }) } }); @@ -114,7 +120,7 @@ describe('The AppConfigDriver', () => { ]; run(() => ({ - config$: Observable.of({ tasks }) + config$: xs.of({ tasks }) }), { config$: AppConfigDriver(app) }); diff --git a/test/specs/AppEventsDriver.tests.js b/test/specs/AppEventsDriver.tests.js index 2f64d48..cc2c226 100644 --- a/test/specs/AppEventsDriver.tests.js +++ b/test/specs/AppEventsDriver.tests.js @@ -2,8 +2,7 @@ import AppEventsDriver from '../../src/AppEventsDriver'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -35,7 +34,7 @@ describe('AppEventsDriver', () => { output: appEvent$.filter(e => e.type === eventName) }), { app: driver, - output: event$ => Observable.from(event$).first().forEach(assert) + output: event$ => event$.take(1).addListener({ next: assert }) }); const origEventObj = {}; diff --git a/test/specs/AppLifecycleDriver.tests.js b/test/specs/AppLifecycleDriver.tests.js index d21fbbd..5b5c6df 100644 --- a/test/specs/AppLifecycleDriver.tests.js +++ b/test/specs/AppLifecycleDriver.tests.js @@ -2,8 +2,8 @@ import AppLifecycleDriver from '../../src/AppLifecycleDriver'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import xs from 'xstream'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -31,7 +31,7 @@ describe('The AppLifecycleDriver', () => { output: lifecycle[prop] }), { lifecycle: AppLifecycleDriver(app), - output: event$ => Observable.from(event$).first().forEach(verify) + output: event$ => event$.take(1).addListener({ next: verify }) }); const emittedEvent = {}; @@ -51,7 +51,7 @@ describe('The AppLifecycleDriver', () => { output: lifecycle.quit$ }), { lifecycle: AppLifecycleDriver(app), - output: event$ => Observable.from(event$).first().forEach(verify) + output: event$ => event$.take(1).addListener({ next: verify }) }); const emittedEvent = {}; @@ -75,7 +75,7 @@ describe('The AppLifecycleDriver', () => { const flag = preventionFlags[eventName]; it(`prevents ${eventName} default behaviors if ${flag} is false`, done => { run(({ lifecycle }) => ({ - lifecycle: Observable.of({ + lifecycle: xs.of({ [flag]: false }) }), { @@ -94,7 +94,7 @@ describe('The AppLifecycleDriver', () => { it('initiates a quit if `state` is set to `quitting`', done => { run(({ lifecycle }) => ({ - lifecycle: Observable.of({ + lifecycle: xs.of({ state: 'quitting' }) }), { @@ -109,7 +109,7 @@ describe('The AppLifecycleDriver', () => { it('initiates an exit if `state` is set to `exiting`', done => { run(({ lifecycle }) => ({ - lifecycle: Observable.of({ + lifecycle: xs.of({ state: 'exiting' }) }), { @@ -124,7 +124,7 @@ describe('The AppLifecycleDriver', () => { it('passes a specific exit code if `state` is `exiting` and `exitCode` is specified', done => { run(({ lifecycle }) => ({ - lifecycle: Observable.of({ + lifecycle: xs.of({ state: 'exiting', exitCode: 255 }) diff --git a/test/specs/AppMetadataDriver.tests.js b/test/specs/AppMetadataDriver.tests.js index 6bd3af4..21fe267 100644 --- a/test/specs/AppMetadataDriver.tests.js +++ b/test/specs/AppMetadataDriver.tests.js @@ -2,8 +2,7 @@ import AppMetadataDriver from '../../src/AppMetadataDriver'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -21,9 +20,11 @@ describe('The AppMetadataDriver', () => { output: metadata$ }), { metadata$: new AppMetadataDriver(app), - output: metadata$ => Observable.from(metadata$).first().forEach(metadata => { - expect(metadata).to.have.property('name', 'Some arbitrary app'); - done(); + output: metadata$ => metadata$.take(1).addListener({ + next: metadata => { + expect(metadata).to.have.property('name', 'Some arbitrary app'); + done(); + } }) }); }); @@ -35,9 +36,11 @@ describe('The AppMetadataDriver', () => { output: metadata$ }), { metadata$: new AppMetadataDriver(app), - output: metadata$ => Observable.from(metadata$).first().forEach(metadata => { - expect(metadata).to.have.property('version', '1.2.3'); - done(); + output: metadata$ => metadata$.take(1).addListener({ + next: metadata => { + expect(metadata).to.have.property('version', '1.2.3'); + done(); + } }) }); }); @@ -49,9 +52,11 @@ describe('The AppMetadataDriver', () => { output: metadata$ }), { metadata$: new AppMetadataDriver(app), - output: metadata$ => Observable.from(metadata$).first().forEach(metadata => { - expect(metadata).to.have.property('locale', 'es-MX'); - done(); + output: metadata$ => metadata$.take(1).addListener({ + next: metadata => { + expect(metadata).to.have.property('locale', 'es-MX'); + done(); + } }) }); }); diff --git a/test/specs/AppVisibilityDriver.tests.js b/test/specs/AppVisibilityDriver.tests.js index ed7fc1e..7d38392 100644 --- a/test/specs/AppVisibilityDriver.tests.js +++ b/test/specs/AppVisibilityDriver.tests.js @@ -2,8 +2,8 @@ import AppVisibilityDriver from '../../src/AppVisibilityDriver'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import xs from 'xstream'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -16,7 +16,7 @@ describe('AppVisibilityDriver', () => { it('calls `app.hide()` for `false` values', done => { run(() => ({ - visibility$: Observable.of(false) + visibility$: xs.of(false) }), { visibility$: AppVisibilityDriver(app) }); @@ -29,7 +29,7 @@ describe('AppVisibilityDriver', () => { it('calls `app.show()` for `true` values', done => { run(() => ({ - visibility$: Observable.of(true) + visibility$: xs.of(true) }), { visibility$: AppVisibilityDriver(app) }); diff --git a/test/specs/BasicAuthDriver.tests.js b/test/specs/BasicAuthDriver.tests.js index 218c58d..92d3d93 100644 --- a/test/specs/BasicAuthDriver.tests.js +++ b/test/specs/BasicAuthDriver.tests.js @@ -2,8 +2,7 @@ import BasicAuthDriver from '../../src/BasicAuthDriver'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -20,7 +19,7 @@ describe('The BasicAuthDriver', () => { output: login$ }), { login$: BasicAuthDriver(app), - output: login$ => Observable.from(login$).first().forEach(assert) + output: login$ => login$.take(1).addListener({ next: assert }) }); const webContents = {}; @@ -41,7 +40,7 @@ describe('The BasicAuthDriver', () => { output: login$ }), { login$: BasicAuthDriver(app), - output: login$ => Observable.from(login$).first().forEach(assert) + output: login$ => login$.take(1).addListener({ next: assert }) }); const origEvent = { preventDefault: spy() }; diff --git a/test/specs/CertErrorOverrideDriver.js b/test/specs/CertErrorOverrideDriver.js index eacd49c..03bd6c6 100644 --- a/test/specs/CertErrorOverrideDriver.js +++ b/test/specs/CertErrorOverrideDriver.js @@ -2,8 +2,7 @@ import CertErrorOverrideDriver from '../../src/CertErrorOverrideDriver'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -20,7 +19,7 @@ describe('The CertErrorOverrideDriver', () => { output: certErr$ }), { certErr$: new CertErrorOverrideDriver(app), - output: certErr$ => Observable.from(certErr$).first().forEach(assert) + output: certErr$ => certErr$.take(1).addListener({ next: assert }) }); const certErrorEvent = {}; diff --git a/test/specs/ClientCertDriver.tests.js b/test/specs/ClientCertDriver.tests.js index a4e0c73..042703f 100644 --- a/test/specs/ClientCertDriver.tests.js +++ b/test/specs/ClientCertDriver.tests.js @@ -2,8 +2,7 @@ import ClientCertDriver from '../../src/ClientCertDriver'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -20,7 +19,7 @@ describe('The ClientCertDriver', () => { output: certPrompt$ }), { certPrompt$: ClientCertDriver(app), - output: certPrompt$ => Observable.from(certPrompt$).first().forEach(assert) + output: certPrompt$ => certPrompt$.take(1).addListener({ next: assert }) }); const webContents = {}; @@ -43,7 +42,7 @@ describe('The ClientCertDriver', () => { output: certPrompt$ }), { certPrompt$: ClientCertDriver(app), - output: prompt$ => Observable.from(prompt$).forEach(() => {}) + output: prompt$ => prompt$.addListener({ next: () => {} }) }); const origEvent = { preventDefault: spy() }; diff --git a/test/specs/MainDriver.tests.js b/test/specs/MainDriver.tests.js index 84dce45..75437b8 100644 --- a/test/specs/MainDriver.tests.js +++ b/test/specs/MainDriver.tests.js @@ -4,8 +4,9 @@ import { expect } from 'chai'; import { spy } from 'sinon'; import Promise from 'bluebird'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import xs from 'xstream'; +import delay from 'xstream/extra/delay'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -22,7 +23,7 @@ describe('MainDriver', () => { run(() => { return { - electron: Observable.of({}) + electron: xs.of({}) } }, { electron: new MainDriver(app, { isSingleInstance: true }) @@ -41,12 +42,14 @@ describe('MainDriver', () => { app.isAeroGlassEnabled.returns(true); run(({ electron }) => ({ - output: Observable.of(electron.platformInfo.isAeroGlassEnabled) + output: xs.of(electron.platformInfo.isAeroGlassEnabled) }), { electron: driver, - output: value$ => Observable.from(value$).first().forEach(isEnabled => { - expect(isEnabled).to.be.true; - done(); + output: value$ => value$.take(1).addListener({ + next: isEnabled => { + expect(isEnabled).to.be.true; + done(); + } }) }); }); @@ -62,7 +65,7 @@ describe('MainDriver', () => { } }, { electron: driver, - receivedEvent$: events$ => Observable.from(events$).first().forEach(verify) + receivedEvent$: events$ => events$.take(1).addListener({ next: verify }) }); const emittedEvent = {}; @@ -87,7 +90,7 @@ describe('MainDriver', () => { } }, { electron: new MainDriver(app, { isSingleInstance: true }), - output: value$ => Observable.from(value$).forEach(assert) + output: value$ => value$.addListener({ next: assert }) }); setTimeout(() => { @@ -109,20 +112,22 @@ describe('MainDriver', () => { let valueCount = 0; run(({ electron }) => ({ - electron: Observable.of({ + electron: xs.of({ dock: { - badgeLabel$: Observable.timer(5).mapTo('Label 2') + badgeLabel$: xs.of('Label 2').compose(delay(5)) } }), output: electron.badgeLabel$ }), { electron: driver, - output: value$ => Observable.from(value$).forEach(label => { - valueCount++; - expect(label).to.equal(`Label ${valueCount}`); - if (valueCount === 2) { - expect(app.dock.setBadge).to.have.been.calledWith('Label 2'); - done(); + output: value$ => value$.addListener({ + next: label => { + valueCount++; + expect(label).to.equal(`Label ${valueCount}`); + if (valueCount === 2) { + expect(app.dock.setBadge).to.have.been.calledWith('Label 2'); + done(); + } } }) }); @@ -149,10 +154,10 @@ describe('MainDriver', () => { function testBounceStart(bounce, assertions) { return new Promise(resolve => { run(() => ({ - electron: Observable.of({ + electron: xs.of({ dock: { bounce: { - start$: Observable.of(bounce) + start$: xs.of(bounce) } } }) @@ -171,11 +176,11 @@ describe('MainDriver', () => { app.dock.bounce.returns(8346); run(() => ({ - electron: Observable.of({ + electron: xs.of({ dock: { bounce: { - start$: Observable.of({ id: 'auth-has-expired', type: 'critical' }), - cancel$: Observable.timer(5).map(() => 'auth-has-expired') + start$: xs.of({ id: 'auth-has-expired', type: 'critical' }), + cancel$: xs.of('auth-has-expired').compose(delay(5)) } } }) @@ -205,9 +210,9 @@ describe('MainDriver', () => { function testVisibility(value, assertions) { return new Promise(resolve => { run(() => ({ - electron: Observable.of({ + electron: xs.of({ dock: { - visibility$: Observable.of(value) + visibility$: xs.of(value) } }) }), { electron: driver }); @@ -225,9 +230,9 @@ describe('MainDriver', () => { const img = {}; run(() => ({ - electron: Observable.of({ + electron: xs.of({ dock: { - icon$: Observable.of(img) + icon$: xs.of(img) } }) }), { electron: driver }); @@ -244,9 +249,9 @@ describe('MainDriver', () => { const menu = {}; run(() => ({ - electron: Observable.of({ + electron: xs.of({ dock: { - menu$: Observable.of(menu) + menu$: xs.of(menu) } }) }), { electron: driver }); @@ -262,8 +267,8 @@ describe('MainDriver', () => { describe('newChromiumParam$', () => { it('calls appendSwitch and appendArgument for each switch & argument', done => { run(() => ({ - electron: Observable.of({ - newChromiumParam$: Observable.of({ + electron: xs.of({ + newChromiumParam$: xs.of({ switches: [ { 'switch': 'prefetch', value: 1 }, { 'switch': 'aggressive-cache-discard' } @@ -287,8 +292,8 @@ describe('MainDriver', () => { describe('appUserModelId$', () => { it('causes the setAppUserModelId method of the app to be called', done => { run(() => ({ - electron: Observable.of({ - appUserModelId$: Observable.of('new-user-model-id') + electron: xs.of({ + appUserModelId$: xs.of('new-user-model-id') }) }), { electron: driver }); diff --git a/test/specs/RecentDocsDriver.tests.js b/test/specs/RecentDocsDriver.tests.js index 35956bf..cb3d3a6 100644 --- a/test/specs/RecentDocsDriver.tests.js +++ b/test/specs/RecentDocsDriver.tests.js @@ -2,8 +2,8 @@ import RecentDocsDriver from '../../src/RecentDocsDriver'; import { expect } from 'chai'; import { spy } from 'sinon'; -import { Observable } from 'rxjs'; -import { run } from '@cycle/rxjs-run'; +import xs from 'xstream'; +import { run } from '@cycle/run'; import AppStub from '../stubs/App'; @@ -16,7 +16,7 @@ describe('RecentDocsDriver', () => { it('performs clear operations before adds', done => { run(() => ({ - recentDoc$: Observable.of({ + recentDoc$: xs.of({ clear: true, add: '/some/path' })