SevdanurGenc's picture
Upload 300 files
9438a57 verified
Raw History Blame Contribute Delete
2.29 kB
const { RateLimiter } = require('./solution');
function clock(start = 0) {
let t = start;
return { now: () => t, advance: (ms) => { t += ms; } };
}
describe('RateLimiter', () => {
test('validates constructor arguments', () => {
expect(() => new RateLimiter({ capacity: 0, refillPerSec: 1 })).toThrow(RangeError);
expect(() => new RateLimiter({ capacity: 1, refillPerSec: -1 })).toThrow(RangeError);
});
test('uses the system clock by default', () => {
const rl = new RateLimiter({ capacity: 1, refillPerSec: 1 });
expect(rl.tryRemove()).toBe(true);
});
test('starts full and spends tokens', () => {
const c = clock();
const rl = new RateLimiter({ capacity: 2, refillPerSec: 1, now: c.now });
expect(rl.tryRemove()).toBe(true);
expect(rl.tryRemove()).toBe(true);
expect(rl.tryRemove()).toBe(false);
});
test('can spend exactly all remaining tokens', () => {
const c = clock();
const rl = new RateLimiter({ capacity: 3, refillPerSec: 1, now: c.now });
expect(rl.tryRemove(3)).toBe(true);
expect(rl.tokens).toBe(0);
});
test('failed request spends nothing', () => {
const c = clock();
const rl = new RateLimiter({ capacity: 2, refillPerSec: 1, now: c.now });
expect(rl.tryRemove(5)).toBe(false);
expect(rl.tokens).toBe(2);
});
test('refills over time but never above capacity', () => {
const c = clock();
const rl = new RateLimiter({ capacity: 2, refillPerSec: 1, now: c.now });
rl.tryRemove(2);
c.advance(1000);
expect(rl.tryRemove()).toBe(true);
expect(rl.tryRemove()).toBe(false);
c.advance(10000);
rl.waitTime();
expect(rl.tokens).toBe(2);
});
test('rejects non-positive cost', () => {
const rl = new RateLimiter({ capacity: 1, refillPerSec: 1, now: clock().now });
expect(() => rl.tryRemove(0)).toThrow(RangeError);
});
test('waitTime rounds up and handles zero refill', () => {
const c = clock();
const rl = new RateLimiter({ capacity: 1, refillPerSec: 3, now: c.now });
expect(rl.waitTime()).toBe(0);
rl.tryRemove();
expect(rl.waitTime()).toBe(334);
const frozen = new RateLimiter({ capacity: 1, refillPerSec: 0, now: c.now });
frozen.tryRemove();
expect(frozen.waitTime()).toBe(Infinity);
});
});