estela 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/statusline.js +34 -21
- package/package.json +3 -1
- package/dist/billing/amortize.d.ts.map +0 -1
- package/dist/billing/amortize.js.map +0 -1
- package/dist/billing/amortize.test.d.ts +0 -2
- package/dist/billing/amortize.test.d.ts.map +0 -1
- package/dist/billing/amortize.test.js +0 -121
- package/dist/billing/amortize.test.js.map +0 -1
- package/dist/billing/assign.d.ts.map +0 -1
- package/dist/billing/assign.js.map +0 -1
- package/dist/billing/assign.test.d.ts +0 -2
- package/dist/billing/assign.test.d.ts.map +0 -1
- package/dist/billing/assign.test.js +0 -153
- package/dist/billing/assign.test.js.map +0 -1
- package/dist/billing/format.test.d.ts +0 -2
- package/dist/billing/format.test.d.ts.map +0 -1
- package/dist/billing/format.test.js +0 -110
- package/dist/billing/format.test.js.map +0 -1
- package/dist/billing/invoice.d.ts.map +0 -1
- package/dist/billing/invoice.js.map +0 -1
- package/dist/billing/invoice.test.d.ts +0 -2
- package/dist/billing/invoice.test.d.ts.map +0 -1
- package/dist/billing/invoice.test.js +0 -200
- package/dist/billing/invoice.test.js.map +0 -1
- package/dist/billing/localize.d.ts.map +0 -1
- package/dist/billing/localize.js.map +0 -1
- package/dist/billing/localize.test.d.ts +0 -2
- package/dist/billing/localize.test.d.ts.map +0 -1
- package/dist/billing/localize.test.js +0 -144
- package/dist/billing/localize.test.js.map +0 -1
- package/dist/billing/sessionize.d.ts.map +0 -1
- package/dist/billing/sessionize.js.map +0 -1
- package/dist/billing/sessionize.test.d.ts +0 -2
- package/dist/billing/sessionize.test.d.ts.map +0 -1
- package/dist/billing/sessionize.test.js +0 -187
- package/dist/billing/sessionize.test.js.map +0 -1
- package/dist/billing.d.ts.map +0 -1
- package/dist/billing.js.map +0 -1
- package/dist/bin.d.ts.map +0 -1
- package/dist/bin.js.map +0 -1
- package/dist/cli-badge.test.d.ts +0 -2
- package/dist/cli-badge.test.d.ts.map +0 -1
- package/dist/cli-badge.test.js +0 -118
- package/dist/cli-badge.test.js.map +0 -1
- package/dist/cli-idioma.test.d.ts +0 -2
- package/dist/cli-idioma.test.d.ts.map +0 -1
- package/dist/cli-idioma.test.js +0 -190
- package/dist/cli-idioma.test.js.map +0 -1
- package/dist/cli-import-recover.test.d.ts +0 -2
- package/dist/cli-import-recover.test.d.ts.map +0 -1
- package/dist/cli-import-recover.test.js +0 -191
- package/dist/cli-import-recover.test.js.map +0 -1
- package/dist/cli-quota.test.d.ts +0 -2
- package/dist/cli-quota.test.d.ts.map +0 -1
- package/dist/cli-quota.test.js +0 -281
- package/dist/cli-quota.test.js.map +0 -1
- package/dist/cli-statusline.test.d.ts +0 -2
- package/dist/cli-statusline.test.d.ts.map +0 -1
- package/dist/cli-statusline.test.js +0 -333
- package/dist/cli-statusline.test.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/cloud/auth.d.ts.map +0 -1
- package/dist/cloud/auth.js.map +0 -1
- package/dist/cloud/client.d.ts.map +0 -1
- package/dist/cloud/client.js.map +0 -1
- package/dist/cloud/errors.test.d.ts +0 -2
- package/dist/cloud/errors.test.d.ts.map +0 -1
- package/dist/cloud/errors.test.js +0 -34
- package/dist/cloud/errors.test.js.map +0 -1
- package/dist/db/schema.d.ts.map +0 -1
- package/dist/db/schema.js.map +0 -1
- package/dist/db/schema.test.d.ts +0 -2
- package/dist/db/schema.test.d.ts.map +0 -1
- package/dist/db/schema.test.js +0 -825
- package/dist/db/schema.test.js.map +0 -1
- package/dist/db/store.d.ts.map +0 -1
- package/dist/db/store.js.map +0 -1
- package/dist/demo.d.ts.map +0 -1
- package/dist/demo.js.map +0 -1
- package/dist/demo.test.d.ts +0 -2
- package/dist/demo.test.d.ts.map +0 -1
- package/dist/demo.test.js +0 -148
- package/dist/demo.test.js.map +0 -1
- package/dist/doctor.d.ts.map +0 -1
- package/dist/doctor.js.map +0 -1
- package/dist/doctor.test.d.ts +0 -2
- package/dist/doctor.test.d.ts.map +0 -1
- package/dist/doctor.test.js +0 -167
- package/dist/doctor.test.js.map +0 -1
- package/dist/export/badge.d.ts.map +0 -1
- package/dist/export/badge.js.map +0 -1
- package/dist/export/badge.test.d.ts +0 -2
- package/dist/export/badge.test.d.ts.map +0 -1
- package/dist/export/badge.test.js +0 -32
- package/dist/export/badge.test.js.map +0 -1
- package/dist/export/clockify.d.ts.map +0 -1
- package/dist/export/clockify.js.map +0 -1
- package/dist/export/clockify.test.d.ts +0 -2
- package/dist/export/clockify.test.d.ts.map +0 -1
- package/dist/export/clockify.test.js +0 -51
- package/dist/export/clockify.test.js.map +0 -1
- package/dist/export/csv.d.ts.map +0 -1
- package/dist/export/csv.js.map +0 -1
- package/dist/export/dates.d.ts.map +0 -1
- package/dist/export/dates.js.map +0 -1
- package/dist/export/idioma.test.d.ts +0 -2
- package/dist/export/idioma.test.d.ts.map +0 -1
- package/dist/export/idioma.test.js +0 -255
- package/dist/export/idioma.test.js.map +0 -1
- package/dist/export/invoice-pdf.d.ts.map +0 -1
- package/dist/export/invoice-pdf.js.map +0 -1
- package/dist/export/panel.d.ts.map +0 -1
- package/dist/export/panel.js.map +0 -1
- package/dist/export/panel.test.d.ts +0 -2
- package/dist/export/panel.test.d.ts.map +0 -1
- package/dist/export/panel.test.js +0 -386
- package/dist/export/panel.test.js.map +0 -1
- package/dist/export/pdf.d.ts.map +0 -1
- package/dist/export/pdf.js.map +0 -1
- package/dist/export/pdf.test.d.ts +0 -2
- package/dist/export/pdf.test.d.ts.map +0 -1
- package/dist/export/pdf.test.js +0 -172
- package/dist/export/pdf.test.js.map +0 -1
- package/dist/export/pixelfont.d.ts.map +0 -1
- package/dist/export/pixelfont.js.map +0 -1
- package/dist/export/png.d.ts.map +0 -1
- package/dist/export/png.js.map +0 -1
- package/dist/export/receipt.d.ts.map +0 -1
- package/dist/export/receipt.js.map +0 -1
- package/dist/export/receipt.test.d.ts +0 -2
- package/dist/export/receipt.test.d.ts.map +0 -1
- package/dist/export/receipt.test.js +0 -207
- package/dist/export/receipt.test.js.map +0 -1
- package/dist/export/share.d.ts.map +0 -1
- package/dist/export/share.js.map +0 -1
- package/dist/export/share.test.d.ts +0 -2
- package/dist/export/share.test.d.ts.map +0 -1
- package/dist/export/share.test.js +0 -116
- package/dist/export/share.test.js.map +0 -1
- package/dist/i18n/en.d.ts.map +0 -1
- package/dist/i18n/en.js.map +0 -1
- package/dist/i18n/i18n.test.d.ts +0 -2
- package/dist/i18n/i18n.test.d.ts.map +0 -1
- package/dist/i18n/i18n.test.js +0 -226
- package/dist/i18n/i18n.test.js.map +0 -1
- package/dist/i18n/index.d.ts.map +0 -1
- package/dist/i18n/index.js.map +0 -1
- package/dist/i18n/labels.d.ts.map +0 -1
- package/dist/i18n/labels.js.map +0 -1
- package/dist/metrics/index.d.ts.map +0 -1
- package/dist/metrics/index.js.map +0 -1
- package/dist/metrics/metrics.test.d.ts +0 -2
- package/dist/metrics/metrics.test.d.ts.map +0 -1
- package/dist/metrics/metrics.test.js +0 -162
- package/dist/metrics/metrics.test.js.map +0 -1
- package/dist/metrics/people.d.ts.map +0 -1
- package/dist/metrics/people.js.map +0 -1
- package/dist/metrics/people.test.d.ts +0 -2
- package/dist/metrics/people.test.d.ts.map +0 -1
- package/dist/metrics/people.test.js +0 -92
- package/dist/metrics/people.test.js.map +0 -1
- package/dist/metrics/quota.d.ts.map +0 -1
- package/dist/metrics/quota.js.map +0 -1
- package/dist/metrics/quota.test.d.ts +0 -2
- package/dist/metrics/quota.test.d.ts.map +0 -1
- package/dist/metrics/quota.test.js +0 -325
- package/dist/metrics/quota.test.js.map +0 -1
- package/dist/metrics/team.d.ts.map +0 -1
- package/dist/metrics/team.js.map +0 -1
- package/dist/metrics/team.test.d.ts +0 -2
- package/dist/metrics/team.test.d.ts.map +0 -1
- package/dist/metrics/team.test.js +0 -90
- package/dist/metrics/team.test.js.map +0 -1
- package/dist/node-version.d.ts.map +0 -1
- package/dist/node-version.js.map +0 -1
- package/dist/node-version.test.d.ts +0 -2
- package/dist/node-version.test.d.ts.map +0 -1
- package/dist/node-version.test.js +0 -53
- package/dist/node-version.test.js.map +0 -1
- package/dist/paths.d.ts.map +0 -1
- package/dist/paths.js.map +0 -1
- package/dist/paths.test.d.ts +0 -2
- package/dist/paths.test.d.ts.map +0 -1
- package/dist/paths.test.js +0 -32
- package/dist/paths.test.js.map +0 -1
- package/dist/pricing/catalog.d.ts.map +0 -1
- package/dist/pricing/catalog.js.map +0 -1
- package/dist/pricing/cost.d.ts.map +0 -1
- package/dist/pricing/cost.js.map +0 -1
- package/dist/pricing/cost.test.d.ts +0 -2
- package/dist/pricing/cost.test.d.ts.map +0 -1
- package/dist/pricing/cost.test.js +0 -100
- package/dist/pricing/cost.test.js.map +0 -1
- package/dist/project-of.d.ts.map +0 -1
- package/dist/project-of.js.map +0 -1
- package/dist/project-of.test.d.ts +0 -2
- package/dist/project-of.test.d.ts.map +0 -1
- package/dist/project-of.test.js +0 -203
- package/dist/project-of.test.js.map +0 -1
- package/dist/publish.d.ts.map +0 -1
- package/dist/publish.js.map +0 -1
- package/dist/publish.test.d.ts +0 -2
- package/dist/publish.test.d.ts.map +0 -1
- package/dist/publish.test.js +0 -113
- package/dist/publish.test.js.map +0 -1
- package/dist/quota.d.ts.map +0 -1
- package/dist/quota.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/server.test.d.ts +0 -2
- package/dist/server.test.d.ts.map +0 -1
- package/dist/server.test.js +0 -402
- package/dist/server.test.js.map +0 -1
- package/dist/setup.d.ts.map +0 -1
- package/dist/setup.js.map +0 -1
- package/dist/setup.test.d.ts +0 -2
- package/dist/setup.test.d.ts.map +0 -1
- package/dist/setup.test.js +0 -144
- package/dist/setup.test.js.map +0 -1
- package/dist/statusline-cache.d.ts.map +0 -1
- package/dist/statusline-cache.js.map +0 -1
- package/dist/statusline-install.d.ts.map +0 -1
- package/dist/statusline-install.js.map +0 -1
- package/dist/statusline-run.d.ts.map +0 -1
- package/dist/statusline-run.js.map +0 -1
- package/dist/statusline.d.ts.map +0 -1
- package/dist/statusline.js.map +0 -1
- package/dist/statusline.test.d.ts +0 -2
- package/dist/statusline.test.d.ts.map +0 -1
- package/dist/statusline.test.js +0 -197
- package/dist/statusline.test.js.map +0 -1
- package/dist/sync/team.d.ts.map +0 -1
- package/dist/sync/team.js.map +0 -1
- package/dist/sync/team.test.d.ts +0 -2
- package/dist/sync/team.test.d.ts.map +0 -1
- package/dist/sync/team.test.js +0 -102
- package/dist/sync/team.test.js.map +0 -1
- package/dist/sync.d.ts.map +0 -1
- package/dist/sync.js.map +0 -1
- package/dist/sync.test.d.ts +0 -2
- package/dist/sync.test.d.ts.map +0 -1
- package/dist/sync.test.js +0 -151
- package/dist/sync.test.js.map +0 -1
- package/dist/team.d.ts.map +0 -1
- package/dist/team.js.map +0 -1
- package/dist/team.test.d.ts +0 -2
- package/dist/team.test.d.ts.map +0 -1
- package/dist/team.test.js +0 -163
- package/dist/team.test.js.map +0 -1
- package/dist/updateCheck.d.ts.map +0 -1
- package/dist/updateCheck.js.map +0 -1
- package/dist/updateCheck.test.d.ts +0 -2
- package/dist/updateCheck.test.d.ts.map +0 -1
- package/dist/updateCheck.test.js +0 -27
- package/dist/updateCheck.test.js.map +0 -1
- package/dist/watchers/agents.d.ts.map +0 -1
- package/dist/watchers/agents.js.map +0 -1
- package/dist/watchers/agents.test.d.ts +0 -2
- package/dist/watchers/agents.test.d.ts.map +0 -1
- package/dist/watchers/agents.test.js +0 -96
- package/dist/watchers/agents.test.js.map +0 -1
- package/dist/watchers/claude.d.ts.map +0 -1
- package/dist/watchers/claude.js.map +0 -1
- package/dist/watchers/claude.test.d.ts +0 -2
- package/dist/watchers/claude.test.d.ts.map +0 -1
- package/dist/watchers/claude.test.js +0 -180
- package/dist/watchers/claude.test.js.map +0 -1
- package/dist/watchers/codex.d.ts.map +0 -1
- package/dist/watchers/codex.js.map +0 -1
- package/dist/watchers/codex.test.d.ts +0 -2
- package/dist/watchers/codex.test.d.ts.map +0 -1
- package/dist/watchers/codex.test.js +0 -207
- package/dist/watchers/codex.test.js.map +0 -1
- package/dist/watchers/copilot.d.ts.map +0 -1
- package/dist/watchers/copilot.js.map +0 -1
- package/dist/watchers/copilot.test.d.ts +0 -2
- package/dist/watchers/copilot.test.d.ts.map +0 -1
- package/dist/watchers/copilot.test.js +0 -98
- package/dist/watchers/copilot.test.js.map +0 -1
- package/dist/watchers/git.d.ts.map +0 -1
- package/dist/watchers/git.js.map +0 -1
- package/dist/watchers/git.test.d.ts +0 -2
- package/dist/watchers/git.test.d.ts.map +0 -1
- package/dist/watchers/git.test.js +0 -75
- package/dist/watchers/git.test.js.map +0 -1
- package/dist/watchers/identity.d.ts.map +0 -1
- package/dist/watchers/identity.js.map +0 -1
- package/dist/watchers/identity.test.d.ts +0 -2
- package/dist/watchers/identity.test.d.ts.map +0 -1
- package/dist/watchers/identity.test.js +0 -48
- package/dist/watchers/identity.test.js.map +0 -1
- package/dist/web-ui.test.d.ts +0 -2
- package/dist/web-ui.test.d.ts.map +0 -1
- package/dist/web-ui.test.js +0 -414
- package/dist/web-ui.test.js.map +0 -1
- package/dist/workitems.test.d.ts +0 -2
- package/dist/workitems.test.d.ts.map +0 -1
- package/dist/workitems.test.js +0 -59
- package/dist/workitems.test.js.map +0 -1
package/dist/watchers/git.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/watchers/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git.test.d.ts","sourceRoot":"","sources":["../../src/watchers/git.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
7
|
-
const node_child_process_1 = require("node:child_process");
|
|
8
|
-
const node_fs_1 = require("node:fs");
|
|
9
|
-
const node_os_1 = require("node:os");
|
|
10
|
-
const node_path_1 = require("node:path");
|
|
11
|
-
const node_test_1 = require("node:test");
|
|
12
|
-
const paths_js_1 = require("../paths.js");
|
|
13
|
-
const git_js_1 = require("./git.js");
|
|
14
|
-
/** Repo de verdad: lo que falla aquí falla contra git real, no contra un mock. */
|
|
15
|
-
function makeRepo() {
|
|
16
|
-
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "estela-git-"));
|
|
17
|
-
const git = (...args) => (0, node_child_process_1.execFileSync)("git", args, { cwd: dir, stdio: "pipe", env: {
|
|
18
|
-
...process.env,
|
|
19
|
-
GIT_AUTHOR_NAME: "Prueba", GIT_AUTHOR_EMAIL: "prueba@ejemplo.com",
|
|
20
|
-
GIT_COMMITTER_NAME: "Prueba", GIT_COMMITTER_EMAIL: "prueba@ejemplo.com",
|
|
21
|
-
} });
|
|
22
|
-
git("init", "-q");
|
|
23
|
-
git("config", "user.email", "prueba@ejemplo.com");
|
|
24
|
-
git("config", "user.name", "Prueba");
|
|
25
|
-
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, "a.txt"), Array.from({ length: 10 }, (_, i) => `linea ${i}`).join("\n") + "\n");
|
|
26
|
-
git("add", "-A");
|
|
27
|
-
git("commit", "-q", "-m", "feat: primer commit con diez líneas");
|
|
28
|
-
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, "b.txt"), "una\ndos\ntres\n");
|
|
29
|
-
git("add", "-A");
|
|
30
|
-
git("commit", "-q", "-m", "feat(b): añade tres líneas más");
|
|
31
|
-
return dir;
|
|
32
|
-
}
|
|
33
|
-
(0, node_test_1.test)("cuenta las líneas añadidas y borradas de cada commit", async () => {
|
|
34
|
-
// El fallo que esto previene: con el separador de registro DETRÁS de la
|
|
35
|
-
// cabecera, las líneas de --numstat se pegaban al commit siguiente y todos
|
|
36
|
-
// los recuentos salían +0 −0.
|
|
37
|
-
const dir = makeRepo();
|
|
38
|
-
const commits = await (0, git_js_1.readCommits)(dir);
|
|
39
|
-
strict_1.default.equal(commits.length, 2);
|
|
40
|
-
const total = commits.reduce((s, c) => s + c.linesAdded, 0);
|
|
41
|
-
strict_1.default.equal(total, 13, "10 líneas del primer commit + 3 del segundo");
|
|
42
|
-
const primero = commits.find((c) => c.subject.includes("primer"));
|
|
43
|
-
strict_1.default.ok(primero);
|
|
44
|
-
strict_1.default.equal(primero.linesAdded, 10);
|
|
45
|
-
strict_1.default.equal(primero.linesDeleted, 0);
|
|
46
|
-
});
|
|
47
|
-
(0, node_test_1.test)("lee hash, fecha, autor y asunto", async () => {
|
|
48
|
-
const dir = makeRepo();
|
|
49
|
-
const commits = await (0, git_js_1.readCommits)(dir);
|
|
50
|
-
const c = commits[0];
|
|
51
|
-
strict_1.default.match(c.hash, /^[0-9a-f]{40}$/);
|
|
52
|
-
strict_1.default.equal(c.authorEmail, "prueba@ejemplo.com");
|
|
53
|
-
strict_1.default.ok(c.subject.length > 0);
|
|
54
|
-
strict_1.default.ok(!Number.isNaN(c.at.getTime()));
|
|
55
|
-
});
|
|
56
|
-
(0, node_test_1.test)("filtra por autor", async () => {
|
|
57
|
-
const dir = makeRepo();
|
|
58
|
-
strict_1.default.equal((await (0, git_js_1.readCommits)(dir, { authorEmail: "prueba@ejemplo.com" })).length, 2);
|
|
59
|
-
strict_1.default.equal((await (0, git_js_1.readCommits)(dir, { authorEmail: "otro@ejemplo.com" })).length, 0);
|
|
60
|
-
});
|
|
61
|
-
(0, node_test_1.test)("un directorio que no es repo devuelve vacío en vez de lanzar", async () => {
|
|
62
|
-
const dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "estela-norepo-"));
|
|
63
|
-
strict_1.default.equal(await (0, git_js_1.repoRoot)(dir), null);
|
|
64
|
-
strict_1.default.deepEqual(await (0, git_js_1.readCommits)(dir), []);
|
|
65
|
-
});
|
|
66
|
-
(0, node_test_1.test)("repoRoot funciona donde la comprobación de un .git como directorio fallaría", async () => {
|
|
67
|
-
// En un `git worktree` el .git es un archivo, no un directorio. Por eso se
|
|
68
|
-
// usa `git rev-parse --show-toplevel` y no `existsSync(join(dir, '.git'))`.
|
|
69
|
-
const dir = makeRepo();
|
|
70
|
-
const root = await (0, git_js_1.repoRoot)(dir);
|
|
71
|
-
strict_1.default.ok(root);
|
|
72
|
-
// baseName y no split("/"): en Windows la ruta del test va con \\ y la de git con /.
|
|
73
|
-
strict_1.default.equal((0, paths_js_1.baseName)(root), (0, paths_js_1.baseName)(dir));
|
|
74
|
-
});
|
|
75
|
-
//# sourceMappingURL=git.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git.test.js","sourceRoot":"","sources":["../../src/watchers/git.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/watchers/identity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAKnD;;;;;;;;;;;;;GAaG;AAEH;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC5C,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAanC;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,SAAS,YAAY,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GACvE,YAAY,EAAE,CAEhB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/watchers/identity.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,wCAeC;AASD,4BAIC;AAtDD,sDAAwC;AACxC,qCAAkD;AAElD;;;;;;;;;;;;;GAaG;AAEH;;;;;;;GAOG;AACI,KAAK,UAAU,cAAc,CAClC,EAAgB,EAAE,SAA2B;IAE7C,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE5C,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,IAAA,iBAAQ,EAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAEtC,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACpE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,IAAA,qBAAY,EAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvF,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,MAAkB,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,QAAQ,CACtB,OAAgC,EAAE,IAAsC;IAExE,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,CAAC;AAClF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"identity.test.d.ts","sourceRoot":"","sources":["../../src/watchers/identity.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
7
|
-
const node_test_1 = require("node:test");
|
|
8
|
-
const sessionize_js_1 = require("../billing/sessionize.js");
|
|
9
|
-
const identity_js_1 = require("./identity.js");
|
|
10
|
-
function commit(email, iso, repo = "/repo") {
|
|
11
|
-
return {
|
|
12
|
-
repoPath: repo, hash: `${email}-${iso}`, at: new Date(iso),
|
|
13
|
-
authorEmail: email, authorName: email.split("@")[0], branch: "main",
|
|
14
|
-
subject: "trabajo", linesAdded: 1, linesDeleted: 0, files: [],
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
const MINE = new Map([["/repo", new Set(["yo@ejemplo.com"])]]);
|
|
18
|
-
(0, node_test_1.test)("el trabajo de un compañero nunca se convierte en horas tuyas", () => {
|
|
19
|
-
// La regresión más cara que este sistema puede sufrir: desde que `commits`
|
|
20
|
-
// guarda a todo el equipo, un filtro que falle te haría facturarle a un
|
|
21
|
-
// cliente el trabajo de otra persona.
|
|
22
|
-
const commits = [
|
|
23
|
-
commit("yo@ejemplo.com", "2026-08-20T09:00:00Z"),
|
|
24
|
-
commit("ana@empresa.com", "2026-08-20T10:00:00Z"),
|
|
25
|
-
commit("ana@empresa.com", "2026-08-21T10:00:00Z"),
|
|
26
|
-
];
|
|
27
|
-
const mine = (0, identity_js_1.onlyMine)(commits, MINE);
|
|
28
|
-
strict_1.default.equal(mine.length, 1);
|
|
29
|
-
strict_1.default.equal(mine[0].authorEmail, "yo@ejemplo.com");
|
|
30
|
-
const blocks = (0, sessionize_js_1.sessionizeCommits)(mine);
|
|
31
|
-
strict_1.default.equal(blocks.length, 1, "solo tu commit produce un bloque");
|
|
32
|
-
strict_1.default.ok(blocks.every((b) => b.commits.every((c) => c.authorEmail === "yo@ejemplo.com")));
|
|
33
|
-
});
|
|
34
|
-
(0, node_test_1.test)("un repositorio sin autores conocidos no aporta horas", () => {
|
|
35
|
-
// Preferimos perder horas a imputarte las de otro: quedarse corto se corrige
|
|
36
|
-
// con `estela author`, haber facturado trabajo ajeno no.
|
|
37
|
-
const commits = [commit("quien.sea@empresa.com", "2026-08-20T09:00:00Z", "/otro")];
|
|
38
|
-
strict_1.default.equal((0, identity_js_1.onlyMine)(commits, MINE).length, 0);
|
|
39
|
-
strict_1.default.equal((0, sessionize_js_1.sessionizeCommits)((0, identity_js_1.onlyMine)(commits, MINE)).length, 0);
|
|
40
|
-
});
|
|
41
|
-
(0, node_test_1.test)("los correos de un repositorio no valen en otro", () => {
|
|
42
|
-
// Commiteas con un correo distinto en cada cliente. Si el filtro no
|
|
43
|
-
// distinguiera el repositorio, capturarías commits ajenos allí donde otra
|
|
44
|
-
// persona use el correo que tú usas aquí.
|
|
45
|
-
const commits = [commit("yo@ejemplo.com", "2026-08-20T09:00:00Z", "/ajeno")];
|
|
46
|
-
strict_1.default.equal((0, identity_js_1.onlyMine)(commits, MINE).length, 0);
|
|
47
|
-
});
|
|
48
|
-
//# sourceMappingURL=identity.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"identity.test.js","sourceRoot":"","sources":["../../src/watchers/identity.test.ts"],"names":[],"mappings":";;;;;AAAA,gEAAwC;AACxC,yCAAiC;AAIjC,4DAA6D;AAC7D,+CAAyC;AAEzC,SAAS,MAAM,CAAC,KAAa,EAAE,GAAW,EAAE,IAAI,GAAG,OAAO;IACxD,OAAO;QACL,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC;QAC1D,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,EAAE,MAAM,EAAE,MAAM;QACpE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE;KAC9D,CAAC;AACJ,CAAC;AAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE/D,IAAA,gBAAI,EAAC,8DAA8D,EAAE,GAAG,EAAE;IACxE,2EAA2E;IAC3E,wEAAwE;IACxE,sCAAsC;IACtC,MAAM,OAAO,GAAG;QACd,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,CAAC;QAChD,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;QACjD,MAAM,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;KAClD,CAAC;IAEF,MAAM,IAAI,GAAG,IAAA,sBAAQ,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrC,gBAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC7B,gBAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,IAAA,iCAAiB,EAAC,IAAI,CAAC,CAAC;IACvC,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,kCAAkC,CAAC,CAAC;IACnE,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAC7F,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,sDAAsD,EAAE,GAAG,EAAE;IAChE,6EAA6E;IAC7E,yDAAyD;IACzD,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,uBAAuB,EAAE,sBAAsB,EAAE,OAAO,CAAC,CAAC,CAAC;IACnF,gBAAM,CAAC,KAAK,CAAC,IAAA,sBAAQ,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAChD,gBAAM,CAAC,KAAK,CAAC,IAAA,iCAAiB,EAAC,IAAA,sBAAQ,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC;AAEH,IAAA,gBAAI,EAAC,gDAAgD,EAAE,GAAG,EAAE;IAC1D,oEAAoE;IACpE,0EAA0E;IAC1E,0CAA0C;IAC1C,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,gBAAgB,EAAE,sBAAsB,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7E,gBAAM,CAAC,KAAK,CAAC,IAAA,sBAAQ,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC"}
|
package/dist/web-ui.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"web-ui.test.d.ts","sourceRoot":"","sources":["../src/web-ui.test.ts"],"names":[],"mappings":""}
|
package/dist/web-ui.test.js
DELETED
|
@@ -1,414 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
7
|
-
const node_fs_1 = require("node:fs");
|
|
8
|
-
const node_path_1 = require("node:path");
|
|
9
|
-
const node_test_1 = require("node:test");
|
|
10
|
-
/**
|
|
11
|
-
* Pruebas de la interfaz web sin navegador.
|
|
12
|
-
*
|
|
13
|
-
* Los fallos que llegaron a producción fueron de dos clases:
|
|
14
|
-
*
|
|
15
|
-
* 1. Lógica pura mal escrita — "2h 60m", el día de hoy calculado en UTC, el
|
|
16
|
-
* salto de dos días al navegar. Se prueban llamando a las funciones.
|
|
17
|
-
* 2. CSS y DOM — el atributo `hidden` que no ocultaba nada porque una clase
|
|
18
|
-
* con `display: flex` lo pisaba, y un `id` referenciado que no existía en
|
|
19
|
-
* el HTML. Se prueban leyendo los ficheros y comprobando invariantes.
|
|
20
|
-
*
|
|
21
|
-
* Nada de esto necesita un navegador ni una dependencia nueva, y cubre las dos
|
|
22
|
-
* familias de fallo que de verdad ocurrieron.
|
|
23
|
-
*/
|
|
24
|
-
const WEB = (0, node_path_1.join)(__dirname, "..", "..", "web");
|
|
25
|
-
const html = (0, node_fs_1.readFileSync)((0, node_path_1.join)(WEB, "index.html"), "utf8");
|
|
26
|
-
const css = (0, node_fs_1.readFileSync)((0, node_path_1.join)(WEB, "app.css"), "utf8");
|
|
27
|
-
const appJs = (0, node_fs_1.readFileSync)((0, node_path_1.join)(WEB, "app.js"), "utf8");
|
|
28
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
29
|
-
const lib = require((0, node_path_1.join)(WEB, "lib.js"));
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
31
|
-
const i18n = require((0, node_path_1.join)(WEB, "i18n.js"));
|
|
32
|
-
// ── Duraciones ─────────────────────────────────────────────────────────
|
|
33
|
-
(0, node_test_1.test)("interfaz: nunca imprime 60 minutos", () => {
|
|
34
|
-
strict_1.default.equal(lib.fmtDuration(2 * 3600 + 59 * 60 + 50), "3h");
|
|
35
|
-
strict_1.default.equal(lib.fmtDuration(3599), "1h");
|
|
36
|
-
for (let s = 0; s < 12 * 3600; s += 13) {
|
|
37
|
-
strict_1.default.ok(!lib.fmtDuration(s).includes("60m"), `fmtDuration(${s})`);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
(0, node_test_1.test)("interfaz: duraciones normales", () => {
|
|
41
|
-
strict_1.default.equal(lib.fmtDuration(0), "0m");
|
|
42
|
-
strict_1.default.equal(lib.fmtDuration(3660), "1h 01m");
|
|
43
|
-
strict_1.default.equal(lib.fmtDuration(4 * 3600 + 16 * 60), "4h 16m");
|
|
44
|
-
});
|
|
45
|
-
// ── Fechas ─────────────────────────────────────────────────────────────
|
|
46
|
-
(0, node_test_1.test)("interfaz: hoy se calcula en local, no en Greenwich", () => {
|
|
47
|
-
// El fallo real: a las 23:31 en UTC-5, toISOString() daba el día siguiente,
|
|
48
|
-
// así que la pestaña "Hoy" llevaba a un día vacío y el día real salía
|
|
49
|
-
// etiquetado como "Ayer".
|
|
50
|
-
const tarde = new Date("2026-08-27T04:31:00Z"); // 23:31 del 26 en UTC-5
|
|
51
|
-
strict_1.default.equal(lib.localToday(0, tarde), lib.localDay(tarde));
|
|
52
|
-
if (tarde.getTimezoneOffset() > 0) {
|
|
53
|
-
strict_1.default.notEqual(lib.localToday(0, tarde), tarde.toISOString().slice(0, 10), "al oeste de Greenwich la fecha local difiere de la UTC a esa hora");
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
(0, node_test_1.test)("interfaz: navegar un día no salta dos", () => {
|
|
57
|
-
// Anclar a mediodía evita que a las 00:30 la aritmética en UTC salte dos días.
|
|
58
|
-
strict_1.default.equal(lib.shiftDay("2026-08-26", 1), "2026-08-27");
|
|
59
|
-
strict_1.default.equal(lib.shiftDay("2026-08-27", -1), "2026-08-26");
|
|
60
|
-
strict_1.default.equal(lib.shiftDay("2026-03-01", -1), "2026-02-28");
|
|
61
|
-
strict_1.default.equal(lib.shiftDay("2026-12-31", 1), "2027-01-01");
|
|
62
|
-
});
|
|
63
|
-
(0, node_test_1.test)("interfaz: ida y vuelta entre días siempre vuelve al mismo sitio", () => {
|
|
64
|
-
let day = "2026-01-01";
|
|
65
|
-
for (let i = 0; i < 400; i++) {
|
|
66
|
-
const next = lib.shiftDay(day, 1);
|
|
67
|
-
strict_1.default.equal(lib.shiftDay(next, -1), day, `falla en ${day}`);
|
|
68
|
-
day = next;
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
(0, node_test_1.test)("interfaz: 'Hoy' y 'Ayer' se calculan con la misma fecha local", () => {
|
|
72
|
-
const now = new Date("2026-08-27T04:31:00Z");
|
|
73
|
-
strict_1.default.equal(lib.fmtDayTitle(lib.localToday(0, now), now), "Hoy");
|
|
74
|
-
strict_1.default.equal(lib.fmtDayTitle(lib.localToday(-1, now), now), "Ayer");
|
|
75
|
-
});
|
|
76
|
-
(0, node_test_1.test)("interfaz: el periodo 'todo' no acota fechas", () => {
|
|
77
|
-
strict_1.default.deepEqual(lib.periodRange("all"), { from: "", to: "" });
|
|
78
|
-
const mes = lib.periodRange("month", new Date("2026-08-27T12:00:00Z"));
|
|
79
|
-
strict_1.default.ok(mes.from.endsWith("-01"), "el mes empieza el día 1");
|
|
80
|
-
strict_1.default.ok(mes.from <= mes.to);
|
|
81
|
-
});
|
|
82
|
-
// ── Importes ───────────────────────────────────────────────────────────
|
|
83
|
-
(0, node_test_1.test)("interfaz: sin importe devuelve null, no cero", () => {
|
|
84
|
-
// Enseñar "0,00" donde no hay tarifa haría creer que el trabajo no vale nada.
|
|
85
|
-
strict_1.default.equal(lib.fmtMoney(null, "EUR"), null);
|
|
86
|
-
strict_1.default.equal(lib.fmtMoney(undefined, "EUR"), null);
|
|
87
|
-
strict_1.default.equal(lib.fmtMoney(0, "EUR"), "€0,00");
|
|
88
|
-
});
|
|
89
|
-
(0, node_test_1.test)("interfaz: una moneda sin símbolo se escribe con su código", () => {
|
|
90
|
-
strict_1.default.ok(lib.fmtMoney(1000, "COP").includes("COP"));
|
|
91
|
-
strict_1.default.equal(lib.fmtMoney(1300, "EUR"), "€13,00");
|
|
92
|
-
});
|
|
93
|
-
// ── Invariantes del HTML y el CSS ──────────────────────────────────────
|
|
94
|
-
(0, node_test_1.test)("interfaz: el atributo hidden oculta de verdad", () => {
|
|
95
|
-
// El fallo real: `[hidden] { display: none }` es una regla del navegador y
|
|
96
|
-
// cualquier `display` de autor la gana. Como .hero y .approve son flex, el
|
|
97
|
-
// atributo no hacía nada: el formulario salía abierto y un día vacío seguía
|
|
98
|
-
// enseñando las cifras del anterior.
|
|
99
|
-
strict_1.default.match(css, /\[hidden\]\s*\{[^}]*display:\s*none\s*!important/, "hace falta [hidden] { display: none !important }");
|
|
100
|
-
});
|
|
101
|
-
(0, node_test_1.test)("interfaz: todo id que usa el guion existe en el HTML", () => {
|
|
102
|
-
// Un $("#x") contra un id que se renombró devuelve null y revienta al usarlo.
|
|
103
|
-
const ids = new Set([...html.matchAll(/\bid="([^"]+)"/g)].map((m) => m[1]));
|
|
104
|
-
const usados = [...appJs.matchAll(/\$\("#([a-zA-Z0-9_-]+)"\)/g)].map((m) => m[1]);
|
|
105
|
-
// Los que se crean dinámicamente y no están en el HTML de partida.
|
|
106
|
-
const dinamicos = new Set(["add-toggle", "add-form", "add-cancel", "add-kind",
|
|
107
|
-
"add-minutes", "add-what", "add-project", "new-project", "np-repo", "np-name",
|
|
108
|
-
"np-rate", "np-client", "np-clientname", "np-currency", "approve-all", "rep-periods",
|
|
109
|
-
"team-more", "rep-search", "reports-more"]);
|
|
110
|
-
const faltan = [...new Set(usados)].filter((id) => !ids.has(id) && !dinamicos.has(id));
|
|
111
|
-
strict_1.default.deepEqual(faltan, [], `ids referenciados que no existen: ${faltan.join(", ")}`);
|
|
112
|
-
});
|
|
113
|
-
(0, node_test_1.test)("interfaz: ningún color vive solo dentro de un media query", () => {
|
|
114
|
-
// Un color declarado únicamente bajo `prefers-color-scheme` no aplica en el
|
|
115
|
-
// otro tema, y la página sale con el texto de un tema sobre el fondo del otro.
|
|
116
|
-
const dentro = css.slice(css.indexOf("@media (prefers-color-scheme: dark)"));
|
|
117
|
-
const bloque = dentro.slice(0, dentro.indexOf("\n}\n") + 3);
|
|
118
|
-
const reglas = [...bloque.matchAll(/^\s{2,}([a-z-]+)\s*\{/gm)].map((m) => m[1]);
|
|
119
|
-
strict_1.default.deepEqual(reglas, [], `el bloque oscuro solo debe redefinir variables, no reglas: ${reglas.join(", ")}`);
|
|
120
|
-
});
|
|
121
|
-
(0, node_test_1.test)("interfaz: no quedan fechas calculadas en UTC", () => {
|
|
122
|
-
// El patrón que causó tres fallos distintos: toISOString().slice(0,10) sin
|
|
123
|
-
// restar antes el desfase horario.
|
|
124
|
-
const sospechosas = [...appJs.matchAll(/toISOString\(\)\.slice\(0,\s*10\)/g)];
|
|
125
|
-
const conOffset = [...appJs.matchAll(/getTimezoneOffset\(\)[^;]*toISOString\(\)\.slice\(0,\s*10\)/g)];
|
|
126
|
-
strict_1.default.equal(sospechosas.length, conOffset.length, "toda conversión a YYYY-MM-DD debe restar el desfase horario antes");
|
|
127
|
-
});
|
|
128
|
-
(0, node_test_1.test)("interfaz: el HTML carga lib.js, luego i18n.js, luego app.js", () => {
|
|
129
|
-
// Al revés, app.js llamaría a funciones que aún no existen, e i18n.js no
|
|
130
|
-
// podría avisar a lib.js del idioma para las fechas y los importes.
|
|
131
|
-
const lib = html.indexOf('src="/lib.js"');
|
|
132
|
-
const i18n = html.indexOf('src="/i18n.js"');
|
|
133
|
-
const app = html.indexOf('src="/app.js"');
|
|
134
|
-
strict_1.default.ok(lib > 0 && i18n > 0 && app > 0, "los tres scripts deben estar enlazados");
|
|
135
|
-
strict_1.default.ok(lib < i18n && i18n < app, "orden: lib.js, i18n.js, app.js");
|
|
136
|
-
});
|
|
137
|
-
(0, node_test_1.test)("interfaz: el escapado neutraliza HTML en datos", () => {
|
|
138
|
-
// Un mensaje de commit con etiquetas no puede inyectarse en la página.
|
|
139
|
-
const salida = lib.esc('<img onerror="alert(1)"> & "x"');
|
|
140
|
-
strict_1.default.ok(!salida.includes("<img"));
|
|
141
|
-
strict_1.default.ok(salida.includes("<img"));
|
|
142
|
-
strict_1.default.ok(salida.includes("&"));
|
|
143
|
-
});
|
|
144
|
-
// ── La misma lógica bajo varios husos horarios ─────────────────────────
|
|
145
|
-
/**
|
|
146
|
-
* Recarga lib.js con otra zona horaria.
|
|
147
|
-
*
|
|
148
|
-
* Sin esto, los tests de fechas solo valen en el huso de quien los ejecuta: la
|
|
149
|
-
* versión defectuosa de `shiftDay` acierta por casualidad en UTC-5 y falla al
|
|
150
|
-
* este de Greenwich. Un test que depende del reloj de la máquina no prueba nada.
|
|
151
|
-
*/
|
|
152
|
-
function conZona(tz, fn) {
|
|
153
|
-
const previa = process.env["TZ"];
|
|
154
|
-
process.env["TZ"] = tz;
|
|
155
|
-
const ruta = require.resolve((0, node_path_1.join)(WEB, "lib.js"));
|
|
156
|
-
delete require.cache[ruta];
|
|
157
|
-
try {
|
|
158
|
-
return fn(require(ruta));
|
|
159
|
-
}
|
|
160
|
-
finally {
|
|
161
|
-
process.env["TZ"] = previa;
|
|
162
|
-
delete require.cache[ruta];
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
const libMod = lib;
|
|
166
|
-
const ZONAS = [
|
|
167
|
-
"America/Guayaquil", // UTC-5, el tuyo
|
|
168
|
-
"Pacific/Honolulu", // UTC-10, el extremo oeste
|
|
169
|
-
"Europe/Madrid", // UTC+2
|
|
170
|
-
"Asia/Tokyo", // UTC+9
|
|
171
|
-
"Pacific/Kiritimati", // UTC+14, el extremo este
|
|
172
|
-
"Asia/Kathmandu", // UTC+5:45, desfase no entero
|
|
173
|
-
];
|
|
174
|
-
(0, node_test_1.test)("fechas: navegar un día funciona en cualquier huso", () => {
|
|
175
|
-
for (const tz of ZONAS) {
|
|
176
|
-
conZona(tz, (l) => {
|
|
177
|
-
strict_1.default.equal(l.shiftDay("2026-08-26", 1), "2026-08-27", `avanzar en ${tz}`);
|
|
178
|
-
strict_1.default.equal(l.shiftDay("2026-08-27", -1), "2026-08-26", `retroceder en ${tz}`);
|
|
179
|
-
strict_1.default.equal(l.shiftDay("2026-02-28", 1), "2026-03-01", `fin de mes en ${tz}`);
|
|
180
|
-
strict_1.default.equal(l.shiftDay("2026-01-01", -1), "2025-12-31", `cambio de año en ${tz}`);
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
(0, node_test_1.test)("fechas: ida y vuelta es estable en cualquier huso", () => {
|
|
185
|
-
for (const tz of ZONAS) {
|
|
186
|
-
conZona(tz, (l) => {
|
|
187
|
-
let day = "2026-03-01";
|
|
188
|
-
for (let i = 0; i < 120; i++) {
|
|
189
|
-
const next = l.shiftDay(day, 1);
|
|
190
|
-
strict_1.default.equal(l.shiftDay(next, -1), day, `${day} en ${tz}`);
|
|
191
|
-
day = next;
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
(0, node_test_1.test)("fechas: el día local nunca es el de Greenwich al este ni al oeste", () => {
|
|
197
|
-
// A las 23:31 en Guayaquil ya es el día siguiente en UTC; a las 00:30 en
|
|
198
|
-
// Tokio todavía es el día anterior. Ambos casos rompían la pestaña "Hoy".
|
|
199
|
-
const nocheGuayaquil = new Date("2026-08-27T04:31:00Z");
|
|
200
|
-
conZona("America/Guayaquil", (l) => {
|
|
201
|
-
strict_1.default.equal(l.localToday(0, nocheGuayaquil), "2026-08-26");
|
|
202
|
-
});
|
|
203
|
-
const madrugadaTokio = new Date("2026-08-26T15:30:00Z"); // 00:30 del 27 en Tokio
|
|
204
|
-
conZona("Asia/Tokyo", (l) => {
|
|
205
|
-
strict_1.default.equal(l.localToday(0, madrugadaTokio), "2026-08-27");
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
(0, node_test_1.test)("fechas: el rango del mes empieza el día 1 en cualquier huso", () => {
|
|
209
|
-
for (const tz of ZONAS) {
|
|
210
|
-
conZona(tz, (l) => {
|
|
211
|
-
const r = l.periodRange("month", new Date("2026-08-27T04:31:00Z"));
|
|
212
|
-
strict_1.default.ok(r.from.endsWith("-01"), `${tz}: ${r.from}`);
|
|
213
|
-
strict_1.default.ok(r.from <= r.to, `${tz}: ${r.from} > ${r.to}`);
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
(0, node_test_1.test)("interfaz: 'sin tarifa' solo se dice cuando de verdad falta", () => {
|
|
218
|
-
// El fallo real: un día con trabajo en euros y en dólares dejaba el total
|
|
219
|
-
// nulo, y la pantalla decía "sin tarifa definida" aunque todas estuvieran
|
|
220
|
-
// puestas. Mandaba a revisar una configuración correcta.
|
|
221
|
-
//
|
|
222
|
-
// Se comprueba sobre el propio código: la etiqueta debe depender de si hay
|
|
223
|
-
// subtotales, no de que exista un total único.
|
|
224
|
-
strict_1.default.match(appJs, /const totals = day\.totals \|\| \[\]/, "el día debe usar subtotales por moneda");
|
|
225
|
-
strict_1.default.match(appJs, /day\.missingRate \? tr\("day\.noRate"\)/, "la etiqueta de falta de tarifa debe venir del servidor, no deducirse de un total nulo");
|
|
226
|
-
strict_1.default.ok(!/money \? "por facturar" : "sin tarifa definida"/.test(appJs), "no puede deducirse la falta de tarifa de que el total sea nulo");
|
|
227
|
-
});
|
|
228
|
-
// ── Mantenerse al día ────────────────────────────────────────────────────────
|
|
229
|
-
(0, node_test_1.test)("cada pestaña se puede refrescar", () => {
|
|
230
|
-
// Si se añade una pestaña y no se enseña a reloadView() a recargarla, el
|
|
231
|
-
// botón de actualizar deja de hacer nada en esa vista y no lo dice. Falla
|
|
232
|
-
// en silencio, que es justo el fallo que este cambio venía a arreglar.
|
|
233
|
-
const tabs = [...html.matchAll(/data-view="([a-z]+)"/g)].map((m) => m[1]);
|
|
234
|
-
strict_1.default.ok(tabs.length >= 4, `solo se encontraron ${tabs.length} pestañas`);
|
|
235
|
-
const reload = appJs.slice(appJs.indexOf("function reloadView"));
|
|
236
|
-
const body = reload.slice(0, reload.indexOf("\n}"));
|
|
237
|
-
for (const tab of tabs) {
|
|
238
|
-
strict_1.default.ok(body.includes(`"${tab}"`), `reloadView() no recarga la pestaña "${tab}"`);
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
(0, node_test_1.test)("el aviso de import fallido existe y se puede ocultar", () => {
|
|
242
|
-
// El fallo real: `hidden` no ocultaba nada porque una clase con display lo
|
|
243
|
-
// pisaba. Aquí el aviso nace oculto, así que la regla tiene que aguantar.
|
|
244
|
-
strict_1.default.match(html, /id="sync-warn"[^>]*hidden/, "el aviso debe empezar oculto");
|
|
245
|
-
strict_1.default.ok(!/\.sync-warn\s*\{[^}]*display:/.test(css), ".sync-warn no debe declarar display: pisaría a [hidden]");
|
|
246
|
-
});
|
|
247
|
-
(0, node_test_1.test)("el botón de actualizar existe y está referenciado", () => {
|
|
248
|
-
for (const id of ["sync", "sync-label", "sync-warn"]) {
|
|
249
|
-
strict_1.default.ok(html.includes(`id="${id}"`), `falta id="${id}" en el HTML`);
|
|
250
|
-
strict_1.default.ok(appJs.includes(`#${id}`), `app.js no usa #${id}`);
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
(0, node_test_1.test)("volver a la pestaña actualiza", () => {
|
|
254
|
-
// Es la vía que no exige acordarse de nada, y por eso la que importa.
|
|
255
|
-
strict_1.default.ok(appJs.includes("visibilitychange"), "sin esto hay que pulsar el botón a mano cada vez");
|
|
256
|
-
});
|
|
257
|
-
(0, node_test_1.test)("la animación del botón respeta prefers-reduced-motion", () => {
|
|
258
|
-
const idx = css.indexOf("prefers-reduced-motion");
|
|
259
|
-
strict_1.default.ok(idx > 0, "falta la regla de movimiento reducido");
|
|
260
|
-
strict_1.default.ok(css.slice(idx).includes("sync-dot"), "el punto que parpadea debe pararse con movimiento reducido");
|
|
261
|
-
});
|
|
262
|
-
// ── Vista de equipo ──────────────────────────────────────────────────────────
|
|
263
|
-
(0, node_test_1.test)("los KPIs del equipo nunca se apilan en una columna", () => {
|
|
264
|
-
// Cuatro cifras apiladas dejan de compararse entre sí y vuelven a ser datos
|
|
265
|
-
// sueltos, que es justo el problema que esta pantalla venía a resolver.
|
|
266
|
-
const block = css.slice(css.indexOf(".kpis-4"));
|
|
267
|
-
strict_1.default.match(block, /grid-template-columns:\s*repeat\(4/);
|
|
268
|
-
const mobile = block.slice(block.indexOf("max-width"), block.indexOf("max-width") + 160);
|
|
269
|
-
strict_1.default.match(mobile, /repeat\(2/, "en móvil deben quedar dos columnas, no una");
|
|
270
|
-
});
|
|
271
|
-
(0, node_test_1.test)("los segmentos de la barra de composición son bloques", () => {
|
|
272
|
-
// Ya pasó dos veces: un <span> sin display:block renderiza a altura cero y
|
|
273
|
-
// la barra desaparece sin que nada falle.
|
|
274
|
-
const seg = css.slice(css.indexOf(".seg "), css.indexOf(".seg ") + 90);
|
|
275
|
-
strict_1.default.match(seg, /display:\s*block/);
|
|
276
|
-
});
|
|
277
|
-
(0, node_test_1.test)("la tabla ancha hace scroll dentro de su caja, no en la página", () => {
|
|
278
|
-
const wrap = css.slice(css.indexOf(".tbl-wrap"), css.indexOf(".tbl-wrap") + 120);
|
|
279
|
-
strict_1.default.match(wrap, /overflow-x:\s*auto/);
|
|
280
|
-
});
|
|
281
|
-
(0, node_test_1.test)("las cifras de la tabla se alinean para poder compararse", () => {
|
|
282
|
-
const num = css.slice(css.indexOf(".tbl .num"), css.indexOf(".tbl .num") + 130);
|
|
283
|
-
strict_1.default.match(num, /text-align:\s*right/);
|
|
284
|
-
strict_1.default.match(num, /tabular-nums/, "sin cifras de ancho fijo las columnas bailan");
|
|
285
|
-
});
|
|
286
|
-
(0, node_test_1.test)("medido y estimado se distinguen a la vista", () => {
|
|
287
|
-
// Presentar horas estimadas con el mismo aspecto que las medidas es lo que
|
|
288
|
-
// convertiría esta pantalla en una herramienta para señalar a alguien.
|
|
289
|
-
strict_1.default.ok(appJs.includes('tr("team.measured")') && appJs.includes('tr("team.estimated")'));
|
|
290
|
-
// Y en los dos idiomas: en inglés tampoco pueden verse igual.
|
|
291
|
-
for (const lang of ["es", "en"]) {
|
|
292
|
-
const d = i18n.dict[lang];
|
|
293
|
-
strict_1.default.ok(d["team.measured"] && d["team.estimated"] && d["team.measured"] !== d["team.estimated"], `${lang}: medido y estimado tienen que decir cosas distintas`);
|
|
294
|
-
}
|
|
295
|
-
strict_1.default.ok(css.includes(".prec-ok"), "falta el estilo que separa ambas");
|
|
296
|
-
});
|
|
297
|
-
(0, node_test_1.test)("la tabla de personas no se ordena por horas en el cliente", () => {
|
|
298
|
-
// El orden lo fija el servidor por actividad reciente. Si la web reordenara
|
|
299
|
-
// por horas, volvería a ser un ranking de rendimiento.
|
|
300
|
-
const render = appJs.slice(appJs.indexOf("function renderTeam"));
|
|
301
|
-
const body = render.slice(0, render.indexOf("\n}"));
|
|
302
|
-
strict_1.default.ok(!/\.sort\(/.test(body), "renderTeam() no debe reordenar a las personas");
|
|
303
|
-
});
|
|
304
|
-
(0, node_test_1.test)("la pestaña Equipo está enganchada a la navegación", () => {
|
|
305
|
-
strict_1.default.ok(html.includes('data-view="team"'));
|
|
306
|
-
strict_1.default.ok(html.includes('id="view-team"'));
|
|
307
|
-
strict_1.default.ok(appJs.includes('name === "team"'), "showView() no la carga");
|
|
308
|
-
});
|
|
309
|
-
(0, node_test_1.test)("la vista de equipo avisa de que sus cifras no suman con los totales", () => {
|
|
310
|
-
// Los totales cuentan tu trabajo imputado; la tabla de personas incluye horas
|
|
311
|
-
// estimadas de gente que no usa Estela. Sin decirlo, el primer lector atento
|
|
312
|
-
// ve que no cuadra y deja de creerse el resto de la pantalla.
|
|
313
|
-
strict_1.default.ok(appJs.includes('tr("team.note")'), "la nota tiene que pintarse en la vista de equipo");
|
|
314
|
-
strict_1.default.match(String(i18n.dict["es"]["team.note"]), /no entran<\/b> en los totales/);
|
|
315
|
-
strict_1.default.match(String(i18n.dict["en"]["team.note"]), /aren't included<\/b> in the totals/);
|
|
316
|
-
});
|
|
317
|
-
(0, node_test_1.test)("la vista de equipo ensancha la página", () => {
|
|
318
|
-
// 720px es el ancho para leer un texto. Una tabla de seis columnas ahí no
|
|
319
|
-
// cabe, y era la queja concreta: que ocupe más pantalla.
|
|
320
|
-
strict_1.default.match(css, /main\.wide\s*\{[^}]*max-width:\s*11\d\dpx/);
|
|
321
|
-
strict_1.default.ok(appJs.includes('classList.toggle("wide"'), "nadie activa la clase");
|
|
322
|
-
});
|
|
323
|
-
// ── Informes: buscador y plegado ─────────────────────────────────────────────
|
|
324
|
-
(0, node_test_1.test)("Informes pliega el formulario por defecto, igual que un bloque de Mi día", () => {
|
|
325
|
-
// El fallo que esto evita: con varios proyectos con tarifa, la pantalla
|
|
326
|
-
// desplegaba fecha+fecha+nombre+casilla+botón para CADA UNO a la vez, y se
|
|
327
|
-
// volvía una columna larga sin poder distinguir un proyecto de otro.
|
|
328
|
-
strict_1.default.ok(appJs.includes("state.reportsOpen"), "falta el registro de qué fila está abierta");
|
|
329
|
-
strict_1.default.match(appJs, /\$\{open \? `[\s\S]*?<form class="report-actions"/, "el formulario debe renderizarse solo cuando la fila está abierta, no ocultarse con CSS");
|
|
330
|
-
});
|
|
331
|
-
(0, node_test_1.test)("Informes muestra un tope de filas con 'ver más', y busca en el navegador", () => {
|
|
332
|
-
strict_1.default.ok(appJs.includes("const REPORT_ROWS = 5"), "el tope debe ser explícito, no un número suelto");
|
|
333
|
-
strict_1.default.ok(appJs.includes("state.reportsQuery"), "falta el estado del buscador");
|
|
334
|
-
strict_1.default.ok(appJs.includes('id="reports-more"'), "falta el botón de ver más proyectos");
|
|
335
|
-
});
|
|
336
|
-
// ── Idiomas ──────────────────────────────────────────────────────────────────
|
|
337
|
-
function variables(entry) {
|
|
338
|
-
const texto = typeof entry === "string" ? entry : entry.one + entry.other;
|
|
339
|
-
return [...new Set([...texto.matchAll(/\{(\w+)\}/g)].map((m) => m[1]))].sort().join(",");
|
|
340
|
-
}
|
|
341
|
-
(0, node_test_1.test)("idiomas: español e inglés tienen exactamente las mismas claves", () => {
|
|
342
|
-
// Una clave solo en un idioma cae al español en pantalla: en inglés saldría
|
|
343
|
-
// media interfaz en otro idioma sin que nada fallara.
|
|
344
|
-
const es = Object.keys(i18n.dict["es"]);
|
|
345
|
-
const en = Object.keys(i18n.dict["en"]);
|
|
346
|
-
strict_1.default.deepEqual(es.filter((k) => !en.includes(k)), [], "claves sin traducir al inglés");
|
|
347
|
-
strict_1.default.deepEqual(en.filter((k) => !es.includes(k)), [], "claves en inglés que no existen en español");
|
|
348
|
-
});
|
|
349
|
-
(0, node_test_1.test)("idiomas: cada traducción usa las mismas variables y la misma forma", () => {
|
|
350
|
-
// "{n} bloques" traducido como "{count} blocks" dejaría el número sin poner.
|
|
351
|
-
for (const [key, es] of Object.entries(i18n.dict["es"])) {
|
|
352
|
-
const en = i18n.dict["en"][key];
|
|
353
|
-
strict_1.default.equal(typeof en, typeof es, `${key}: uno es plural y el otro no`);
|
|
354
|
-
strict_1.default.equal(variables(en), variables(es), `${key}: variables distintas`);
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
|
-
(0, node_test_1.test)("idiomas: toda clave que usan la página y el HTML existe", () => {
|
|
358
|
-
const usadas = [
|
|
359
|
-
...[...appJs.matchAll(/\btr\("([^"]+)"/g)].map((m) => m[1]),
|
|
360
|
-
...[...html.matchAll(/data-i18n(?:-[a-z-]+)?="([^"]+)"/g)].map((m) => m[1]),
|
|
361
|
-
];
|
|
362
|
-
// `kind.${kind}` se arma en tiempo de ejecución: se comprueba aparte.
|
|
363
|
-
for (const kind of ["development", "meeting", "research", "review", "travel", "support", "other"]) {
|
|
364
|
-
usadas.push(`kind.${kind}`);
|
|
365
|
-
}
|
|
366
|
-
const faltan = [...new Set(usadas)].filter((k) => !(k in i18n.dict["es"]));
|
|
367
|
-
strict_1.default.deepEqual(faltan, [], `claves usadas que no están en i18n.js: ${faltan.join(", ")}`);
|
|
368
|
-
});
|
|
369
|
-
(0, node_test_1.test)("idiomas: no queda texto en español escrito a mano en app.js", () => {
|
|
370
|
-
// La forma de romper el inglés sin que falle nada más: añadir un aviso nuevo
|
|
371
|
-
// con la frase puesta directamente en vez de con tr(). Se buscan tildes y
|
|
372
|
-
// palabras que solo existen en español, fuera de comentarios.
|
|
373
|
-
const codigo = appJs.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
|
|
374
|
-
const lineas = codigo.split("\n").filter((l) => /["'`>]/.test(l) && /[áéíóúñ¿¡]|\b(sin|por|para|los|las|del|una|hay|desde|hasta)\b/.test(l.replace(/tr\("[^"]*"/g, "")));
|
|
375
|
-
// `hay` es el nombre de una variable, no una frase.
|
|
376
|
-
const reales = lineas.filter((l) => !/const hay =/.test(l));
|
|
377
|
-
strict_1.default.deepEqual(reales.map((l) => l.trim()), [], "texto sin pasar por tr()");
|
|
378
|
-
});
|
|
379
|
-
(0, node_test_1.test)("idiomas: plurales y variables se resuelven bien", () => {
|
|
380
|
-
i18n.setLang("es");
|
|
381
|
-
strict_1.default.equal(i18n.t("summary.days", { n: 1 }), "1 día trabajado", "el singular concuerda entero");
|
|
382
|
-
strict_1.default.equal(i18n.t("summary.days", { n: 3 }), "3 días trabajados");
|
|
383
|
-
i18n.setLang("en");
|
|
384
|
-
strict_1.default.equal(i18n.t("summary.days", { n: 1 }), "1 day worked");
|
|
385
|
-
strict_1.default.equal(i18n.t("team.people", { n: 2 }), "2 people", "el plural irregular no es añadir una s");
|
|
386
|
-
strict_1.default.equal(i18n.t("projects.stale.item", { name: "Web", blocks: "2 new blocks", when: "today" }), "Web — 2 new blocks since you published it today");
|
|
387
|
-
i18n.setLang("es");
|
|
388
|
-
});
|
|
389
|
-
(0, node_test_1.test)("idiomas: el elegido a mano gana, luego el del navegador, y si no inglés", () => {
|
|
390
|
-
strict_1.default.equal(i18n.detectLang("es", ["en-US"]), "es", "lo elegido a mano manda");
|
|
391
|
-
strict_1.default.equal(i18n.detectLang(null, ["es-EC", "en"]), "es");
|
|
392
|
-
strict_1.default.equal(i18n.detectLang(null, ["en-GB"]), "en");
|
|
393
|
-
strict_1.default.equal(i18n.detectLang(null, ["fr-FR", "de"]), "en", "un idioma sin traducción cae al inglés");
|
|
394
|
-
strict_1.default.equal(i18n.detectLang("xx", undefined), "en");
|
|
395
|
-
});
|
|
396
|
-
(0, node_test_1.test)("idiomas: fechas e importes siguen al idioma", () => {
|
|
397
|
-
const mod = require((0, node_path_1.join)(WEB, "lib.js"));
|
|
398
|
-
const now = new Date("2026-09-14T15:00:00Z");
|
|
399
|
-
try {
|
|
400
|
-
mod.setLocale("en");
|
|
401
|
-
strict_1.default.equal(mod.fmtDayTitle(mod.localToday(0, now), now), "Today");
|
|
402
|
-
strict_1.default.equal(mod.fmtDayTitle("2026-09-07", now), "Monday, September 7");
|
|
403
|
-
strict_1.default.equal(mod.fmtMoney(1234567, "USD"), "$12,345.67", "en inglés, coma de miles y punto decimal");
|
|
404
|
-
mod.setLocale("es");
|
|
405
|
-
strict_1.default.equal(mod.fmtDayTitle("2026-09-07", now), "lunes 7 de septiembre");
|
|
406
|
-
// 5 cifras: en español, 1234 va sin separador de miles por norma (lo
|
|
407
|
-
// hace así Intl), así que se prueba con un número donde sí toca.
|
|
408
|
-
strict_1.default.equal(mod.fmtMoney(1234567, "EUR"), "€12.345,67");
|
|
409
|
-
}
|
|
410
|
-
finally {
|
|
411
|
-
mod.setLocale("es");
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
//# sourceMappingURL=web-ui.test.js.map
|