Skip to content

Commit

Permalink
Merge pull request #10 from michaelbpaulson/master
Browse files Browse the repository at this point in the history
Happy Case: Get Datasource chainer
  • Loading branch information
ThePrimeagen committed Nov 14, 2015
2 parents 5b465da + a898621 commit 953f193
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 26 deletions.
29 changes: 3 additions & 26 deletions src/DataSourceChainer.js
@@ -1,7 +1,6 @@
var getRequestCycle = require('./getRequestCycle');
var Subscribable = require('./Subscribable');
var AssignableDisposable = require('./AssignableDisposable');
var EMPTY_SOURCES_ARRAY = [];
var EMPTY_DISPOSABLE = {dispose: function empty() {}};

/**
* DataSourceChainer takes in a list of dataSources and calls them one at a time
Expand Down Expand Up @@ -31,35 +30,13 @@ DataSourceChainer.prototype = {
};

// Performs the internal get request loop.
return self._getRequestCycle(self, self._sources, 0,
paths, seed, observer);
return getRequestCycle(self._sources, 0,
paths, seed, observer);
});
},
set: function set(jsonGraph) {
},
call: function call(callPath, args, suffixes, paths) {
},

/**
* Performs the requesting of the data from each dataSource until exhausted
* or completed.
* @private
*/
_getRequestCycle: function _getRequestCycle(sourceChainer, sources,
sourceIndex, remainingPaths,
seed, observer, disposable) {
var currentSource = sources[sourceIndex];
disposable = disposable || new AssignableDisposable();

// Sources have been exhausted, time to finish
if (!currentSource) {
seed.unhandledPaths = remainingPaths;
observer.onNext(seed);
observer.onCompleted();
return EMPTY_DISPOSABLE;
}

return disposable;
}
};

Expand Down
Empty file added src/SourceRequest.js
Empty file.
82 changes: 82 additions & 0 deletions src/getRequestCycle.js
@@ -0,0 +1,82 @@
var AssignableDisposable = require('./AssignableDisposable');
var EMPTY_DISPOSABLE = {dispose: function empty() {}};

/**
* Performs the requesting of the data from each dataSource until exhausted
* or completed.
* @private
*/
// TODO: Clean up this function as its very large.
module.exports = function getRequestCycle(sources, sourceIndex, remainingPaths,
seed, observer, disposable) {

var currentSource = sources[sourceIndex];
disposable = disposable || new AssignableDisposable();

// Sources have been exhausted, time to finish
if (!currentSource || !remainingPaths || remainingPaths.length === 0) {
seed.unhandledPaths = remainingPaths;
observer.onNext(seed);
observer.onCompleted();
return EMPTY_DISPOSABLE;
}

// we have a current source so we need to attempt to fulfill the
// remaining paths.

// If the source index is greater than 1 then we need to attemp to
// optimize / reduce missing paths with our already formulated seed.
if (sourceIndex > 1) {
// TODO: optimize / reduce
}

// Request from the current source.
var jsonGraphFromSource;
disposable.currentDisposable = currentSource.
get(remainingPaths).
subscribe(function onNext(jsonGraphEnvelop) {
jsonGraphFromSource = jsonGraphEnvelop;
}, function onError(dataSourceError) {
// Exit condition.
if (disposable.disposed) {
return;
}

// TODO: If there has been an error what do we do?
// Are all paths considered 'unhandledPaths?' Its not really
// the case.
observer.onError(dataSourceError);
}, function onCompleted() {
// Exit condition.
if (disposable.disposed) {
return;
}

// We need to merge the results into our seed, if the source
// is the second or later source.
if (sourceIndex === 0) {
seed = {
jsonGraph: jsonGraphFromSource.jsonGraph,
paths: jsonGraphFromSource.paths
};
}

else {
// TODO: Merge algorithm
}

// are there unhandledPaths?
if (jsonGraphFromSource.unhandledPaths &&
jsonGraphFromSource.unhandledPaths.length) {
}

// We have finished here.
else {
observer.onNext(seed);
observer.onCompleted();
}
});


return disposable;
};
28 changes: 28 additions & 0 deletions test/AutoRespondDataSource.js
@@ -0,0 +1,28 @@
var Subscribable = require('./../src/Subscribable');
var AutoRespondDataSource = function AutoRespondDataSource(data, options) {
this._options = options || {};
this._data = data;
};

AutoRespondDataSource.prototype.get = function get() {
var self = this;
var options = self._options;
return new Subscribable(function getSubscribe(observer) {
if (options.wait) {
setTimeout(respond, options.wait);
} else {
respond();
}

function respond() {
onNext(self._data);
}

function onNext(data) {
observer.onNext(data);
observer.onCompleted();
}
});
};

module.exports = AutoRespondDataSource;
55 changes: 55 additions & 0 deletions test/src/DataSourceChainer.spec.js
Expand Up @@ -3,6 +3,7 @@ var sinon = require('sinon');
var toObservable = require('./../toObservable');
var noOp = function noOp() {};
var expect = require('chai').expect;
var AutoRespondDataSource = require('./../AutoRespondDataSource');

describe('DataSourceChainer', function() {
it('should be able to construct an empty chainer and make get requests.', function(done) {
Expand All @@ -23,4 +24,58 @@ describe('DataSourceChainer', function() {
subscribe(noOp, done, done);

});

it('should be ok with happy case DataSource where the first DataSource fills all data (sync).', function(done) {
var innerSource = new AutoRespondDataSource({
jsonGraph: {
hello: {
world: 'foo bar'
}
},
paths: [['hello', 'world']]
});
var source = new DataSourceChainer([innerSource]);
var onNext = sinon.spy();
toObservable(source.
get([['hello', 'world']])).
doAction(onNext, noOp, function() {
expect(onNext.calledOnce).to.be.ok;
expect(onNext.getCall(0).args[0]).to.deep.equals({
jsonGraph: {
hello: {
world: 'foo bar'
}
},
paths: [['hello', 'world']]
});
}).
subscribe(noOp, done, done);
});

it('should be ok with happy case DataSource where the first DataSource fills all data (async).', function(done) {
var innerSource = new AutoRespondDataSource({
jsonGraph: {
hello: {
world: 'foo bar'
}
},
paths: [['hello', 'world']]
}, {wait: 100});
var source = new DataSourceChainer([innerSource]);
var onNext = sinon.spy();
toObservable(source.
get([['hello', 'world']])).
doAction(onNext, noOp, function() {
expect(onNext.calledOnce).to.be.ok;
expect(onNext.getCall(0).args[0]).to.deep.equals({
jsonGraph: {
hello: {
world: 'foo bar'
}
},
paths: [['hello', 'world']]
});
}).
subscribe(noOp, done, done);
});
});

0 comments on commit 953f193

Please sign in to comment.