UNB/ CS/ David Bremner/ teaching/ cs2613/ tests/ T4/ sample/ samplesol/ filtered.js
const test=require("node:test");
const assert=require("assert");

class Filtered {
    constructor(list,predicate) {
        this.list = list;
        this.predicate = predicate
    }

    [Symbol.iterator]() {
        return new FilteredIterator(this);
    }
}

class FilteredIterator {
    constructor(obj) {
        this.obj = obj;
        this.index = 0;
    }

    next () {
        while (this.index < this.obj.list.length &&
               !this.obj.predicate(this.obj.list[this.index])) {
            this.index++;
        }
        if (this.index >= this.obj.list.length) {
            return {done: true}
        } else {
            let val = this.obj.list[this.index];
            this.index++;
            return {done: false, value: val}
        }
    }
}


test("empty", (t)=> {
    let results = [];
    for (let f of new Filtered([],(x)=>true)) { results.push(f); }
    assert.deepStrictEqual(results,[]);
});

test("nonempty", (t)=> {
    let results = [];
    let filter_obj = new Filtered([1,2,3,4],(x)=>(x % 2 == 0))
    for (let f of filter_obj) { results.push(f); }
    assert.deepStrictEqual(results,[2,4]);
});

test("big", (t)=> {
    let input = [], results=[];
    for (let i=0; i<100; i++){ input.push(i);}
    let filter_obj = new Filtered(input, (n) => n % 4 == 0 && n*n < 100);
    for (let f of filter_obj) { results.push(f); }
    assert.deepStrictEqual(results,[0,4,8]);
});
test("restart", (t)=> {
    let results1 = [];
    let filter_obj = new Filtered([1,2,3,4],(x)=>(x % 2 == 0));
    for (let f of filter_obj) { results1.push(f); }
    assert.deepStrictEqual(results1,[2,4]);
    let results2 = [];      
    for (let f of filter_obj) { results2.push(f); }
    assert.deepStrictEqual(results2,[2,4]);
});