niceeval 0.5.4 → 0.6.0
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/INDEX.md +55 -0
- package/dist/agents/types.d.ts +317 -0
- package/dist/context/types.d.ts +335 -0
- package/dist/i18n/core.d.ts +11 -0
- package/dist/i18n/en.d.ts +181 -0
- package/dist/i18n/index.d.ts +5 -0
- package/dist/i18n/zh-CN.d.ts +183 -0
- package/dist/o11y/execution-tree.d.ts +103 -0
- package/dist/o11y/otlp/parse.d.ts +3 -0
- package/dist/o11y/otlp/receiver.d.ts +21 -0
- package/dist/o11y/otlp/select.d.ts +22 -0
- package/dist/o11y/otlp/turn-otel.d.ts +43 -0
- package/dist/o11y/types.d.ts +190 -0
- package/dist/report/aggregate.d.ts +57 -0
- package/dist/report/aggregate.js +212 -0
- package/dist/report/built-ins/cost-pass-rate-comparison.d.ts +1 -0
- package/dist/report/built-ins/cost-pass-rate-comparison.js +17 -0
- package/dist/report/built-ins/index.d.ts +1 -0
- package/dist/report/built-ins/index.js +2 -0
- package/dist/report/components.d.ts +178 -0
- package/dist/report/components.js +132 -0
- package/dist/report/compute.d.ts +106 -0
- package/dist/report/compute.js +618 -0
- package/dist/report/flag.d.ts +6 -0
- package/dist/report/flag.js +8 -0
- package/dist/report/format.d.ts +32 -0
- package/dist/report/format.js +126 -0
- package/dist/report/index.d.ts +19 -0
- package/dist/report/index.js +30 -0
- package/dist/report/load.d.ts +12 -0
- package/dist/report/load.js +56 -0
- package/dist/report/locale.d.ts +83 -0
- package/dist/report/locale.js +160 -0
- package/dist/report/metrics.d.ts +21 -0
- package/dist/report/metrics.js +115 -0
- package/dist/report/primitives.d.ts +64 -0
- package/dist/report/primitives.js +113 -0
- package/dist/report/react/AttemptList.d.ts +23 -0
- package/dist/report/react/AttemptList.js +20 -0
- package/dist/report/react/DeltaTable.d.ts +8 -0
- package/dist/report/react/DeltaTable.js +24 -0
- package/dist/report/react/EvalList.d.ts +10 -0
- package/dist/report/react/EvalList.js +0 -0
- package/dist/report/react/ExperimentList.d.ts +10 -0
- package/dist/report/react/ExperimentList.js +15 -0
- package/dist/report/react/GroupSummary.d.ts +8 -0
- package/dist/report/react/GroupSummary.js +8 -0
- package/dist/report/react/MetricBars.d.ts +10 -0
- package/dist/report/react/MetricBars.js +48 -0
- package/dist/report/react/MetricLine.d.ts +9 -0
- package/dist/report/react/MetricLine.js +68 -0
- package/dist/report/react/MetricMatrix.d.ts +10 -0
- package/dist/report/react/MetricMatrix.js +23 -0
- package/dist/report/react/MetricScatter.d.ts +9 -0
- package/dist/report/react/MetricScatter.js +100 -0
- package/dist/report/react/MetricTable.d.ts +11 -0
- package/dist/report/react/MetricTable.js +26 -0
- package/dist/report/react/RunOverview.d.ts +8 -0
- package/dist/report/react/RunOverview.js +12 -0
- package/dist/report/react/Scoreboard.d.ts +8 -0
- package/dist/report/react/Scoreboard.js +26 -0
- package/dist/report/react/cell.d.ts +9 -0
- package/dist/report/react/cell.js +9 -0
- package/dist/report/react/chart-math.d.ts +14 -0
- package/dist/report/react/chart-math.js +68 -0
- package/dist/report/react/colors.d.ts +14 -0
- package/dist/report/react/colors.js +45 -0
- package/dist/report/react/fixtures.d.ts +19 -0
- package/dist/report/react/fixtures.js +393 -0
- package/dist/report/react/format.d.ts +3 -0
- package/dist/report/react/format.js +7 -0
- package/dist/report/react/index.d.ts +6 -0
- package/dist/report/react/index.js +14 -0
- package/dist/report/report.d.ts +24 -0
- package/dist/report/report.js +49 -0
- package/dist/report/text/faces.d.ts +29 -0
- package/dist/report/text/faces.js +503 -0
- package/dist/report/text/layout.d.ts +75 -0
- package/dist/report/text/layout.js +173 -0
- package/dist/report/text/plot.d.ts +37 -0
- package/dist/report/text/plot.js +81 -0
- package/dist/report/text/table.d.ts +8 -0
- package/dist/report/text/table.js +86 -0
- package/dist/report/tree.d.ts +99 -0
- package/dist/report/tree.js +228 -0
- package/dist/report/types.d.ts +420 -0
- package/dist/report/types.js +4 -0
- package/dist/report/web.d.ts +15 -0
- package/dist/report/web.js +37 -0
- package/dist/results/annotated-source.d.ts +61 -0
- package/dist/results/attempt-evidence.d.ts +69 -0
- package/dist/results/attempt-source.d.ts +15 -0
- package/dist/results/locator.d.ts +75 -0
- package/dist/results/locator.js +0 -0
- package/dist/results/select.d.ts +45 -0
- package/dist/results/select.js +230 -0
- package/dist/results/source-hash.d.ts +9 -0
- package/dist/results/types.d.ts +204 -0
- package/dist/runner/eval-source.d.ts +22 -0
- package/dist/runner/fingerprint.d.ts +23 -0
- package/dist/runner/types.d.ts +332 -0
- package/dist/sandbox/docker-stream.d.ts +24 -0
- package/dist/sandbox/docker.d.ts +84 -0
- package/dist/sandbox/e2b.d.ts +31 -0
- package/dist/sandbox/errors.d.ts +4 -0
- package/dist/sandbox/local-files.d.ts +6 -0
- package/dist/sandbox/paths.d.ts +4 -0
- package/dist/sandbox/registry.d.ts +13 -0
- package/dist/sandbox/resolve.d.ts +40 -0
- package/dist/sandbox/retry.d.ts +10 -0
- package/dist/sandbox/shell.d.ts +11 -0
- package/dist/sandbox/source-files.d.ts +13 -0
- package/dist/sandbox/types.d.ts +203 -0
- package/dist/sandbox/vercel.d.ts +37 -0
- package/dist/scoring/types.d.ts +70 -0
- package/dist/shared/aggregate.d.ts +29 -0
- package/dist/shared/aggregate.js +55 -0
- package/dist/shared/types.d.ts +27 -0
- package/dist/shared/verdict.d.ts +27 -0
- package/dist/shared/verdict.js +34 -0
- package/dist/tty-line.d.ts +6 -0
- package/dist/types.d.ts +7 -0
- package/dist/util.d.ts +22 -0
- package/docs-site/zh/concepts/adapter.mdx +5 -5
- package/docs-site/zh/concepts/assert.mdx +8 -8
- package/docs-site/zh/concepts/evals.mdx +5 -5
- package/docs-site/zh/concepts/experiment.mdx +2 -2
- package/docs-site/zh/concepts/judge.mdx +9 -9
- package/docs-site/zh/concepts/overview.mdx +2 -2
- package/docs-site/zh/concepts/tier.mdx +6 -6
- package/docs-site/zh/example/claude-code-codex-plugin.mdx +9 -5
- package/docs-site/zh/example/claude-code-codex-skill.mdx +12 -7
- package/docs-site/zh/guides/agent-feedback-loop.mdx +235 -78
- package/docs-site/zh/guides/connect-otel.mdx +3 -3
- package/docs-site/zh/guides/connect-your-agent.mdx +2 -2
- package/docs-site/zh/guides/custom-reports.mdx +196 -36
- package/docs-site/zh/guides/experiments.mdx +7 -1
- package/docs-site/zh/guides/fixtures.mdx +1 -1
- package/docs-site/zh/guides/official-adapters.mdx +31 -9
- package/docs-site/zh/guides/publish-report.mdx +3 -3
- package/docs-site/zh/guides/report-components.mdx +194 -55
- package/docs-site/zh/guides/reporters.mdx +2 -2
- package/docs-site/zh/guides/results-data.mdx +35 -34
- package/docs-site/zh/guides/runner.mdx +2 -2
- package/docs-site/zh/guides/sandbox-agent.mdx +2 -2
- package/docs-site/zh/guides/{sandbox-backends.mdx → sandbox-providers.mdx} +11 -11
- package/docs-site/zh/guides/viewing-results.mdx +199 -79
- package/docs-site/zh/guides/write-experiment.mdx +9 -1
- package/docs-site/zh/guides/write-send.mdx +2 -2
- package/docs-site/zh/index.mdx +4 -3
- package/docs-site/zh/introduction.mdx +2 -1
- package/docs-site/zh/quickstart.mdx +5 -3
- package/docs-site/zh/reference/builtin-agents.mdx +38 -13
- package/docs-site/zh/reference/capabilities.mdx +1 -1
- package/docs-site/zh/reference/cli.mdx +36 -13
- package/docs-site/zh/reference/define-agent.mdx +12 -12
- package/docs-site/zh/reference/define-config.mdx +1 -1
- package/docs-site/zh/reference/define-eval.mdx +3 -3
- package/docs-site/zh/reference/events.mdx +7 -1
- package/docs-site/zh/reference/expect.mdx +3 -3
- package/package.json +10 -6
- package/src/agents/bub.ts +129 -42
- package/src/agents/claude-code.test.ts +152 -0
- package/src/agents/claude-code.ts +127 -13
- package/src/agents/codex.test.ts +192 -0
- package/src/agents/codex.ts +151 -12
- package/src/agents/index.ts +9 -3
- package/src/agents/manifest.ts +41 -0
- package/src/agents/plugin-config.test.ts +94 -0
- package/src/agents/shared.ts +33 -2
- package/src/agents/skills.test.ts +214 -0
- package/src/agents/skills.ts +304 -0
- package/src/agents/streaming.ts +5 -5
- package/src/agents/types.ts +54 -2
- package/src/cli.ts +74 -47
- package/src/context/context.test.ts +20 -2
- package/src/context/control-flow.ts +1 -1
- package/src/context/session.test.ts +92 -1
- package/src/context/session.ts +23 -1
- package/src/context/types.ts +4 -4
- package/src/define.test.ts +8 -8
- package/src/define.ts +11 -11
- package/src/expect/index.ts +5 -5
- package/src/i18n/en.ts +34 -15
- package/src/i18n/zh-CN.ts +37 -21
- package/src/index.ts +1 -1
- package/src/o11y/execution-tree.test.ts +452 -0
- package/src/o11y/execution-tree.ts +367 -0
- package/src/o11y/otlp/receiver.ts +1 -1
- package/src/o11y/otlp/select.ts +7 -3
- package/src/o11y/parsers/claude-code.test.ts +175 -0
- package/src/o11y/parsers/claude-code.ts +32 -0
- package/src/o11y/types.ts +6 -1
- package/src/report/aggregate.ts +26 -20
- package/src/report/built-in-user-parity.test.tsx +643 -0
- package/src/report/built-ins/cost-pass-rate-comparison.tsx +23 -0
- package/src/report/built-ins/index.ts +2 -0
- package/src/report/components.tsx +223 -50
- package/src/report/compute.ts +358 -53
- package/src/report/dual-render.test.tsx +1125 -0
- package/src/report/flag.ts +1 -1
- package/src/report/format.ts +50 -2
- package/src/report/index.ts +48 -14
- package/src/report/load.ts +1 -1
- package/src/report/locale.ts +206 -0
- package/src/report/metrics.ts +39 -15
- package/src/report/primitives.tsx +100 -2
- package/src/report/react/AttemptList.tsx +115 -0
- package/src/report/react/DeltaTable.tsx +9 -6
- package/src/report/react/EvalList.tsx +0 -0
- package/src/report/react/ExperimentList.tsx +108 -0
- package/src/report/react/GroupSummary.tsx +66 -0
- package/src/report/react/MetricBars.tsx +24 -13
- package/src/report/react/MetricLine.tsx +21 -21
- package/src/report/react/MetricMatrix.tsx +8 -4
- package/src/report/react/MetricScatter.tsx +136 -96
- package/src/report/react/MetricTable.tsx +115 -15
- package/src/report/react/RunOverview.tsx +48 -26
- package/src/report/react/Scoreboard.tsx +15 -7
- package/src/report/react/cell.tsx +18 -9
- package/src/{view/app/lib/chart.ts → report/react/chart-math.ts} +2 -6
- package/src/report/react/colors.ts +24 -15
- package/src/report/react/enhance.js +129 -0
- package/src/report/react/fixtures.ts +163 -34
- package/src/report/react/format.ts +1 -1
- package/src/report/react/index.tsx +22 -6
- package/src/report/react/render.test.tsx +164 -31
- package/src/report/react/styles.css +405 -213
- package/src/report/report.test.ts +403 -94
- package/src/report/report.ts +29 -11
- package/src/report/text/faces.ts +303 -95
- package/src/report/text/layout.ts +76 -11
- package/src/report/text/table.ts +98 -0
- package/src/report/tree.ts +103 -20
- package/src/report/types.ts +196 -25
- package/src/report/web.ts +46 -19
- package/src/results/annotated-source.test.ts +146 -0
- package/src/results/annotated-source.ts +128 -0
- package/src/results/attempt-evidence.test.ts +158 -0
- package/src/results/attempt-evidence.ts +158 -0
- package/src/results/attempt-source.ts +48 -0
- package/src/results/copy.ts +154 -139
- package/src/results/format.ts +54 -47
- package/src/results/host-equivalence.test.ts +527 -0
- package/src/results/index.ts +56 -14
- package/src/results/locator.test.ts +198 -0
- package/src/results/locator.ts +0 -0
- package/src/results/open.ts +392 -175
- package/src/results/results.test.ts +943 -494
- package/src/results/select.ts +129 -23
- package/src/results/skipped-notice.ts +0 -0
- package/src/results/source-hash.ts +28 -0
- package/src/results/types.ts +98 -62
- package/src/results/writer.ts +304 -176
- package/src/runner/attempt.test.ts +170 -0
- package/src/runner/attempt.ts +48 -13
- package/src/runner/discover.test.ts +65 -0
- package/src/runner/discover.ts +6 -2
- package/src/runner/eval-source.test.ts +121 -0
- package/src/runner/eval-source.ts +45 -0
- package/src/runner/fingerprint.ts +54 -1
- package/src/runner/remote-sandbox.ts +1 -1
- package/src/runner/report.test.ts +6 -8
- package/src/runner/report.ts +5 -4
- package/src/runner/reporters/artifacts.ts +27 -41
- package/src/runner/reporters/braintrust.test.ts +3 -3
- package/src/runner/reporters/braintrust.ts +1 -1
- package/src/runner/reporters/console.ts +6 -6
- package/src/runner/reporters/json.ts +4 -4
- package/src/runner/reporters/live.test.ts +56 -0
- package/src/runner/reporters/live.ts +36 -10
- package/src/runner/reporters/quiet.test.ts +66 -0
- package/src/runner/reporters/quiet.ts +49 -0
- package/src/runner/reporters/shared.ts +5 -5
- package/src/runner/reporters/table.ts +17 -17
- package/src/runner/run.ts +61 -102
- package/src/runner/types.ts +43 -32
- package/src/sandbox/checkpoint.ts +1 -1
- package/src/sandbox/docker.ts +15 -2
- package/src/sandbox/e2b.ts +11 -5
- package/src/sandbox/errors.ts +13 -0
- package/src/sandbox/index.ts +3 -3
- package/src/sandbox/local-files.ts +1 -1
- package/src/sandbox/registry.ts +6 -5
- package/src/sandbox/resolve.ts +38 -23
- package/src/sandbox/retry.test.ts +68 -0
- package/src/sandbox/retry.ts +44 -0
- package/src/sandbox/types.ts +24 -24
- package/src/sandbox/vercel.ts +17 -3
- package/src/scoring/collector.ts +3 -3
- package/src/scoring/judge.ts +2 -2
- package/src/scoring/scoped.ts +13 -1
- package/src/scoring/types.ts +7 -7
- package/src/scoring/verdict.ts +4 -4
- package/src/shared/aggregate.ts +23 -3
- package/src/shared/types.ts +2 -2
- package/src/shared/{outcome.ts → verdict.ts} +15 -15
- package/src/show/compose.ts +12 -132
- package/src/show/index.ts +125 -94
- package/src/show/render.ts +660 -160
- package/src/show/show.test.ts +472 -253
- package/src/source-loc.ts +1 -1
- package/src/tty-line.ts +32 -0
- package/src/types.ts +2 -2
- package/src/util.test.ts +21 -1
- package/src/util.ts +5 -1
- package/src/view/app/App.tsx +33 -198
- package/src/view/app/components/AttemptModal.tsx +6 -6
- package/src/view/app/components/CodeView.tsx +2 -2
- package/src/view/app/components/CopyControls.tsx +32 -36
- package/src/view/app/components/SkippedRunsBanner.tsx +140 -0
- package/src/view/app/components/ui/badge.tsx +1 -1
- package/src/view/app/components/ui/dialog.tsx +2 -2
- package/src/view/app/i18n.ts +40 -31
- package/src/view/app/lib/artifact-url.ts +1 -1
- package/src/view/app/lib/attempt-route.test.ts +37 -47
- package/src/view/app/lib/attempt-route.ts +26 -26
- package/src/view/app/lib/rows.ts +9 -112
- package/src/view/app/lib/verdict.ts +25 -0
- package/src/view/app/main.tsx +9 -12
- package/src/view/app/pages/RunsPage.tsx +4 -4
- package/src/view/app/pages/TracesPage.tsx +3 -3
- package/src/view/app/shared.ts +0 -1
- package/src/view/app/types.ts +6 -51
- package/src/view/artifact-serving.test.ts +136 -0
- package/src/view/client-dist/app.css +1 -1
- package/src/view/client-dist/app.js +21 -21
- package/src/view/data.test.ts +214 -143
- package/src/view/data.ts +166 -120
- package/src/view/index.ts +23 -11
- package/src/view/server.ts +52 -17
- package/src/view/shared/types.ts +22 -31
- package/src/view/styles.css +117 -327
- package/src/view/view-report.test.ts +146 -98
- package/src/report/default-report.tsx +0 -222
- package/src/report/dual-face.test.tsx +0 -527
- package/src/report/react/CaseList.tsx +0 -70
- package/src/view/app/components/CostScoreChart.tsx +0 -147
- package/src/view/app/components/ExperimentTable.tsx +0 -284
- package/src/view/app/components/GroupSelector.tsx +0 -61
- package/src/view/app/components/primitives.tsx +0 -43
- package/src/view/app/lib/outcome.ts +0 -82
|
@@ -8,29 +8,35 @@ import { dirname, join } from "node:path";
|
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { renderToStaticMarkup } from "react-dom/server";
|
|
10
10
|
import { describe, expect, it } from "vitest";
|
|
11
|
+
import type { AttemptLocator } from "../../results/locator.ts";
|
|
11
12
|
|
|
12
13
|
import {
|
|
13
|
-
|
|
14
|
+
AttemptList,
|
|
14
15
|
DeltaTable,
|
|
16
|
+
EvalList,
|
|
17
|
+
ExperimentList,
|
|
15
18
|
MetricMatrix,
|
|
16
19
|
MetricScatter,
|
|
17
20
|
MetricTable,
|
|
18
21
|
RunOverview,
|
|
19
22
|
Scoreboard,
|
|
20
23
|
} from "./index.tsx";
|
|
21
|
-
import {
|
|
24
|
+
import { colorClassForKey, seriesClassForKey } from "./colors.ts";
|
|
22
25
|
import {
|
|
23
|
-
|
|
26
|
+
attemptListItems,
|
|
24
27
|
deltaData,
|
|
28
|
+
evalListItems,
|
|
29
|
+
experimentListItems,
|
|
25
30
|
matrixData,
|
|
26
31
|
overviewData,
|
|
27
32
|
overviewWithCost,
|
|
28
33
|
scatterData,
|
|
29
34
|
scoreboardData,
|
|
30
35
|
tableData,
|
|
36
|
+
tableDataWithMeta,
|
|
31
37
|
} from "./fixtures.ts";
|
|
32
38
|
|
|
33
|
-
const attemptHref = (
|
|
39
|
+
const attemptHref = (locator: AttemptLocator) => `/attempts/${locator}`;
|
|
34
40
|
|
|
35
41
|
describe("RunOverview", () => {
|
|
36
42
|
const html = renderToStaticMarkup(<RunOverview data={overviewData} />);
|
|
@@ -39,7 +45,11 @@ describe("RunOverview", () => {
|
|
|
39
45
|
expect(html).toContain("nre-overview");
|
|
40
46
|
expect(html).toContain("<dd>12</dd>"); // 题目
|
|
41
47
|
expect(html).toContain("<dd>48</dd>"); // attempts
|
|
42
|
-
|
|
48
|
+
// totals.passRate.display 原样渲染(两级聚合 70%),不是从 passed/failed/errored
|
|
49
|
+
// 现场重算的 78%(36/(36+8+2))—— 两个数刻意不同,证明组件没有偷懒重算
|
|
50
|
+
expect(html).toContain("70%");
|
|
51
|
+
expect(html).not.toContain("78%");
|
|
52
|
+
expect(html).toContain("46/48"); // samples < total:覆盖率角标(2 个 skipped attempt 不进桶)
|
|
43
53
|
expect(html).toContain("4m 21s"); // 261000ms
|
|
44
54
|
});
|
|
45
55
|
|
|
@@ -88,7 +98,54 @@ describe("MetricTable", () => {
|
|
|
88
98
|
});
|
|
89
99
|
|
|
90
100
|
it("refs + attemptHref 出普通 <a>", () => {
|
|
91
|
-
expect(html).toContain('href="/attempts
|
|
101
|
+
expect(html).toContain('href="/attempts/@1a0a0a0"');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("渐进增强的 data 属性:所有表头 data-nre-sort、格子 data-sort-value(无 JS 时纯属性,内容完整)", () => {
|
|
105
|
+
expect(html.match(/data-nre-sort/g)).toHaveLength(3); // 维度列 + 2 指标列
|
|
106
|
+
expect(html).toContain('data-sort-value="codex"');
|
|
107
|
+
expect(html).toContain('data-sort-value="0.87"');
|
|
108
|
+
// 缺数据格子的排序值为空串:enhance.js 排序时恒沉底
|
|
109
|
+
expect(html).toContain('data-sort-value=""');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe("MetricTable:meta 榜单 parity 与 filter", () => {
|
|
114
|
+
const html = renderToStaticMarkup(<MetricTable data={tableDataWithMeta} />);
|
|
115
|
+
|
|
116
|
+
it("meta 在场补 Model / Agent 列,列序 experiment、model、agent、指标、verdicts", () => {
|
|
117
|
+
expect(html).toContain(">Model</th>");
|
|
118
|
+
expect(html).toContain(">Agent</th>");
|
|
119
|
+
expect(html).toContain(">Verdicts</th>");
|
|
120
|
+
expect(html.indexOf(">Model</th>")).toBeLessThan(html.indexOf(">Agent</th>"));
|
|
121
|
+
expect(html.indexOf(">Agent</th>")).toBeLessThan(html.indexOf("pass rate"));
|
|
122
|
+
expect(html).toContain("gpt-5.4");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("verdict 计票列:eval 级折叠口径的 pill,零计数不出 pill", () => {
|
|
126
|
+
expect(html).toContain("nre-verdict-pill");
|
|
127
|
+
expect(html).toContain("1 passed");
|
|
128
|
+
expect(html).toContain("1 failed");
|
|
129
|
+
expect(html).toContain("2 passed");
|
|
130
|
+
expect(html).not.toContain("0 errored");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("filter 开:表格前渲染 data-nre-filter 输入框(无 JS 静默无功能),仍无 <script>", () => {
|
|
134
|
+
const filtered = renderToStaticMarkup(<MetricTable data={tableDataWithMeta} filter />);
|
|
135
|
+
expect(filtered).toContain("data-nre-filter");
|
|
136
|
+
expect(filtered).toContain('class="nre-filter"');
|
|
137
|
+
expect(filtered.indexOf("nre-filter")).toBeLessThan(filtered.indexOf("<table"));
|
|
138
|
+
expect(filtered).toContain('placeholder="Filter rows…"');
|
|
139
|
+
expect(filtered).not.toContain("<script");
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("locale=zh-CN:chrome 文案与 meta 列头走字典;display 不本地化", () => {
|
|
143
|
+
const zh = renderToStaticMarkup(<MetricTable data={tableDataWithMeta} filter locale="zh-CN" />);
|
|
144
|
+
expect(zh).toContain(">模型</th>");
|
|
145
|
+
expect(zh).toContain(">结果</th>");
|
|
146
|
+
expect(zh).toContain("1 通过");
|
|
147
|
+
expect(zh).toContain('placeholder="筛选行…"');
|
|
148
|
+
expect(zh).toContain("50%"); // display 是 format 产物,不本地化
|
|
92
149
|
});
|
|
93
150
|
});
|
|
94
151
|
|
|
@@ -107,8 +164,8 @@ describe("MetricMatrix", () => {
|
|
|
107
164
|
it("格子数字与 refs 下钻链接", () => {
|
|
108
165
|
expect(html).toContain("100%");
|
|
109
166
|
expect(html).toContain("0%");
|
|
110
|
-
expect(html).toContain('href="/attempts
|
|
111
|
-
expect(html).toContain('href="/attempts
|
|
167
|
+
expect(html).toContain('href="/attempts/@1b3b3b3"');
|
|
168
|
+
expect(html).toContain('href="/attempts/@1b7b7b7"');
|
|
112
169
|
});
|
|
113
170
|
|
|
114
171
|
it("列头(维度键)带稳定散列配色 class", () => {
|
|
@@ -145,13 +202,14 @@ describe("Scoreboard", () => {
|
|
|
145
202
|
describe("MetricScatter", () => {
|
|
146
203
|
const html = renderToStaticMarkup(<MetricScatter data={scatterData} pointHref={(row) => `/exp/${row.key}`} />);
|
|
147
204
|
|
|
205
|
+
// data-key 在点的 <g> 上,坐标在其内第一个 circle 上(非贪婪跨标签匹配)
|
|
148
206
|
const cxOf = (key: string): number => {
|
|
149
|
-
const m = html.match(new RegExp(`data-key="${key}"[
|
|
207
|
+
const m = html.match(new RegExp(`data-key="${key}"[\\s\\S]*?\\bcx="([\\d.]+)"`));
|
|
150
208
|
expect(m, `circle for ${key}`).toBeTruthy();
|
|
151
209
|
return Number(m![1]);
|
|
152
210
|
};
|
|
153
211
|
const cyOf = (key: string): number => {
|
|
154
|
-
const m = html.match(new RegExp(`data-key="${key}"[
|
|
212
|
+
const m = html.match(new RegExp(`data-key="${key}"[\\s\\S]*?\\bcy="([\\d.]+)"`));
|
|
155
213
|
expect(m, `circle for ${key}`).toBeTruthy();
|
|
156
214
|
return Number(m![1]);
|
|
157
215
|
};
|
|
@@ -168,12 +226,21 @@ describe("MetricScatter", () => {
|
|
|
168
226
|
expect(cyOf("compare/bub-high")).toBeLessThan(cyOf("compare/bub-low"));
|
|
169
227
|
});
|
|
170
228
|
|
|
171
|
-
it("
|
|
229
|
+
it("同系列点连线,系列色走类名(nre-series-cN,CSS 上色跟随深浅主题),图例列系列名", () => {
|
|
172
230
|
expect(html).toContain("<polyline");
|
|
173
|
-
expect(html).toContain("
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
231
|
+
expect(html).toContain(`nre-scatter-line ${seriesClassForKey("bub")}`);
|
|
232
|
+
// 渲染面零内联 hex:深色主题下由 CSS 变量切换
|
|
233
|
+
expect(html).not.toMatch(/#[0-9a-f]{6}/i);
|
|
234
|
+
// 图例:codex 只有 1 个可画点、不出线,但系列名仍在图例里
|
|
235
|
+
expect(html).toContain(">bub</span>");
|
|
236
|
+
expect(html).toContain(">codex</span>");
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it("niceTicks 网格与每点直接标签(id 末段)", () => {
|
|
240
|
+
expect(html).toContain("nre-scatter-grid");
|
|
241
|
+
expect(html.match(/nre-scatter-tick/g)!.length).toBeGreaterThanOrEqual(6);
|
|
242
|
+
expect(html).toContain(">bub-low</text>");
|
|
243
|
+
expect(html).toContain(">codex-mid</text>");
|
|
177
244
|
});
|
|
178
245
|
|
|
179
246
|
it("null 点不画,底部注脚如实报数", () => {
|
|
@@ -190,7 +257,7 @@ describe("MetricScatter", () => {
|
|
|
190
257
|
expect(html).toContain('href="/exp/compare/bub-low"');
|
|
191
258
|
});
|
|
192
259
|
|
|
193
|
-
it("
|
|
260
|
+
it("全部点都缺数据时不画空坐标系:显式说明缺哪两个指标", () => {
|
|
194
261
|
const empty = renderToStaticMarkup(
|
|
195
262
|
<MetricScatter
|
|
196
263
|
data={{
|
|
@@ -200,9 +267,23 @@ describe("MetricScatter", () => {
|
|
|
200
267
|
/>,
|
|
201
268
|
);
|
|
202
269
|
expect(empty).not.toContain("<svg");
|
|
203
|
-
expect(empty).toContain("
|
|
270
|
+
expect(empty).toContain("No data to plot"); // 0 可画点:命名 x/y 指标,不画空图
|
|
204
271
|
expect(empty).toContain("4 points missing data");
|
|
205
272
|
});
|
|
273
|
+
|
|
274
|
+
it("恰好 1 个可画点:比较至少要两个实验,不画孤点图", () => {
|
|
275
|
+
const single = renderToStaticMarkup(
|
|
276
|
+
<MetricScatter
|
|
277
|
+
data={{
|
|
278
|
+
...scatterData,
|
|
279
|
+
// 只留第一个点可画,其余 x 置空
|
|
280
|
+
rows: scatterData.rows.map((r, i) => (i === 0 ? r : { ...r, x: { ...r.x, value: null } })),
|
|
281
|
+
}}
|
|
282
|
+
/>,
|
|
283
|
+
);
|
|
284
|
+
expect(single).not.toContain("<svg");
|
|
285
|
+
expect(single).toContain("At least 2 experiments needed to compare");
|
|
286
|
+
});
|
|
206
287
|
});
|
|
207
288
|
|
|
208
289
|
describe("DeltaTable", () => {
|
|
@@ -233,12 +314,16 @@ describe("DeltaTable", () => {
|
|
|
233
314
|
});
|
|
234
315
|
});
|
|
235
316
|
|
|
236
|
-
|
|
237
|
-
|
|
317
|
+
// AttemptList / EvalList / ExperimentList 的公开(报告组件)Props 没有 attemptHref 覆盖口子——
|
|
318
|
+
// 证据室深链恒经 ctx.attemptHref,宿主外直接嵌进 React 应用时退化为默认 `#/attempt/<locator>`
|
|
319
|
+
// (tree.ts 的 DEFAULT_WEB_CONTEXT),不是纯展示、也不发明另一套断链(与 MetricTable 等
|
|
320
|
+
// 可选 attemptHref 的组件不同,这三个组件的下钻不是可选行为)。
|
|
238
321
|
|
|
239
|
-
|
|
322
|
+
describe("AttemptList", () => {
|
|
323
|
+
const html = renderToStaticMarkup(<AttemptList items={attemptListItems} />);
|
|
324
|
+
|
|
325
|
+
it("逐条断言:name、score、detail、evidence", () => {
|
|
240
326
|
expect(html).toContain("roots-correct");
|
|
241
|
-
expect(html).toContain("score 0");
|
|
242
327
|
expect(html).toContain("expected x=2, got x=3");
|
|
243
328
|
expect(html).toContain("judge: sign flipped when substituting into the quadratic formula");
|
|
244
329
|
});
|
|
@@ -247,21 +332,67 @@ describe("CaseList", () => {
|
|
|
247
332
|
expect(html).toContain("TypeError: cannot read properties of undefined");
|
|
248
333
|
});
|
|
249
334
|
|
|
250
|
-
it("
|
|
251
|
-
|
|
335
|
+
it("total > items.length 时如实报「还有 n 条没列」", () => {
|
|
336
|
+
const html2 = renderToStaticMarkup(<AttemptList items={attemptListItems} total={attemptListItems.length + 2} />);
|
|
337
|
+
expect(html2).toContain("and 2 more not shown");
|
|
338
|
+
// 不传 total(或 total === items.length)不产出截断文案
|
|
339
|
+
expect(html).not.toContain("more not shown");
|
|
252
340
|
});
|
|
253
341
|
|
|
254
|
-
it("
|
|
255
|
-
expect(html).toContain('href="
|
|
256
|
-
expect(html).toContain('href="
|
|
342
|
+
it("每条 attempt 带 locator + 默认证据室深链 + 证据能力标记", () => {
|
|
343
|
+
expect(html).toContain('href="#/attempt/@1a4a4a4"');
|
|
344
|
+
expect(html).toContain('href="#/attempt/@1c1c1c1"');
|
|
345
|
+
expect(html).toContain("[E,X,⏱]"); // failedAttempt: eval + execution + timing
|
|
257
346
|
});
|
|
258
347
|
|
|
259
|
-
it("
|
|
348
|
+
it("长文本(evidence)收进 <details>,零 JS 可展开", () => {
|
|
260
349
|
expect(html).toContain("<details");
|
|
261
350
|
expect(html).toContain("<summary>");
|
|
262
351
|
});
|
|
263
352
|
});
|
|
264
353
|
|
|
354
|
+
describe("EvalList", () => {
|
|
355
|
+
const html = renderToStaticMarkup(<EvalList items={evalListItems} />);
|
|
356
|
+
|
|
357
|
+
it("每项一个 experimentId + evalId,判定与分数在场", () => {
|
|
358
|
+
expect(html).toContain("algebra/quadratic");
|
|
359
|
+
expect(html).toContain("geometry/angles");
|
|
360
|
+
expect(html).toContain("compare/bub");
|
|
361
|
+
expect(html).toContain("compare/codex");
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it("展开到这道题的 Attempt(与 AttemptList 同一套 AttemptRow 渲染)", () => {
|
|
365
|
+
expect(html).toContain('href="#/attempt/@1a4a4a4"');
|
|
366
|
+
expect(html).toContain("roots-correct");
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
it("零 JS 靠原生 <details>,静态 HTML 内容已完整", () => {
|
|
370
|
+
expect(html).toContain("<details");
|
|
371
|
+
expect(html).not.toContain("<script");
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
describe("ExperimentList", () => {
|
|
376
|
+
const html = renderToStaticMarkup(<ExperimentList items={experimentListItems} />);
|
|
377
|
+
|
|
378
|
+
it("主行:身份、agent/model、官方两级聚合指标", () => {
|
|
379
|
+
expect(html).toContain("compare/bub");
|
|
380
|
+
expect(html).toContain("compare/codex");
|
|
381
|
+
expect(html).toContain("gpt-5.4");
|
|
382
|
+
expect(html).toContain("50%"); // passRate.display
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it("展开到 Eval:判定符 + 该题 Attempt 的 locator 徽标内联", () => {
|
|
386
|
+
expect(html).toContain("algebra/quadratic");
|
|
387
|
+
expect(html).toContain('href="#/attempt/@1a4a4a4"');
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it("零 JS 靠原生 <details>,无 <script>", () => {
|
|
391
|
+
expect(html).toContain("<details");
|
|
392
|
+
expect(html).not.toContain("<script");
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
|
|
265
396
|
describe("跨组件契约", () => {
|
|
266
397
|
it("同一维度键在所有块里同色(稳定散列,与渲染顺序无关)", () => {
|
|
267
398
|
const cls = colorClassForKey("bub");
|
|
@@ -269,12 +400,12 @@ describe("跨组件契约", () => {
|
|
|
269
400
|
const matrix = renderToStaticMarkup(<MetricMatrix data={matrixData} />);
|
|
270
401
|
const board = renderToStaticMarkup(<Scoreboard data={scoreboardData} />);
|
|
271
402
|
const delta = renderToStaticMarkup(<DeltaTable data={deltaData} />);
|
|
272
|
-
const
|
|
273
|
-
for (const html of [table, matrix, board, delta,
|
|
403
|
+
const attempts = renderToStaticMarkup(<AttemptList items={attemptListItems} />);
|
|
404
|
+
for (const html of [table, matrix, board, delta, attempts]) {
|
|
274
405
|
expect(html).toContain(cls);
|
|
275
406
|
}
|
|
276
407
|
const scatter = renderToStaticMarkup(<MetricScatter data={scatterData} />);
|
|
277
|
-
expect(scatter).toContain(
|
|
408
|
+
expect(scatter).toContain(seriesClassForKey("bub"));
|
|
278
409
|
});
|
|
279
410
|
|
|
280
411
|
it("静态输出不含 <script>:交互只靠 <a>/<details>/CSS", () => {
|
|
@@ -285,7 +416,9 @@ describe("跨组件契约", () => {
|
|
|
285
416
|
renderToStaticMarkup(<Scoreboard data={scoreboardData} />),
|
|
286
417
|
renderToStaticMarkup(<MetricScatter data={scatterData} />),
|
|
287
418
|
renderToStaticMarkup(<DeltaTable data={deltaData} />),
|
|
288
|
-
renderToStaticMarkup(<
|
|
419
|
+
renderToStaticMarkup(<AttemptList items={attemptListItems} />),
|
|
420
|
+
renderToStaticMarkup(<EvalList items={evalListItems} />),
|
|
421
|
+
renderToStaticMarkup(<ExperimentList items={experimentListItems} />),
|
|
289
422
|
].join("");
|
|
290
423
|
expect(all).not.toContain("<script");
|
|
291
424
|
});
|