Create topic_generator.js.

This commit is contained in:
Steve Howell
2017-04-05 20:40:40 -07:00
committed by showell
parent 3db61ecd20
commit 262a4d5da6
2 changed files with 274 additions and 0 deletions

View File

@@ -0,0 +1,133 @@
var tg = require('js/topic_generator.js');
function is_even(i) { return i % 2 === 0; }
function is_odd(i) { return i % 2 === 1; }
(function test_basics() {
var gen = tg.list_generator([10, 20, 30]);
assert.equal(gen.next(), 10);
assert.equal(gen.next(), 20);
assert.equal(gen.next(), 30);
assert.equal(gen.next(), undefined);
assert.equal(gen.next(), undefined);
var gen1 = tg.list_generator([100, 200]);
var gen2 = tg.list_generator([300, 400]);
var outers = [gen1, gen2];
gen = tg.chain(outers);
assert.equal(gen.next(), 100);
assert.equal(gen.next(), 200);
assert.equal(gen.next(), 300);
assert.equal(gen.next(), 400);
assert.equal(gen.next(), undefined);
assert.equal(gen.next(), undefined);
gen = tg.wrap([5, 15, 25, 35], 25);
assert.equal(gen.next(), 25);
assert.equal(gen.next(), 35);
assert.equal(gen.next(), 5);
assert.equal(gen.next(), 15);
assert.equal(gen.next(), undefined);
assert.equal(gen.next(), undefined);
gen = tg.wrap_exclude([5, 15, 25, 35], 25);
assert.equal(gen.next(), 35);
assert.equal(gen.next(), 5);
assert.equal(gen.next(), 15);
assert.equal(gen.next(), undefined);
assert.equal(gen.next(), undefined);
gen = tg.wrap([5, 15, 25, 35], undefined);
assert.equal(gen.next(), 5);
gen = tg.wrap_exclude([5, 15, 25, 35], undefined);
assert.equal(gen.next(), 5);
gen = tg.wrap([5, 15, 25, 35], 17);
assert.equal(gen.next(), 5);
gen = tg.wrap([], 42);
assert.equal(gen.next(), undefined);
var ints = tg.list_generator([1, 2, 3, 4, 5]);
gen = tg.filter(ints, is_even);
assert.equal(gen.next(), 2);
assert.equal(gen.next(), 4);
assert.equal(gen.next(), undefined);
assert.equal(gen.next(), undefined);
ints = tg.list_generator([]);
gen = tg.filter(ints, is_even);
assert.equal(gen.next(), undefined);
assert.equal(gen.next(), undefined);
}());
(function test_fchain() {
var mults = function (n) {
var ret = 0;
return {
next: function () {
ret += n;
return (ret <= 100) ? ret : undefined;
},
};
};
var ints = tg.list_generator([29, 43]);
var gen = tg.fchain(ints, mults);
assert.equal(gen.next(), 29);
assert.equal(gen.next(), 58);
assert.equal(gen.next(), 87);
assert.equal(gen.next(), 43);
assert.equal(gen.next(), 86);
assert.equal(gen.next(), undefined);
assert.equal(gen.next(), undefined);
ints = tg.wrap([33, 34, 37], 37);
ints = tg.filter(ints, is_odd);
gen = tg.fchain(ints, mults);
assert.equal(gen.next(), 37);
assert.equal(gen.next(), 74);
assert.equal(gen.next(), 33);
assert.equal(gen.next(), 66);
assert.equal(gen.next(), 99);
assert.equal(gen.next(), undefined);
assert.equal(gen.next(), undefined);
}());
(function test_topics() {
var streams = [1, 2, 3, 4];
var topics = {};
topics[1] = ['read', 'read', '1a', '1b', 'read', '1c'];
topics[2] = [];
topics[3] = ['3a', 'read', 'read', '3b', 'read'];
topics[4] = ['4a'];
function has_unread_messages(stream, topic) {
return topic !== 'read';
}
function get_topics(stream) {
return topics[stream];
}
function next_topic(curr_stream, curr_topic) {
return tg.next_topic(
streams,
get_topics,
has_unread_messages,
curr_stream,
curr_topic);
}
assert.equal(next_topic(1, '1a'), '1b');
assert.equal(next_topic(1, undefined), '1a');
assert.equal(next_topic(2, 'bogus'), '3a');
assert.equal(next_topic(3, '3b'), '3a');
assert.equal(next_topic(4, '4a'), '1a');
assert.equal(next_topic(undefined, undefined), '1a');
}());

View File

@@ -0,0 +1,141 @@
var topic_generator = (function () {
var exports = {};
exports.sub_list_generator = function (lst, lower, upper) {
// lower/upper has Python range semantics so if you pass
// in lower=5 and upper=8, you get elements 5/6/7
var i = lower;
return {
next: function () {
if (i >= upper) {
return;
}
var res = lst[i];
i += 1;
return res;
},
};
};
exports.list_generator = function (lst) {
return exports.sub_list_generator(lst, 0, lst.length);
};
exports.fchain = function (outer_gen, get_inner_gen) {
var outer_val = outer_gen.next();
var inner_gen;
return {
next: function () {
while (outer_val !== undefined) {
if (inner_gen === undefined) {
inner_gen = get_inner_gen(outer_val);
if (!inner_gen || !inner_gen.next) {
blueslip.error('Invalid generator returned.');
return;
}
}
var inner = inner_gen.next();
if (inner !== undefined) {
return inner;
}
outer_val = outer_gen.next();
inner_gen = undefined;
}
},
};
};
exports.chain = function (gen_lst) {
function get(which) {
return which;
}
var outer_gen = exports.list_generator(gen_lst);
return exports.fchain(outer_gen, get);
};
exports.wrap = function (lst, val) {
if (val === undefined) {
return exports.list_generator(lst);
}
var i = _.indexOf(lst, val);
if (i < 0) {
return exports.list_generator(lst);
}
var inners = [
exports.sub_list_generator(lst, i, lst.length),
exports.sub_list_generator(lst, 0, i),
];
return exports.chain(inners);
};
exports.wrap_exclude = function (lst, val) {
if (val === undefined) {
return exports.list_generator(lst);
}
var i = _.indexOf(lst, val);
if (i < 0) {
return exports.list_generator(lst);
}
var inners = [
exports.sub_list_generator(lst, i+1, lst.length),
exports.sub_list_generator(lst, 0, i),
];
return exports.chain(inners);
};
exports.filter = function (gen, filter_func) {
return {
next: function () {
while (true) {
var val = gen.next();
if (val === undefined) {
return;
}
if (filter_func(val)) {
return val;
}
}
},
};
};
exports.next_topic = function (streams, get_topics, has_unread_messages, curr_stream, curr_topic) {
var stream_gen = exports.wrap(streams, curr_stream);
function get_topic_gen(which_stream) {
var gen;
if (which_stream === curr_stream) {
gen = exports.wrap_exclude(get_topics(which_stream), curr_topic);
} else {
gen = exports.list_generator(get_topics(which_stream));
}
var has_unread = function (topic) {
return has_unread_messages(which_stream, topic);
};
return exports.filter(gen, has_unread);
}
var outer_gen = exports.fchain(stream_gen, get_topic_gen);
return outer_gen.next();
};
return exports;
}());
if (typeof module !== 'undefined') {
module.exports = topic_generator;
}