mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	Add topic_generator.reverse_wrap_exclude().
This allows us to traverse a list backwards, cycling to the bottom as needed. This code is going to be used for the "A" key that cycles upward in the stream sidebar. It's probably overkill for that use case, but it does give us O(1) behavior and avoids the pitfall of accidentally mutating a list when reversing it.
This commit is contained in:
		@@ -80,6 +80,67 @@ function is_odd(i) { return i % 2 === 1; }
 | 
			
		||||
    assert.equal(gen.next(), 200);
 | 
			
		||||
}());
 | 
			
		||||
 | 
			
		||||
(function test_reverse() {
 | 
			
		||||
    var gen = tg.reverse_list_generator([10, 20, 30]);
 | 
			
		||||
    assert.equal(gen.next(), 30);
 | 
			
		||||
    assert.equal(gen.next(), 20);
 | 
			
		||||
    assert.equal(gen.next(), 10);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
 | 
			
		||||
    // If second parameter is not in the list, we just traverse the list
 | 
			
		||||
    // in reverse.
 | 
			
		||||
    gen = tg.reverse_wrap_exclude([10, 20, 30]);
 | 
			
		||||
    assert.equal(gen.next(), 30);
 | 
			
		||||
    assert.equal(gen.next(), 20);
 | 
			
		||||
    assert.equal(gen.next(), 10);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
 | 
			
		||||
    gen = tg.reverse_wrap_exclude([10, 20, 30], 'whatever');
 | 
			
		||||
    assert.equal(gen.next(), 30);
 | 
			
		||||
    assert.equal(gen.next(), 20);
 | 
			
		||||
    assert.equal(gen.next(), 10);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
 | 
			
		||||
    // Witness the mostly typical cycling behavior.
 | 
			
		||||
    gen = tg.reverse_wrap_exclude([5, 10, 20, 30], 20);
 | 
			
		||||
    assert.equal(gen.next(), 10);
 | 
			
		||||
    assert.equal(gen.next(), 5);
 | 
			
		||||
    assert.equal(gen.next(), 30);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
 | 
			
		||||
    gen = tg.reverse_wrap_exclude([5, 10, 20, 30], 5);
 | 
			
		||||
    assert.equal(gen.next(), 30);
 | 
			
		||||
    assert.equal(gen.next(), 20);
 | 
			
		||||
    assert.equal(gen.next(), 10);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
 | 
			
		||||
    gen = tg.reverse_wrap_exclude([5, 10, 20, 30], 30);
 | 
			
		||||
    assert.equal(gen.next(), 20);
 | 
			
		||||
    assert.equal(gen.next(), 10);
 | 
			
		||||
    assert.equal(gen.next(), 5);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
 | 
			
		||||
    // Test small lists.
 | 
			
		||||
    gen = tg.reverse_wrap_exclude([], 5);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
 | 
			
		||||
    gen = tg.reverse_wrap_exclude([5], 5);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
 | 
			
		||||
    gen = tg.reverse_wrap_exclude([5], 10);
 | 
			
		||||
    assert.equal(gen.next(), 5);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
    assert.equal(gen.next(), undefined);
 | 
			
		||||
}());
 | 
			
		||||
 | 
			
		||||
(function test_fchain() {
 | 
			
		||||
    var mults = function (n) {
 | 
			
		||||
        var ret = 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,10 +19,31 @@ exports.sub_list_generator = function (lst, lower, upper) {
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.reverse_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 7/6/5
 | 
			
		||||
    var i = upper - 1;
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        next: function () {
 | 
			
		||||
            if (i < lower) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var res = lst[i];
 | 
			
		||||
            i -= 1;
 | 
			
		||||
            return res;
 | 
			
		||||
        },
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.list_generator = function (lst) {
 | 
			
		||||
    return exports.sub_list_generator(lst, 0, lst.length);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.reverse_list_generator = function (lst) {
 | 
			
		||||
    return exports.reverse_sub_list_generator(lst, 0, lst.length);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.fchain = function (outer_gen, get_inner_gen) {
 | 
			
		||||
    var outer_val = outer_gen.next();
 | 
			
		||||
    var inner_gen;
 | 
			
		||||
@@ -94,6 +115,24 @@ exports.wrap_exclude = function (lst, val) {
 | 
			
		||||
    return exports.chain(inners);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.reverse_wrap_exclude = function (lst, val) {
 | 
			
		||||
    if (val === undefined) {
 | 
			
		||||
        return exports.reverse_list_generator(lst);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var i = _.indexOf(lst, val);
 | 
			
		||||
    if (i < 0) {
 | 
			
		||||
        return exports.reverse_list_generator(lst);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var inners = [
 | 
			
		||||
         exports.reverse_sub_list_generator(lst, 0, i),
 | 
			
		||||
         exports.reverse_sub_list_generator(lst, i+1, lst.length),
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    return exports.chain(inners);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.filter = function (gen, filter_func) {
 | 
			
		||||
    return {
 | 
			
		||||
        next: function () {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user