iterize
Version:
Use JavaScript Iterator, Easily
149 lines (132 loc) • 5.26 kB
text/typescript
import {expect} from 'chai';
import {range} from '../src';
import {iterResult, iterDone} from './utility';
function increaseTester(start: number, end: number, step: any, iter: any) {
let stepFunc = step;
if (typeof step === 'number') {
stepFunc = function (value: number) {
return step + value;
};
}
let cIter;
for (let i = start; i < end; i = stepFunc(cIter.value)) {
cIter = iter.next();
expect(cIter).to.deep.equal(iterResult(i));
}
cIter = iter.next();
expect(cIter).to.deep.equal(iterDone());
}
function decreaseTester(start: number, end: number, step: any, iter: any) {
let stepFunc = step;
if (typeof step === 'number') {
stepFunc = function (value: number) {
return step + value;
};
}
let cIter;
for (let i = start; i > end; i = stepFunc(cIter.value)) {
cIter = iter.next();
expect(cIter).to.deep.equal(iterResult(i));
}
cIter = iter.next();
expect(cIter).to.deep.equal(iterDone());
}
describe('Test Range API', () => {
describe('Default case: Step is number type', () => {
it('increase number', () => {
const start = 0;
const end = 5;
const increaseNumberOne = range(start, end, 1);
const increaseNumberTwo = range(start, end, 2);
const increaseNumberFour = range(start, end, 4);
increaseTester(start, end, 1, increaseNumberOne);
increaseTester(start, end, 2, increaseNumberTwo);
increaseTester(start, end, 4, increaseNumberFour);
});
it('decrease number ', () => {
const start = 5;
const end = 0;
const decreaseNumberOne = range(start, end, -1);
const decreaseNumberTwo = range(start, end, -2);
const decreaseNumberFour = range(start, end, -4);
decreaseTester(start, end, -1, decreaseNumberOne);
decreaseTester(start, end, -2, decreaseNumberTwo);
decreaseTester(start, end, -4, decreaseNumberFour);
});
});
describe('Default case: Step is function type', () => {
it('increase number', () => {
const start = 0;
const end = 5;
const increaseNumberOne = range(start, end, (x: number) => x + 1);
const increaseNumberTwo = range(start, end, (x: number) => x + 2);
const increaseNumberFour = range(start, end, (x: number) => x + 4);
increaseTester(start, end, (x: number) => x + 1, increaseNumberOne);
increaseTester(start, end, (x: number) => x + 2, increaseNumberTwo);
increaseTester(
start,
end,
(x: number) => x + 4,
increaseNumberFour
);
});
it('decrease number', () => {
const start = 5;
const end = 0;
const decreaseNumberOne = range(start, end, (x: number) => x - 1);
const decreaseNumberTwo = range(start, end, (x: number) => x - 2);
const decreaseNumberFour = range(start, end, (x: number) => x - 4);
decreaseTester(start, end, (x: number) => x - 1, decreaseNumberOne);
decreaseTester(start, end, (x: number) => x - 2, decreaseNumberTwo);
decreaseTester(
start,
end,
(x: number) => x - 4,
decreaseNumberFour
);
});
it('square x^2', () => {
const iter = range(2, 64, (x: number) => x * x);
expect(iter.next()).to.deep.equal(iterResult(2));
expect(iter.next()).to.deep.equal(iterResult(4));
expect(iter.next()).to.deep.equal(iterResult(16));
expect(iter.next()).to.deep.equal(iterDone());
});
});
describe('Default case: overloading', () => {
it('one parameter', () => {
const increaseNumberOne = range(5);
increaseTester(0, 5, 1, increaseNumberOne);
});
it('two parameter', () => {
const increaseNumberOne = range(0, 5);
const decreaseNumberOne = range(5, 0);
increaseTester(0, 5, 1, increaseNumberOne);
decreaseTester(5, 0, -1, decreaseNumberOne);
});
});
describe('Default case: Compatibility with language specifications', () => {
it('for - of', () => {
let number = 0;
for (let n of range(0, 2, 1)) {
expect(n).equal(number++);
}
expect(number).equal(2);
});
it('[...iterator]', () => {
let numbers = [...range(0, 2, 1)];
expect(numbers).to.deep.equal([0, 1]);
});
});
describe('Edge case', () => {
it('illegal input parameter', () => {
expect(() => range(<any>'a', 2, 3).next()).to.throw();
expect(() => range(1, <any>'b', 3).next()).to.throw();
expect(() => range(1, 2, <any>'1').next()).to.throw();
});
it('start === end', () => {
expect(() => range(1, 1).next()).to.throw();
expect(() => range(1, 1, 3).next()).to.throw();
});
});
});