add Time test
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
"module": "./dist/timi-web.mjs",
|
"module": "./dist/timi-web.mjs",
|
||||||
"style": "./dist/timi-web.css",
|
"style": "./dist/timi-web.css",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "0.0.10",
|
"version": "0.0.12",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div
|
<div
|
||||||
class="tui-markdown-view selectable break-all line-numbers"
|
class="tui-markdown-view selectable break-all line-numbers"
|
||||||
v-html="markdownHTML"
|
v-html="markdownHTML"
|
||||||
:data-max-height="maxHeight"
|
:style="{ '--data-max-height': maxHeight }"
|
||||||
></div>
|
></div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|||||||
@@ -260,9 +260,9 @@
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
max-height: var(data-max-height);
|
max-height: var(--data-max-height);
|
||||||
transition: max-height .5s var(--tui-bezier);
|
transition: max-height .5s var(--tui-bezier);
|
||||||
font-family: var(--td-font-family);
|
font-family: var(--td-font);
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@
|
|||||||
color: #333;
|
color: #333;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
text-shadow: none !important;
|
text-shadow: none !important;
|
||||||
font-family: var(--td-font-family);
|
font-family: var(--td-font);
|
||||||
|
|
||||||
.line-numbers-rows {
|
.line-numbers-rows {
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|||||||
67
src/utils/Time.test.ts
Normal file
67
src/utils/Time.test.ts
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import Time from "./Time";
|
||||||
|
|
||||||
|
describe("Time", () => {
|
||||||
|
describe("between", () => {
|
||||||
|
it("should return time segments between begin and end", () => {
|
||||||
|
const begin = new Date("2026-01-01T00:00:00.000Z");
|
||||||
|
const end = new Date("2027-01-03T04:05:06.789Z");
|
||||||
|
const result = Time.between(begin, end);
|
||||||
|
expect(result.y).toBe(1);
|
||||||
|
expect(result.d).toBe(2);
|
||||||
|
expect(result.h).toBe(4);
|
||||||
|
expect(result.m).toBe(5);
|
||||||
|
expect(result.s).toBe(6);
|
||||||
|
expect(result.ms).toBeGreaterThanOrEqual(788);
|
||||||
|
expect(result.ms).toBeLessThanOrEqual(789);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("duration", () => {
|
||||||
|
it("should return empty string when totalMs is falsy", () => {
|
||||||
|
expect(Time.duration()).toBe("");
|
||||||
|
expect(Time.duration(0)).toBe("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should format duration without milliseconds by default", () => {
|
||||||
|
const value = Time.D * 366 + Time.H * 2 + Time.M * 3 + Time.S * 4 + 567;
|
||||||
|
expect(Time.duration(value)).toBe("1 年 1 日 2 小时 3 分钟 4 秒");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should include milliseconds when ms flag is true", () => {
|
||||||
|
const value = Time.M + 250;
|
||||||
|
expect(Time.duration(value, true)).toBe("1 分钟 250 毫秒");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("toMediaTime", () => {
|
||||||
|
it("should format seconds to media time", () => {
|
||||||
|
expect(Time.toMediaTime(59.9)).toBe("00:59");
|
||||||
|
expect(Time.toMediaTime(61)).toBe("01:01");
|
||||||
|
expect(Time.toMediaTime(3661)).toBe("1:01:01");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("parseToMS", () => {
|
||||||
|
it("should parse value without unit as milliseconds", () => {
|
||||||
|
expect(Time.parseToMS("10")).toBe(10);
|
||||||
|
expect(Time.parseToMS("10ms")).toBe(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse supported units", () => {
|
||||||
|
expect(Time.parseToMS("10s")).toBe(10 * Time.S);
|
||||||
|
expect(Time.parseToMS("10m")).toBe(10 * Time.M);
|
||||||
|
expect(Time.parseToMS("10h")).toBe(10 * Time.H);
|
||||||
|
expect(Time.parseToMS("10d")).toBe(10 * Time.D);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse decimal with spaces and uppercase unit", () => {
|
||||||
|
expect(Time.parseToMS(" 10.5 D ")).toBe(Math.round(10.5 * Time.D));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw for empty or invalid format", () => {
|
||||||
|
expect(() => Time.parseToMS("")).toThrowError("not found timeStr");
|
||||||
|
expect(() => Time.parseToMS("abc")).toThrowError("invalid format: abc");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -71,26 +71,6 @@ export default class Time {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 将毫秒值转换为可读的时间字符串
|
|
||||||
*
|
|
||||||
* @param ms 毫秒值
|
|
||||||
* @return 时间字符串,如 "10 天"、"5 小时"、"30 分钟"、"15 秒"、"500 毫秒"
|
|
||||||
*/
|
|
||||||
public static toString(ms: number): string {
|
|
||||||
if (Time.D <= ms) {
|
|
||||||
return `${Math.floor(ms / Time.D)} 天`;
|
|
||||||
} else if (Time.H <= ms) {
|
|
||||||
return `${Math.floor(ms / Time.H)} 小时`;
|
|
||||||
} else if (Time.M <= ms) {
|
|
||||||
return `${Math.floor(ms / Time.M)} 分钟`;
|
|
||||||
} else if (Time.S <= ms) {
|
|
||||||
return `${Math.floor(ms / Time.S)} 秒`;
|
|
||||||
} else {
|
|
||||||
return `${Math.floor(ms)} 毫秒`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static between(begin: Date, end?: Date) : any {
|
public static between(begin: Date, end?: Date) : any {
|
||||||
if (!end) {
|
if (!end) {
|
||||||
end = new Date();
|
end = new Date();
|
||||||
@@ -106,18 +86,36 @@ export default class Time {
|
|||||||
return { l, y, d, h, m, s, ms };
|
return { l, y, d, h, m, s, ms };
|
||||||
}
|
}
|
||||||
|
|
||||||
public static duration(begin?: number, ms?: boolean): string {
|
public static duration(totalMs?: number, ms?: boolean): string {
|
||||||
if (!begin) {
|
if (!totalMs) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
const r = Time.between(new Date(begin), new Date());
|
let remain = Math.floor(totalMs);
|
||||||
|
const yearMs = Time.D * 365;
|
||||||
|
const dayMs = Time.D;
|
||||||
|
const hourMs = Time.H;
|
||||||
|
const minuteMs = Time.M;
|
||||||
|
const secondMs = Time.S;
|
||||||
|
|
||||||
|
const years = Math.floor(remain / yearMs);
|
||||||
|
remain %= yearMs;
|
||||||
|
const days = Math.floor(remain / dayMs);
|
||||||
|
remain %= dayMs;
|
||||||
|
const hours = Math.floor(remain / hourMs);
|
||||||
|
remain %= hourMs;
|
||||||
|
const minutes = Math.floor(remain / minuteMs);
|
||||||
|
remain %= minuteMs;
|
||||||
|
const seconds = Math.floor(remain / secondMs);
|
||||||
|
remain %= secondMs;
|
||||||
|
|
||||||
|
const milliseconds = remain;
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
Toolkit.doWhere(0 < r.y, () => parts.push(`${r.y} 年`));
|
Toolkit.doWhere(0 < years, () => parts.push(`${years} 年`));
|
||||||
Toolkit.doWhere(0 < r.d, () => parts.push(`${r.d} 天`));
|
Toolkit.doWhere(0 < days, () => parts.push(`${days} 日`));
|
||||||
Toolkit.doWhere(0 < r.h, () => parts.push(`${r.h} 小时`));
|
Toolkit.doWhere(0 < hours, () => parts.push(`${hours} 小时`));
|
||||||
Toolkit.doWhere(0 < r.m, () => parts.push(`${r.m} 分钟`));
|
Toolkit.doWhere(0 < minutes, () => parts.push(`${minutes} 分钟`));
|
||||||
Toolkit.doWhere(0 < r.s, () => parts.push(`${r.s} 秒`));
|
Toolkit.doWhere(0 < seconds, () => parts.push(`${seconds} 秒`));
|
||||||
Toolkit.doWhere(!!ms && 0 < r.ms, () => parts.push(`${r.ms} 毫秒`));
|
Toolkit.doWhere(!!ms && 0 < milliseconds, () => parts.push(`${milliseconds} 毫秒`));
|
||||||
return parts.join(" ");
|
return parts.join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user