Skip to content

Commit

Permalink
+ timeLeft property
Browse files Browse the repository at this point in the history
= `restartOnly` methods supports updating timeout and instant first run
= `startOnly` methods supports updating instant first run
! JSDoc is invalid about return types
  • Loading branch information
dzek69 committed Mar 31, 2024
1 parent c217214 commit 28c4f2c
Show file tree
Hide file tree
Showing 8 changed files with 498 additions and 45 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
The format is based on [EZEZ Changelog](https://ezez.dev/changelog/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [UNRELEASED]
(nothing yet)
### Added
- `timeLeft` property
### Changed
- `restartOnly` methods supports updating timeout and instant first run
- `startOnly` methods supports updating instant first run
### Fixed
- JSDoc is invalid about return types

## [5.0.0] - 2023-05-07
### Added
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ This library wraps JavaScript timers (timeout and interval) in a class to provid

- 🌟 Extra features - stop repeating yourself
- 🛠 First class TypeScript support - 100% type safe and intellisense friendly
- 📦 No dependencies - use it anywhere
- 📦 No dependencies - it's small and can be used anywhere
- 🌎 Universal - exposes both ESM modules and CommonJS
- 🛡️ Secure - fully tested and used in production
- 🛡️ Safe - fully tested and used in production

## Quick example

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "oop-timers",
"version": "5.0.0",
"version": "5.0.0+",
"repository": "[email protected]:dzek69/oop-timers.git",
"author": "Jacek Nowacki",
"license": "MIT",
Expand Down
202 changes: 202 additions & 0 deletions src/Interval.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,4 +419,206 @@ describe("Interval", () => {
callback.__spy.calls.length.must.equal(1);
interval.stop();
});

it("allows to change interval while restarting-only the timer", async () => {
const callback = spy();
const interval = new Interval(callback, 100);
interval.start();

await wait(50);
callback.__spy.calls.must.have.length(0);
await wait(50);
callback.__spy.calls.must.have.length(1);
const restarted = interval.restartOnly(200);
restarted.must.be.true();

callback.__spy.reset();

await wait(150);
callback.__spy.calls.must.have.length(0);
await wait(50);
callback.__spy.calls.must.have.length(1);

interval.stop();
});

it("allows to change instant first run when restarting-only", async () => {
const callback = spy();
const interval = new Interval(callback, 100);
interval.start();
await wait(10);

callback.__spy.calls.must.have.length(0);
interval.restartOnly(undefined, true);
callback.__spy.calls.must.have.length(1);
interval.restartOnly(undefined, true);
callback.__spy.calls.must.have.length(2);
interval.restartOnly(undefined, false);
callback.__spy.calls.must.have.length(2);
interval.restartOnly(undefined, false);
callback.__spy.calls.must.have.length(2);

interval.stop();
});

it("allows to change instant first run when starting-only", async () => {
const callback = spy();
const interval = new Interval(callback, 100, false, false);
callback.__spy.calls.must.have.length(0);

interval.startOnly(true);
callback.__spy.calls.must.have.length(1);

interval.stop();
interval.startOnly(false);
callback.__spy.calls.must.have.length(1);

interval.stop();
interval.startOnly(true);
callback.__spy.calls.must.have.length(2);

interval.startOnly(false);
interval.stop();
interval.start();
callback.__spy.calls.must.have.length(2);

interval.stop();
});

describe("has a function to change time", () => {
it("that works when timer is started ", async () => {
const callback = spy();
const interval = new Interval(callback, 100);
interval.start();
interval.changeTime(150);

await wait(100);
callback.__spy.calls.must.have.length(0);

await wait(50);
callback.__spy.calls.must.have.length(1);

await wait(150);
callback.__spy.calls.must.have.length(2);

interval.stop();
});

it("that restarts the timer to change time", async () => {
const callback = spy();
const interval = new Interval(callback, 100);
interval.start();

interval.changeTime(101);
await wait(50);
callback.__spy.calls.must.have.length(0);
interval.changeTime(100);
await wait(50);
callback.__spy.calls.must.have.length(0);
interval.changeTime(101);
await wait(50);
callback.__spy.calls.must.have.length(0);
interval.changeTime(100);
await wait(50);
callback.__spy.calls.must.have.length(0);

await wait(100);
callback.__spy.calls.must.have.length(1);

interval.stop();
});

it("that works when timer is stopped", async () => {
const callback = spy();
const interval = new Interval(callback, 100);
interval.stop();
interval.changeTime(150);
interval.start();

await wait(100);
callback.__spy.calls.must.have.length(0);

await wait(50);
callback.__spy.calls.must.have.length(1);

interval.stop();
});

it("does not start the time if stopped", async () => {
const callback = spy();
const interval = new Interval(callback, 100);
interval.stop();
interval.changeTime(150);

interval.started.must.be.false();
await wait(200);
callback.__spy.calls.must.have.length(0);

interval.stop();
});

it("does not restart the timer if the same exact time is given", async () => {
const callback = spy();
const interval = new Interval(callback, 100);
interval.start();

interval.changeTime(100);
await wait(50);
callback.__spy.calls.must.have.length(0);

interval.changeTime(100);
await wait(50);
callback.__spy.calls.must.have.length(1);

interval.stop();
});
});

describe("has timeLeft property", () => {
it("that returns time to next invocation", async () => {
let resolve: ((v: unknown) => void) = () => {};
const p = new Promise((r) => {
resolve = r;
});

const callback = spy(async () => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
const i = interval;

await wait(25);
const time3 = i.timeLeft;
i.timeLeft.must.be.between(0, 75);

await wait(25);
const time4 = i.timeLeft;
i.timeLeft.must.be.between(0, 50);

time4.must.be.lt(time3);

i.stop();
resolve(null);
});

const interval = new Interval(callback, 100);
interval.start();

await wait(25);
const time1 = interval.timeLeft;
interval.timeLeft.must.be.between(0, 75);

await wait(25);
const time2 = interval.timeLeft;
interval.timeLeft.must.be.between(0, 50);

time2.must.be.lt(time1);

await p;
});

it("that returns zero if timer is not started", async () => {
const callback = spy();
const interval = new Interval(callback, 100);
interval.timeLeft.must.equal(0);
});
});
});
Loading

0 comments on commit 28c4f2c

Please sign in to comment.