Skip to content

Commit 2f1ca82

Browse files
committed
feat: rewrite project with typescript, use jest and rollup for bundling
BREAKING CHANGE: module format has been changed. Please ensure your environment or bundler continue to import the module correctly after version change
1 parent 0050025 commit 2f1ca82

File tree

13 files changed

+2621
-5086
lines changed

13 files changed

+2621
-5086
lines changed

.npmignore

Lines changed: 0 additions & 3 deletions
This file was deleted.

jest.config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/** @type {import('ts-jest').JestConfigWithTsJest} */
2+
module.exports = {
3+
preset: 'ts-jest',
4+
testEnvironment: 'node',
5+
};

package.json

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,40 +26,25 @@
2626
},
2727
"scripts": {
2828
"build": "rollup --config",
29-
"test": "yarn run test:coverage",
30-
"test:coverage": "nyc --reporter=lcovonly ava",
31-
"test:unit": "ava"
29+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
3230
},
3331
"main": "dist/index.js",
3432
"module": "dist/index.esm.js",
33+
"browser": "dist/index.umd.js",
34+
"typings": "dist/index.d.ts",
3535
"files": [
36-
"dist",
37-
"types/*.d.ts"
36+
"dist"
3837
],
3938
"dependencies": {},
4039
"devDependencies": {
41-
"@babel/core": "^7.1.2",
42-
"@babel/preset-env": "^7.1.0",
43-
"ava": "^1.0.0-rc.1",
44-
"codecov": "^3.7.1",
45-
"eslint": "^5.8.0",
46-
"esm": "^3.0.84",
47-
"live-server": "^1.2.0",
48-
"nyc": "^13.1.0",
49-
"rollup": "^0.66.6",
50-
"rollup-plugin-babel": "^4.0.3",
51-
"rollup-plugin-babel-minify": "^6.1.1",
52-
"rollup-plugin-commonjs": "^9.2.0",
53-
"rollup-plugin-node-resolve": "^3.4.0"
54-
},
55-
"typings": "types/index.d.ts",
56-
"ava": {
57-
"require": [
58-
"esm"
59-
],
60-
"files": [
61-
"test/**/*.spec.js"
62-
],
63-
"verbose": true
40+
"@rollup/plugin-terser": "^0.4.4",
41+
"@rollup/plugin-typescript": "^11.1.6",
42+
"@types/jest": "^29.5.12",
43+
"eslint": "^9.0.0",
44+
"jest": "^29.7.0",
45+
"rollup": "^4.14.1",
46+
"ts-jest": "^29.1.2",
47+
"tslib": "^2.6.2",
48+
"typescript": "^5.4.4"
6449
}
6550
}

rollup.config.js

Lines changed: 0 additions & 51 deletions
This file was deleted.

rollup.config.mjs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// @ts-check
2+
import typescript from '@rollup/plugin-typescript';
3+
import pkg from './package.json' assert { type: "json" };
4+
5+
/**
6+
* @type { import("rollup").OutputOptions }
7+
*/
8+
const commonOutput = {
9+
sourcemap: true,
10+
interop: "defaultOnly",
11+
}
12+
13+
/**
14+
* @type { import("rollup").RollupOptions }
15+
*/
16+
const config = {
17+
input: 'src/index.ts',
18+
output: [
19+
{
20+
...commonOutput,
21+
file: pkg.module,
22+
format: 'esm',
23+
},
24+
{
25+
...commonOutput,
26+
file: pkg.main,
27+
format: 'cjs',
28+
},
29+
{
30+
...commonOutput,
31+
file: pkg.browser,
32+
format: 'umd',
33+
name: 'timeMaker',
34+
},
35+
],
36+
plugins: [
37+
typescript({
38+
tsconfig: "tsconfig.build.json",
39+
sourceMap: false,
40+
}),
41+
],
42+
};
43+
44+
export default config;

src/index.js

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/index.spec.ts

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// @ts-check
2+
import T from './index';
3+
4+
const ZERO = 0;
5+
6+
// Usage testing
7+
it('should output correct value with its static method', () => {
8+
expect(ZERO).toBe( T.milliseconds(1) - (1));
9+
expect(ZERO).toBe( T.seconds(1) - (1000));
10+
expect(ZERO).toBe( T.minutes(1) - (60 * 1000));
11+
expect(ZERO).toBe( T.hours(1) - (60 * 60 * 1000));
12+
expect(ZERO).toBe( T.days(1) - (24 * 60 * 60 * 1000));
13+
expect(ZERO).toBe( T.weeks(1) - (7 * 24 * 60 * 60 * 1000));
14+
});
15+
16+
it('should output 0 when 0 given as param', () => {
17+
expect(ZERO).toBe( T.milliseconds(0) - ZERO);
18+
expect(ZERO).toBe( T.seconds(0) - ZERO);
19+
expect(ZERO).toBe( T.minutes(0) - ZERO);
20+
expect(ZERO).toBe( T.hours(0) - ZERO);
21+
expect(ZERO).toBe( T.days(0) - ZERO);
22+
expect(ZERO).toBe( T.weeks(0) - ZERO);
23+
});
24+
25+
it('should output 0 when nothing given as param', () => {
26+
expect(ZERO).toBe( T.milliseconds() - ZERO);
27+
expect(ZERO).toBe( T.seconds() - ZERO);
28+
expect(ZERO).toBe( T.minutes() - ZERO);
29+
expect(ZERO).toBe( T.hours() - ZERO);
30+
expect(ZERO).toBe( T.days() - ZERO);
31+
expect(ZERO).toBe( T.weeks() - ZERO);
32+
33+
expect(ZERO).toBe( T.milliseconds(undefined) - ZERO);
34+
expect(ZERO).toBe( T.seconds(undefined) - ZERO);
35+
expect(ZERO).toBe( T.minutes(undefined) - ZERO);
36+
expect(ZERO).toBe( T.hours(undefined) - ZERO);
37+
expect(ZERO).toBe( T.days(undefined) - ZERO);
38+
expect(ZERO).toBe( T.weeks(undefined) - ZERO);
39+
40+
expect(ZERO).toBe( T.milliseconds(null) - ZERO);
41+
expect(ZERO).toBe( T.seconds(null) - ZERO);
42+
expect(ZERO).toBe( T.minutes(null) - ZERO);
43+
expect(ZERO).toBe( T.hours(null) - ZERO);
44+
expect(ZERO).toBe( T.days(null) - ZERO);
45+
expect(ZERO).toBe( T.weeks(null) - ZERO);
46+
});
47+
48+
it('should work with chaining', () => {
49+
const OF_8_DAYS = (8 * (24 * 60 * 60 * 1000));
50+
51+
expect(ZERO).toBe( T.weeks(1).days(1) - OF_8_DAYS);
52+
});
53+
54+
it('should allow 0 or nothing during chaining', () => {
55+
const OF_8_DAYS = (8 * (24 * 60 * 60 * 1000));
56+
57+
expect(ZERO).toBe( T.weeks(1).days(0 ).days(1) - OF_8_DAYS);
58+
expect(ZERO).toBe( T.weeks(1).days( ).days(1) - OF_8_DAYS);
59+
expect(ZERO).toBe( T.weeks(1).days(null ).days(1) - OF_8_DAYS);
60+
expect(ZERO).toBe( T.weeks(1).days(undefined).days(1) - OF_8_DAYS);
61+
});
62+
63+
// Implementation Assertions
64+
it('static methods should produce instance of T', () => {
65+
expect(T.milliseconds(1)).toBeInstanceOf(T);
66+
expect(T.seconds(1)).toBeInstanceOf(T);
67+
expect(T.minutes(1)).toBeInstanceOf(T);
68+
expect(T.hours(1)).toBeInstanceOf(T);
69+
expect(T.days(1)).toBeInstanceOf(T);
70+
expect(T.weeks(1)).toBeInstanceOf(T);
71+
});
72+
73+
// Implementation Assertions
74+
it('instance methods should produce instance of T', () => {
75+
// The following produce type error
76+
// but should still be allowed in non-typescript environment
77+
78+
// @ts-ignore
79+
expect(new T().milliseconds(1)).toBeInstanceOf(T);
80+
// @ts-ignore
81+
expect(new T().seconds(1)).toBeInstanceOf(T);
82+
// @ts-ignore
83+
expect(new T().minutes(1)).toBeInstanceOf(T);
84+
// @ts-ignore
85+
expect(new T().hours(1)).toBeInstanceOf(T);
86+
// @ts-ignore
87+
expect(new T().days(1)).toBeInstanceOf(T);
88+
// @ts-ignore
89+
expect(new T().weeks(1)).toBeInstanceOf(T);
90+
});
91+
92+
// Type coercion
93+
it('stringification should produce number string', () => {
94+
expect(
95+
JSON.stringify({
96+
time: T.seconds(0),
97+
})
98+
).toBe(
99+
JSON.stringify({
100+
time: 0,
101+
})
102+
);
103+
104+
expect(
105+
JSON.stringify({
106+
time: T.seconds(0),
107+
})
108+
).not.toBe(
109+
JSON.stringify({
110+
time: '0',
111+
})
112+
);
113+
});

src/index.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
type T = number | Number | Time | null | undefined;
2+
type N = number;
3+
4+
type TimeReturn = Time & number;
5+
6+
class Time extends Number {
7+
public value = 0;
8+
9+
constructor(ms?: T) {
10+
super(ms);
11+
this.value = +(ms as number) || 0;
12+
}
13+
14+
valueOf() {
15+
return this.value as number;
16+
}
17+
18+
// Static methods
19+
static milliseconds(ms?: T) { return new Time(ms) as TimeReturn; }
20+
static seconds(s?: T) { return Time.milliseconds(s as N * 1000) as TimeReturn; }
21+
static minutes(m?: T) { return Time.seconds(m as N * 60) as TimeReturn; }
22+
static hours(h?: T) { return Time.minutes(h as N * 60) as TimeReturn; }
23+
static days(d?: T) { return Time.hours(d as N * 24) as TimeReturn; }
24+
static weeks(w?: T) { return Time.days(w as N * 7) as TimeReturn; }
25+
26+
// Instance methods
27+
milliseconds(ms?: T) {
28+
this.value += Time.milliseconds(ms).value;
29+
return this as unknown as TimeReturn;
30+
}
31+
seconds(s?: T) {
32+
this.value += Time.seconds(s).value;
33+
return this as unknown as TimeReturn;
34+
}
35+
minutes(m?: T) {
36+
this.value += Time.minutes(m).value;
37+
return this as unknown as TimeReturn;
38+
}
39+
hours(h?: T) {
40+
this.value += Time.hours(h).value;
41+
return this as unknown as TimeReturn;
42+
}
43+
days(d?: T) {
44+
this.value += Time.days(d).value;
45+
return this as unknown as TimeReturn;
46+
}
47+
weeks(w?: T) {
48+
this.value += Time.weeks(w).value;
49+
return this as unknown as TimeReturn;
50+
}
51+
}
52+
53+
export default Time as unknown as TimeReturn;

0 commit comments

Comments
 (0)