Skip to content

Instantly share code, notes, and snippets.

@axefrog
Last active April 1, 2016 01:59
Show Gist options
  • Select an option

  • Save axefrog/5a89fcb4c56bfee0bb94 to your computer and use it in GitHub Desktop.

Select an option

Save axefrog/5a89fcb4c56bfee0bb94 to your computer and use it in GitHub Desktop.
An idea I was playing around with for improving the way sources are passed around in Cycle.js. I since discarded the approach after the discussion at https://github.com/cyclejs/core/issues/284
export function upgradeSources(sources) {
const sourceKeys = Array.from(Object.keys(sources));
const cleanSources = sources => sourceKeys
.reduce((acc, key) => (acc[key] = sources[key], acc), {});
function withCustom(baseSources, customSources) {
const cleanedSources = cleanSources(baseSources);
const nextSources = Object.assign({}, cleanedSources, customSources);
return augment(nextSources, cleanedSources);
}
function augment(nextSources, cleanedSources) {
let augmentedSources = Object.assign({
sanitize: function() {
return augment(cleanSources(this));
},
with: function(custom) {
return withCustom(this, custom);
}
}, nextSources);
return Object.assign(augmentedSources, {sources: augmentedSources});
}
return augment(sources);
}
import {assert} from 'chai';
import {upgradeSources} from './index';
import {inspect} from 'common/utils/testing'; // eslint-disable-line no-unused-vars
describe('upgradeSources()', () => {
function component({x, y, z, sources}) {
}
function widget({x, y, z, sources}) {
}
function main({x, sources}) {
// const b = a.with({y: 2});
return {
a: [
component(sources.with({x: 3}))
]
};
}
it('should return an augmented clone of the sources object', () => {
const sources = {a: 1, b: 2};
const upgradedSources = upgradeSources(sources);
assert.notEqual(sources, upgradedSources);
assert.property(sources, 'a', 'The original sources object was modified: property "a" is missing');
assert.property(sources, 'b', 'The original sources object was modified: property "b" is missing');
assert.strictEqual(sources.a, 1, 'The original sources object was modified: property "a" has the wrong value');
assert.strictEqual(sources.b, 2, 'The original sources object was modified: property "b" has the wrong value');
assert.property(upgradedSources, 'a', 'The upgraded sources object is missing property "a"');
assert.property(upgradedSources, 'b', 'The upgraded sources object is missing property "b"');
assert.equal(upgradedSources.a, sources.a, 'The upgraded sources object should have the same value for "a" as the original sources object');
assert.equal(upgradedSources.b, sources.b, 'The upgraded sources object should have the same value for "b" as the original sources object');
assert.isFunction(upgradedSources.with);
assert.isFunction(upgradedSources.sanitize);
assert.equal(upgradedSources, upgradedSources.sources);
});
describe('#with()', () => {
it('should return a clone of the basic sources object, augmented with additional properties and functions', () => {
const sources = {a: 1, b: 2};
const upgradedSources = upgradeSources(sources);
const custom = {m: 3, n: 4};
const customizedSources = upgradedSources.with(custom);
assert.notEqual(upgradedSources, customizedSources);
assert.equal(customizedSources, customizedSources.sources);
assert.property(customizedSources, 'a');
assert.property(customizedSources, 'b');
assert.property(customizedSources, 'm');
assert.property(customizedSources, 'n');
assert.equal(customizedSources.a, upgradedSources.a);
assert.equal(customizedSources.b, upgradedSources.b);
assert.equal(customizedSources.m, custom.m);
assert.equal(customizedSources.n, custom.n);
assert.isFunction(customizedSources.with);
assert.isFunction(customizedSources.sanitize);
});
it('should omit custom properties added by a previous call to with()', () => {
const sources = {a: 1, b: 2};
const upgradedSources = upgradeSources(sources);
const custom1 = {m: 3, n: 4};
const customizedSources1 = upgradedSources.with(custom1);
const custom2 = {q: 8, s: 9};
const customizedSources2 = customizedSources1.with(custom2);
assert.notEqual(customizedSources2, customizedSources1);
assert.property(customizedSources2, 'a');
assert.property(customizedSources2, 'b');
assert.property(customizedSources2, 'q');
assert.property(customizedSources2, 's');
assert.notProperty(customizedSources2, 'm');
assert.notProperty(customizedSources2, 'n');
assert.equal(customizedSources2.a, customizedSources1.a);
assert.equal(customizedSources2.b, customizedSources1.b);
assert.equal(customizedSources2.m, custom2.m);
assert.equal(customizedSources2.n, custom2.n);
assert.isFunction(customizedSources2.with);
assert.isFunction(customizedSources2.sanitize);
});
it('should preserve the derived state of core driver sources, in order to account for isolation', () => {
function fakeIsolate(sources) {
return Object.assign({}, sources, 'a' in sources ? {a: sources.a*100} : {});
}
const sources = {a:2, b:3};
const upgradedSources = upgradeSources(sources);
const isolatedSources = fakeIsolate(upgradedSources);
const customizedSources = isolatedSources.with({m: 7});
const customizedSources2 = isolatedSources.with({n: 8});
assert.equal(customizedSources.a, sources.a*100);
assert.equal(customizedSources.b, sources.b);
assert.equal(customizedSources2.a, sources.a*100);
assert.equal(customizedSources2.b, sources.b);
assert.equal(customizedSources2.n, 8);
});
});
describe('#sanitize()', () => {
it('should return an identical result to calling `with({})`', () => {
const sources = {a: 1, b: 2};
const upgradedSources = upgradeSources(sources);
const custom = {m: 3, n: 4};
const customizedSources = upgradedSources.with(custom);
const sanitizedSources = customizedSources.sanitize();
const decustomizedSources = customizedSources.with({});
assert.property(sanitizedSources, 'a');
assert.property(sanitizedSources, 'b');
assert.notProperty(sanitizedSources, 'm');
assert.notProperty(sanitizedSources, 'n');
assert.isFunction(sanitizedSources.with);
assert.isFunction(sanitizedSources.sanitize);
assert.property(decustomizedSources, 'a');
assert.property(decustomizedSources, 'b');
assert.notProperty(decustomizedSources, 'm');
assert.notProperty(decustomizedSources, 'n');
assert.isFunction(decustomizedSources.with);
assert.isFunction(decustomizedSources.sanitize);
});
});
// function run(sources) {
// const sources = {x: 1};
// return main(upgradeSources(sources));
// }
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment