@benchkit/format 0.1.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.
Files changed (148) hide show
  1. package/README.md +521 -0
  2. package/dist/build-otlp-result.d.ts +43 -0
  3. package/dist/build-otlp-result.d.ts.map +1 -0
  4. package/dist/build-otlp-result.js +102 -0
  5. package/dist/build-otlp-result.js.map +1 -0
  6. package/dist/build-otlp-result.test.d.ts +2 -0
  7. package/dist/build-otlp-result.test.d.ts.map +1 -0
  8. package/dist/build-otlp-result.test.js +148 -0
  9. package/dist/build-otlp-result.test.js.map +1 -0
  10. package/dist/compare.d.ts +20 -0
  11. package/dist/compare.d.ts.map +1 -0
  12. package/dist/compare.js +92 -0
  13. package/dist/compare.js.map +1 -0
  14. package/dist/compare.test.d.ts +2 -0
  15. package/dist/compare.test.d.ts.map +1 -0
  16. package/dist/compare.test.js +233 -0
  17. package/dist/compare.test.js.map +1 -0
  18. package/dist/format-comparison-markdown.d.ts +3 -0
  19. package/dist/format-comparison-markdown.d.ts.map +1 -0
  20. package/dist/format-comparison-markdown.js +142 -0
  21. package/dist/format-comparison-markdown.js.map +1 -0
  22. package/dist/format-comparison-markdown.test.d.ts +2 -0
  23. package/dist/format-comparison-markdown.test.d.ts.map +1 -0
  24. package/dist/format-comparison-markdown.test.js +173 -0
  25. package/dist/format-comparison-markdown.test.js.map +1 -0
  26. package/dist/index.d.ts +38 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +100 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/infer-direction.d.ts +10 -0
  31. package/dist/infer-direction.d.ts.map +1 -0
  32. package/dist/infer-direction.js +23 -0
  33. package/dist/infer-direction.js.map +1 -0
  34. package/dist/infer-direction.test.d.ts +2 -0
  35. package/dist/infer-direction.test.d.ts.map +1 -0
  36. package/dist/infer-direction.test.js +28 -0
  37. package/dist/infer-direction.test.js.map +1 -0
  38. package/dist/metrics-batch.d.ts +55 -0
  39. package/dist/metrics-batch.d.ts.map +1 -0
  40. package/dist/metrics-batch.js +296 -0
  41. package/dist/metrics-batch.js.map +1 -0
  42. package/dist/metrics-batch.test.d.ts +2 -0
  43. package/dist/metrics-batch.test.d.ts.map +1 -0
  44. package/dist/metrics-batch.test.js +306 -0
  45. package/dist/metrics-batch.test.js.map +1 -0
  46. package/dist/native-builder.d.ts.map +1 -0
  47. package/dist/native-builder.js.map +1 -0
  48. package/dist/native-builder.test.d.ts.map +1 -0
  49. package/dist/native-builder.test.js.map +1 -0
  50. package/dist/otlp-conventions.d.ts +80 -0
  51. package/dist/otlp-conventions.d.ts.map +1 -0
  52. package/dist/otlp-conventions.js +114 -0
  53. package/dist/otlp-conventions.js.map +1 -0
  54. package/dist/otlp-conventions.test.d.ts +2 -0
  55. package/dist/otlp-conventions.test.d.ts.map +1 -0
  56. package/dist/otlp-conventions.test.js +65 -0
  57. package/dist/otlp-conventions.test.js.map +1 -0
  58. package/dist/otlp-projections.d.ts.map +1 -0
  59. package/dist/otlp-projections.js.map +1 -0
  60. package/dist/otlp-projections.test.d.ts.map +1 -0
  61. package/dist/otlp-projections.test.js.map +1 -0
  62. package/dist/otlp-validation.d.ts +40 -0
  63. package/dist/otlp-validation.d.ts.map +1 -0
  64. package/dist/otlp-validation.js +110 -0
  65. package/dist/otlp-validation.js.map +1 -0
  66. package/dist/otlp-validation.test.d.ts +2 -0
  67. package/dist/otlp-validation.test.d.ts.map +1 -0
  68. package/dist/otlp-validation.test.js +160 -0
  69. package/dist/otlp-validation.test.js.map +1 -0
  70. package/dist/parse-benchmark-action.d.ts +11 -0
  71. package/dist/parse-benchmark-action.d.ts.map +1 -0
  72. package/dist/parse-benchmark-action.js +54 -0
  73. package/dist/parse-benchmark-action.js.map +1 -0
  74. package/dist/parse-benchmark-action.test.d.ts +2 -0
  75. package/dist/parse-benchmark-action.test.d.ts.map +1 -0
  76. package/dist/parse-benchmark-action.test.js +66 -0
  77. package/dist/parse-benchmark-action.test.js.map +1 -0
  78. package/dist/parse-go.d.ts +12 -0
  79. package/dist/parse-go.d.ts.map +1 -0
  80. package/dist/parse-go.js +63 -0
  81. package/dist/parse-go.js.map +1 -0
  82. package/dist/parse-go.test.d.ts +2 -0
  83. package/dist/parse-go.test.d.ts.map +1 -0
  84. package/dist/parse-go.test.js +110 -0
  85. package/dist/parse-go.test.js.map +1 -0
  86. package/dist/parse-hyperfine.d.ts +3 -0
  87. package/dist/parse-hyperfine.d.ts.map +1 -0
  88. package/dist/parse-hyperfine.js +59 -0
  89. package/dist/parse-hyperfine.js.map +1 -0
  90. package/dist/parse-hyperfine.test.d.ts +2 -0
  91. package/dist/parse-hyperfine.test.d.ts.map +1 -0
  92. package/dist/parse-hyperfine.test.js +64 -0
  93. package/dist/parse-hyperfine.test.js.map +1 -0
  94. package/dist/parse-otlp.d.ts +45 -0
  95. package/dist/parse-otlp.d.ts.map +1 -0
  96. package/dist/parse-otlp.js +92 -0
  97. package/dist/parse-otlp.js.map +1 -0
  98. package/dist/parse-otlp.test.d.ts +2 -0
  99. package/dist/parse-otlp.test.d.ts.map +1 -0
  100. package/dist/parse-otlp.test.js +133 -0
  101. package/dist/parse-otlp.test.js.map +1 -0
  102. package/dist/parse-pytest-benchmark.d.ts +3 -0
  103. package/dist/parse-pytest-benchmark.d.ts.map +1 -0
  104. package/dist/parse-pytest-benchmark.js +72 -0
  105. package/dist/parse-pytest-benchmark.js.map +1 -0
  106. package/dist/parse-pytest-benchmark.test.d.ts +2 -0
  107. package/dist/parse-pytest-benchmark.test.d.ts.map +1 -0
  108. package/dist/parse-pytest-benchmark.test.js +85 -0
  109. package/dist/parse-pytest-benchmark.test.js.map +1 -0
  110. package/dist/parse-rust.d.ts +9 -0
  111. package/dist/parse-rust.d.ts.map +1 -0
  112. package/dist/parse-rust.js +50 -0
  113. package/dist/parse-rust.js.map +1 -0
  114. package/dist/parse-rust.test.d.ts +2 -0
  115. package/dist/parse-rust.test.d.ts.map +1 -0
  116. package/dist/parse-rust.test.js +62 -0
  117. package/dist/parse-rust.test.js.map +1 -0
  118. package/dist/parse.d.ts +7 -0
  119. package/dist/parse.d.ts.map +1 -0
  120. package/dist/parse.js +87 -0
  121. package/dist/parse.js.map +1 -0
  122. package/dist/parse.test.d.ts +2 -0
  123. package/dist/parse.test.d.ts.map +1 -0
  124. package/dist/parse.test.js +171 -0
  125. package/dist/parse.test.js.map +1 -0
  126. package/dist/parser-utils.d.ts +17 -0
  127. package/dist/parser-utils.d.ts.map +1 -0
  128. package/dist/parser-utils.js +29 -0
  129. package/dist/parser-utils.js.map +1 -0
  130. package/dist/parser-utils.test.d.ts +2 -0
  131. package/dist/parser-utils.test.d.ts.map +1 -0
  132. package/dist/parser-utils.test.js +27 -0
  133. package/dist/parser-utils.test.js.map +1 -0
  134. package/dist/retry.d.ts +6 -0
  135. package/dist/retry.d.ts.map +1 -0
  136. package/dist/retry.js +18 -0
  137. package/dist/retry.js.map +1 -0
  138. package/dist/retry.test.d.ts +2 -0
  139. package/dist/retry.test.d.ts.map +1 -0
  140. package/dist/retry.test.js +29 -0
  141. package/dist/retry.test.js.map +1 -0
  142. package/dist/test-otlp-helpers.d.ts.map +1 -0
  143. package/dist/test-otlp-helpers.js.map +1 -0
  144. package/dist/types.d.ts +58 -0
  145. package/dist/types.d.ts.map +1 -0
  146. package/dist/types.js +3 -0
  147. package/dist/types.js.map +1 -0
  148. package/package.json +22 -0
@@ -0,0 +1,148 @@
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 node_test_1 = require("node:test");
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const build_otlp_result_js_1 = require("./build-otlp-result.js");
9
+ const otlp_conventions_js_1 = require("./otlp-conventions.js");
10
+ function findAttr(attrs, key) {
11
+ return attrs.find((a) => a.key === key);
12
+ }
13
+ (0, node_test_1.describe)("buildOtlpResult", () => {
14
+ (0, node_test_1.it)("produces a valid OtlpMetricsDocument with one benchmark", () => {
15
+ const doc = (0, build_otlp_result_js_1.buildOtlpResult)({
16
+ benchmarks: [{
17
+ name: "BenchmarkParse",
18
+ metrics: {
19
+ ns_per_op: { value: 1234, unit: "ns/op", direction: "smaller_is_better" },
20
+ },
21
+ }],
22
+ context: { sourceFormat: "go", runId: "123-1", kind: "code" },
23
+ });
24
+ strict_1.default.equal(doc.resourceMetrics.length, 1);
25
+ const rm = doc.resourceMetrics[0];
26
+ strict_1.default.ok(rm.resource?.attributes);
27
+ // Resource attributes
28
+ const resAttrs = rm.resource.attributes;
29
+ strict_1.default.equal(findAttr(resAttrs, otlp_conventions_js_1.ATTR_RUN_ID)?.value?.stringValue, "123-1");
30
+ strict_1.default.equal(findAttr(resAttrs, otlp_conventions_js_1.ATTR_KIND)?.value?.stringValue, "code");
31
+ strict_1.default.equal(findAttr(resAttrs, otlp_conventions_js_1.ATTR_SOURCE_FORMAT)?.value?.stringValue, "go");
32
+ // Scope metrics
33
+ strict_1.default.equal(rm.scopeMetrics?.length, 1);
34
+ const metrics = rm.scopeMetrics[0].metrics;
35
+ strict_1.default.equal(metrics.length, 1);
36
+ strict_1.default.equal(metrics[0].name, "ns_per_op");
37
+ strict_1.default.equal(metrics[0].unit, "ns/op");
38
+ // Gauge datapoint
39
+ const dp = metrics[0].gauge.dataPoints[0];
40
+ strict_1.default.equal(dp.asInt, "1234");
41
+ strict_1.default.ok(dp.timeUnixNano);
42
+ // Datapoint attributes
43
+ const dpAttrs = dp.attributes;
44
+ strict_1.default.equal(findAttr(dpAttrs, otlp_conventions_js_1.ATTR_SCENARIO)?.value?.stringValue, "BenchmarkParse");
45
+ strict_1.default.equal(findAttr(dpAttrs, otlp_conventions_js_1.ATTR_SERIES)?.value?.stringValue, "BenchmarkParse");
46
+ strict_1.default.equal(findAttr(dpAttrs, otlp_conventions_js_1.ATTR_METRIC_DIRECTION)?.value?.stringValue, "smaller_is_better");
47
+ strict_1.default.equal(findAttr(dpAttrs, otlp_conventions_js_1.ATTR_METRIC_ROLE)?.value?.stringValue, "outcome");
48
+ });
49
+ (0, node_test_1.it)("handles multiple benchmarks with multiple metrics", () => {
50
+ const doc = (0, build_otlp_result_js_1.buildOtlpResult)({
51
+ benchmarks: [
52
+ {
53
+ name: "BenchmarkA",
54
+ metrics: {
55
+ ns_per_op: { value: 100, unit: "ns/op", direction: "smaller_is_better" },
56
+ b_per_op: { value: 64, unit: "B/op", direction: "smaller_is_better" },
57
+ },
58
+ },
59
+ {
60
+ name: "BenchmarkB",
61
+ metrics: {
62
+ ns_per_op: { value: 200, unit: "ns/op", direction: "smaller_is_better" },
63
+ },
64
+ },
65
+ ],
66
+ context: { sourceFormat: "go" },
67
+ });
68
+ const metrics = doc.resourceMetrics[0].scopeMetrics[0].metrics;
69
+ strict_1.default.equal(metrics.length, 3);
70
+ strict_1.default.equal(metrics[0].name, "ns_per_op");
71
+ strict_1.default.equal(metrics[1].name, "b_per_op");
72
+ strict_1.default.equal(metrics[2].name, "ns_per_op");
73
+ // First metric belongs to BenchmarkA
74
+ const dp0 = metrics[0].gauge.dataPoints[0];
75
+ strict_1.default.equal(findAttr(dp0.attributes, otlp_conventions_js_1.ATTR_SCENARIO)?.value?.stringValue, "BenchmarkA");
76
+ // Third metric belongs to BenchmarkB
77
+ const dp2 = metrics[2].gauge.dataPoints[0];
78
+ strict_1.default.equal(findAttr(dp2.attributes, otlp_conventions_js_1.ATTR_SCENARIO)?.value?.stringValue, "BenchmarkB");
79
+ });
80
+ (0, node_test_1.it)("accepts numeric shorthand for metric values", () => {
81
+ const doc = (0, build_otlp_result_js_1.buildOtlpResult)({
82
+ benchmarks: [{
83
+ name: "test",
84
+ metrics: { score: 42 },
85
+ }],
86
+ });
87
+ const dp = doc.resourceMetrics[0].scopeMetrics[0].metrics[0].gauge.dataPoints[0];
88
+ strict_1.default.equal(dp.asInt, "42");
89
+ });
90
+ (0, node_test_1.it)("uses asDouble for non-integer values", () => {
91
+ const doc = (0, build_otlp_result_js_1.buildOtlpResult)({
92
+ benchmarks: [{
93
+ name: "test",
94
+ metrics: { latency: { value: 1.5 } },
95
+ }],
96
+ });
97
+ const dp = doc.resourceMetrics[0].scopeMetrics[0].metrics[0].gauge.dataPoints[0];
98
+ strict_1.default.equal(dp.asDouble, 1.5);
99
+ strict_1.default.equal(dp.asInt, undefined);
100
+ });
101
+ (0, node_test_1.it)("includes tags as datapoint attributes", () => {
102
+ const doc = (0, build_otlp_result_js_1.buildOtlpResult)({
103
+ benchmarks: [{
104
+ name: "BenchmarkParse",
105
+ tags: { procs: "8", variant: "fast" },
106
+ metrics: { ns_per_op: 100 },
107
+ }],
108
+ context: { sourceFormat: "go" },
109
+ });
110
+ const dp = doc.resourceMetrics[0].scopeMetrics[0].metrics[0].gauge.dataPoints[0];
111
+ const attrs = dp.attributes;
112
+ strict_1.default.equal(findAttr(attrs, "procs")?.value?.stringValue, "8");
113
+ strict_1.default.equal(findAttr(attrs, "variant")?.value?.stringValue, "fast");
114
+ });
115
+ (0, node_test_1.it)("includes optional resource attributes when provided", () => {
116
+ const doc = (0, build_otlp_result_js_1.buildOtlpResult)({
117
+ benchmarks: [{ name: "test", metrics: { x: 1 } }],
118
+ context: {
119
+ sourceFormat: "go",
120
+ runId: "run-1",
121
+ kind: "code",
122
+ ref: "refs/heads/main",
123
+ commit: "abc123",
124
+ },
125
+ });
126
+ const attrs = doc.resourceMetrics[0].resource.attributes;
127
+ strict_1.default.equal(findAttr(attrs, otlp_conventions_js_1.ATTR_REF)?.value?.stringValue, "refs/heads/main");
128
+ strict_1.default.equal(findAttr(attrs, otlp_conventions_js_1.ATTR_COMMIT)?.value?.stringValue, "abc123");
129
+ });
130
+ (0, node_test_1.it)("defaults to otlp source format when no context is provided", () => {
131
+ const doc = (0, build_otlp_result_js_1.buildOtlpResult)({
132
+ benchmarks: [{ name: "test", metrics: { x: 1 } }],
133
+ });
134
+ const attrs = doc.resourceMetrics[0].resource.attributes;
135
+ strict_1.default.equal(findAttr(attrs, otlp_conventions_js_1.ATTR_SOURCE_FORMAT)?.value?.stringValue, "otlp");
136
+ });
137
+ (0, node_test_1.it)("omits direction attribute when not specified", () => {
138
+ const doc = (0, build_otlp_result_js_1.buildOtlpResult)({
139
+ benchmarks: [{
140
+ name: "test",
141
+ metrics: { score: { value: 42 } },
142
+ }],
143
+ });
144
+ const dp = doc.resourceMetrics[0].scopeMetrics[0].metrics[0].gauge.dataPoints[0];
145
+ strict_1.default.equal(findAttr(dp.attributes, otlp_conventions_js_1.ATTR_METRIC_DIRECTION), undefined);
146
+ });
147
+ });
148
+ //# sourceMappingURL=build-otlp-result.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-otlp-result.test.js","sourceRoot":"","sources":["../src/build-otlp-result.test.ts"],"names":[],"mappings":";;;;;AAAA,yCAAyC;AACzC,gEAAwC;AACxC,iEAAyD;AAEzD,+DAU+B;AAE/B,SAAS,QAAQ,CAAC,KAAsB,EAAE,GAAW;IACnD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED,IAAA,oBAAQ,EAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAA,cAAE,EAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,GAAG,GAAG,IAAA,sCAAe,EAAC;YAC1B,UAAU,EAAE,CAAC;oBACX,IAAI,EAAE,gBAAgB;oBACtB,OAAO,EAAE;wBACP,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE;qBAC1E;iBACF,CAAC;YACF,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;SAC9D,CAAC,CAAC;QAEH,gBAAM,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5C,MAAM,EAAE,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAClC,gBAAM,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEnC,sBAAsB;QACtB,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAS,CAAC,UAAW,CAAC;QAC1C,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,iCAAW,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QAC3E,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,+BAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QACxE,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,wCAAkB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;QAE/E,gBAAgB;QAChB,gBAAM,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAa,CAAC,CAAC,CAAC,CAAC,OAAQ,CAAC;QAC7C,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChC,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC3C,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAEvC,kBAAkB;QAClB,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAM,CAAC,UAAW,CAAC,CAAC,CAAC,CAAC;QAC5C,gBAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC/B,gBAAM,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;QAE3B,uBAAuB;QACvB,MAAM,OAAO,GAAG,EAAE,CAAC,UAAW,CAAC;QAC/B,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,mCAAa,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,CAAC,CAAC;QACrF,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,iCAAW,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,CAAC,CAAC;QACnF,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,2CAAqB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,mBAAmB,CAAC,CAAC;QAChG,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,sCAAgB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,GAAG,GAAG,IAAA,sCAAe,EAAC;YAC1B,UAAU,EAAE;gBACV;oBACE,IAAI,EAAE,YAAY;oBAClB,OAAO,EAAE;wBACP,SAAS,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE;wBACxE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,EAAE;qBACtE;iBACF;gBACD;oBACE,IAAI,EAAE,YAAY;oBAClB,OAAO,EAAE;wBACP,SAAS,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE;qBACzE;iBACF;aACF;YACD,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;SAChC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAa,CAAC,CAAC,CAAC,CAAC,OAAQ,CAAC;QACjE,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChC,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC3C,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC1C,gBAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAE3C,qCAAqC;QACrC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAM,CAAC,UAAW,CAAC,CAAC,CAAC,CAAC;QAC7C,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAW,EAAE,mCAAa,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;QAEzF,qCAAqC;QACrC,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,KAAM,CAAC,UAAW,CAAC,CAAC,CAAC,CAAC;QAC7C,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAW,EAAE,mCAAa,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,GAAG,GAAG,IAAA,sCAAe,EAAC;YAC1B,UAAU,EAAE,CAAC;oBACX,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;iBACvB,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAa,CAAC,CAAC,CAAC,CAAC,OAAQ,CAAC,CAAC,CAAC,CAAC,KAAM,CAAC,UAAW,CAAC,CAAC,CAAC,CAAC;QACrF,gBAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,GAAG,GAAG,IAAA,sCAAe,EAAC;YAC1B,UAAU,EAAE,CAAC;oBACX,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;iBACrC,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAa,CAAC,CAAC,CAAC,CAAC,OAAQ,CAAC,CAAC,CAAC,CAAC,KAAM,CAAC,UAAW,CAAC,CAAC,CAAC,CAAC;QACrF,gBAAM,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC/B,gBAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,GAAG,GAAG,IAAA,sCAAe,EAAC;YAC1B,UAAU,EAAE,CAAC;oBACX,IAAI,EAAE,gBAAgB;oBACtB,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE;oBACrC,OAAO,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE;iBAC5B,CAAC;YACF,OAAO,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;SAChC,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAa,CAAC,CAAC,CAAC,CAAC,OAAQ,CAAC,CAAC,CAAC,CAAC,KAAM,CAAC,UAAW,CAAC,CAAC,CAAC,CAAC;QACrF,MAAM,KAAK,GAAG,EAAE,CAAC,UAAW,CAAC;QAC7B,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QAChE,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,GAAG,GAAG,IAAA,sCAAe,EAAC;YAC1B,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACjD,OAAO,EAAE;gBACP,YAAY,EAAE,IAAI;gBAClB,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,iBAAiB;gBACtB,MAAM,EAAE,QAAQ;aACjB;SACF,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,QAAS,CAAC,UAAW,CAAC;QAC3D,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,8BAAQ,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAC/E,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,iCAAW,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,GAAG,GAAG,IAAA,sCAAe,EAAC;YAC1B,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;SAClD,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,QAAS,CAAC,UAAW,CAAC;QAC3D,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,wCAAkB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,IAAA,cAAE,EAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,GAAG,GAAG,IAAA,sCAAe,EAAC;YAC1B,UAAU,EAAE,CAAC;oBACX,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;iBAClC,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAa,CAAC,CAAC,CAAC,CAAC,OAAQ,CAAC,CAAC,CAAC,CAAC,KAAM,CAAC,UAAW,CAAC,CAAC,CAAC,CAAC;QACrF,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAW,EAAE,2CAAqB,CAAC,EAAE,SAAS,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { ComparisonResult, ThresholdConfig } from "./types.js";
2
+ import type { MetricsBatch } from "./metrics-batch.js";
3
+ /**
4
+ * Compare a current benchmark run against one or more baseline runs.
5
+ *
6
+ * Baseline values are averaged across the provided runs. For each
7
+ * scenario+metric pair in `current`, the function computes a percentage
8
+ * change and applies the threshold test to classify the result as
9
+ * improved, stable, or regressed.
10
+ *
11
+ * Metrics present in `current` but absent from every baseline are
12
+ * excluded — new metrics have no history to regress against.
13
+ *
14
+ * @param current - MetricsBatch for the current run.
15
+ * @param baseline - One or more baseline MetricsBatch objects to compare against.
16
+ * @param config - Threshold configuration (default: 5 % percentage).
17
+ * @returns A `ComparisonResult` with per-metric entries and an overall regression flag.
18
+ */
19
+ export declare function compareRuns(current: MetricsBatch, baseline: MetricsBatch[], config?: ThresholdConfig): ComparisonResult;
20
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAC;AAIpE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,YAAY,EAAE,EACxB,MAAM,GAAE,eAAmC,GAC1C,gBAAgB,CAkFlB"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compareRuns = compareRuns;
4
+ const infer_direction_js_1 = require("./infer-direction.js");
5
+ const DEFAULT_THRESHOLD = { test: "percentage", threshold: 5 };
6
+ /**
7
+ * Compare a current benchmark run against one or more baseline runs.
8
+ *
9
+ * Baseline values are averaged across the provided runs. For each
10
+ * scenario+metric pair in `current`, the function computes a percentage
11
+ * change and applies the threshold test to classify the result as
12
+ * improved, stable, or regressed.
13
+ *
14
+ * Metrics present in `current` but absent from every baseline are
15
+ * excluded — new metrics have no history to regress against.
16
+ *
17
+ * @param current - MetricsBatch for the current run.
18
+ * @param baseline - One or more baseline MetricsBatch objects to compare against.
19
+ * @param config - Threshold configuration (default: 5 % percentage).
20
+ * @returns A `ComparisonResult` with per-metric entries and an overall regression flag.
21
+ */
22
+ function compareRuns(current, baseline, config = DEFAULT_THRESHOLD) {
23
+ if (baseline.length === 0) {
24
+ return { entries: [], hasRegression: false };
25
+ }
26
+ // Build a lookup: scenario → metric → values[]
27
+ const baselineMap = new Map();
28
+ for (const run of baseline) {
29
+ for (const p of run.points) {
30
+ let metricMap = baselineMap.get(p.scenario);
31
+ if (!metricMap) {
32
+ metricMap = new Map();
33
+ baselineMap.set(p.scenario, metricMap);
34
+ }
35
+ let entry = metricMap.get(p.metric);
36
+ if (!entry) {
37
+ entry = { values: [], point: p };
38
+ metricMap.set(p.metric, entry);
39
+ }
40
+ entry.values.push(p.value);
41
+ }
42
+ }
43
+ const entries = [];
44
+ const warnings = [];
45
+ for (const p of current.points) {
46
+ const baselineMetrics = baselineMap.get(p.scenario);
47
+ if (!baselineMetrics)
48
+ continue;
49
+ const baselineEntry = baselineMetrics.get(p.metric);
50
+ if (!baselineEntry || baselineEntry.values.length === 0)
51
+ continue;
52
+ const baselineAvg = baselineEntry.values.reduce((a, b) => a + b, 0) / baselineEntry.values.length;
53
+ if (baselineAvg === 0) {
54
+ warnings.push(`Skipped metric '${p.metric}' for benchmark '${p.scenario}': baseline mean is zero`);
55
+ continue;
56
+ }
57
+ const direction = p.direction ?? (0, infer_direction_js_1.inferDirection)(p.unit || p.metric);
58
+ const rawChange = ((p.value - baselineAvg) / baselineAvg) * 100;
59
+ const isWorse = direction === "smaller_is_better" ? rawChange > 0 : rawChange < 0;
60
+ const isBetter = direction === "smaller_is_better" ? rawChange < 0 : rawChange > 0;
61
+ const absChange = Math.abs(rawChange);
62
+ let status;
63
+ if (absChange <= config.threshold) {
64
+ status = "stable";
65
+ }
66
+ else if (isWorse) {
67
+ status = "regressed";
68
+ }
69
+ else if (isBetter) {
70
+ status = "improved";
71
+ }
72
+ else {
73
+ status = "stable";
74
+ }
75
+ entries.push({
76
+ benchmark: p.scenario,
77
+ metric: p.metric,
78
+ unit: p.unit || undefined,
79
+ direction,
80
+ baseline: baselineAvg,
81
+ current: p.value,
82
+ percentChange: Math.round(rawChange * 100) / 100,
83
+ status,
84
+ });
85
+ }
86
+ return {
87
+ entries,
88
+ hasRegression: entries.some((e) => e.status === "regressed"),
89
+ ...(warnings.length > 0 ? { warnings } : {}),
90
+ };
91
+ }
92
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":";;AA0BA,kCAsFC;AA3GD,6DAAsD;AAGtD,MAAM,iBAAiB,GAAoB,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAEhF;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,WAAW,CACzB,OAAqB,EACrB,QAAwB,EACxB,SAA0B,iBAAiB;IAE3C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IAC/C,CAAC;IAED,+CAA+C;IAC/C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAiE,CAAC;IAC7F,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAC3B,IAAI,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;gBACtB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;gBACjC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACjC,CAAC;YACD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,eAAe;YAAE,SAAS;QAE/B,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAElE,MAAM,WAAW,GACf,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC;QAEhF,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,QAAQ,CAAC,IAAI,CACX,mBAAmB,CAAC,CAAC,MAAM,oBAAoB,CAAC,CAAC,QAAQ,0BAA0B,CACpF,CAAC;YACF,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GACb,CAAC,CAAC,SAAS,IAAI,IAAA,mCAAc,EAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;QAEpD,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,WAAW,CAAC,GAAG,GAAG,CAAC;QAEhE,MAAM,OAAO,GACX,SAAS,KAAK,mBAAmB,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;QACpE,MAAM,QAAQ,GACZ,SAAS,KAAK,mBAAmB,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;QAEpE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,MAAiC,CAAC;QACtC,IAAI,SAAS,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YAClC,MAAM,GAAG,QAAQ,CAAC;QACpB,CAAC;aAAM,IAAI,OAAO,EAAE,CAAC;YACnB,MAAM,GAAG,WAAW,CAAC;QACvB,CAAC;aAAM,IAAI,QAAQ,EAAE,CAAC;YACpB,MAAM,GAAG,UAAU,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,QAAQ,CAAC;QACpB,CAAC;QAED,OAAO,CAAC,IAAI,CAAC;YACX,SAAS,EAAE,CAAC,CAAC,QAAQ;YACrB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS;YACzB,SAAS;YACT,QAAQ,EAAE,WAAW;YACrB,OAAO,EAAE,CAAC,CAAC,KAAK;YAChB,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,GAAG;YAChD,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,OAAO;QACP,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC;QAC5D,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compare.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.test.d.ts","sourceRoot":"","sources":["../src/compare.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,233 @@
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 node_test_1 = require("node:test");
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const compare_js_1 = require("./compare.js");
9
+ const metrics_batch_js_1 = require("./metrics-batch.js");
10
+ /** Shorthand for building a MetricsBatch from simple entries. */
11
+ function makeBatch(entries) {
12
+ const points = entries.map((e) => ({
13
+ scenario: e.scenario,
14
+ series: "default",
15
+ metric: e.metric,
16
+ value: e.value,
17
+ unit: e.unit ?? "",
18
+ direction: e.direction,
19
+ role: undefined,
20
+ tags: {},
21
+ timestamp: undefined,
22
+ }));
23
+ return metrics_batch_js_1.MetricsBatch.fromPoints(points);
24
+ }
25
+ (0, node_test_1.describe)("compare", () => {
26
+ (0, node_test_1.it)("returns empty result for empty baseline", () => {
27
+ const current = makeBatch([
28
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op" },
29
+ ]);
30
+ const result = (0, compare_js_1.compareRuns)(current, []);
31
+ strict_1.default.deepEqual(result.entries, []);
32
+ strict_1.default.equal(result.hasRegression, false);
33
+ });
34
+ (0, node_test_1.it)("detects regression for smaller_is_better metric", () => {
35
+ const baseline = [
36
+ makeBatch([
37
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op", direction: "smaller_is_better" },
38
+ ]),
39
+ ];
40
+ const current = makeBatch([
41
+ { scenario: "BenchA", metric: "ns_per_op", value: 120, unit: "ns/op", direction: "smaller_is_better" },
42
+ ]);
43
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
44
+ strict_1.default.equal(result.entries.length, 1);
45
+ strict_1.default.equal(result.entries[0].status, "regressed");
46
+ strict_1.default.equal(result.entries[0].percentChange, 20);
47
+ strict_1.default.equal(result.hasRegression, true);
48
+ });
49
+ (0, node_test_1.it)("detects improvement for smaller_is_better metric", () => {
50
+ const baseline = [
51
+ makeBatch([
52
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op", direction: "smaller_is_better" },
53
+ ]),
54
+ ];
55
+ const current = makeBatch([
56
+ { scenario: "BenchA", metric: "ns_per_op", value: 80, unit: "ns/op", direction: "smaller_is_better" },
57
+ ]);
58
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
59
+ strict_1.default.equal(result.entries[0].status, "improved");
60
+ strict_1.default.equal(result.entries[0].percentChange, -20);
61
+ strict_1.default.equal(result.hasRegression, false);
62
+ });
63
+ (0, node_test_1.it)("detects regression for bigger_is_better metric", () => {
64
+ const baseline = [
65
+ makeBatch([
66
+ { scenario: "BenchA", metric: "ops_per_sec", value: 1000, unit: "ops/s", direction: "bigger_is_better" },
67
+ ]),
68
+ ];
69
+ const current = makeBatch([
70
+ { scenario: "BenchA", metric: "ops_per_sec", value: 800, unit: "ops/s", direction: "bigger_is_better" },
71
+ ]);
72
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
73
+ strict_1.default.equal(result.entries[0].status, "regressed");
74
+ strict_1.default.equal(result.entries[0].percentChange, -20);
75
+ strict_1.default.equal(result.hasRegression, true);
76
+ });
77
+ (0, node_test_1.it)("detects improvement for bigger_is_better metric", () => {
78
+ const baseline = [
79
+ makeBatch([
80
+ { scenario: "BenchA", metric: "ops_per_sec", value: 1000, unit: "ops/s", direction: "bigger_is_better" },
81
+ ]),
82
+ ];
83
+ const current = makeBatch([
84
+ { scenario: "BenchA", metric: "ops_per_sec", value: 1200, unit: "ops/s", direction: "bigger_is_better" },
85
+ ]);
86
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
87
+ strict_1.default.equal(result.entries[0].status, "improved");
88
+ strict_1.default.equal(result.entries[0].percentChange, 20);
89
+ strict_1.default.equal(result.hasRegression, false);
90
+ });
91
+ (0, node_test_1.it)("classifies within threshold as stable", () => {
92
+ const baseline = [
93
+ makeBatch([
94
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op", direction: "smaller_is_better" },
95
+ ]),
96
+ ];
97
+ const current = makeBatch([
98
+ { scenario: "BenchA", metric: "ns_per_op", value: 103, unit: "ns/op", direction: "smaller_is_better" },
99
+ ]);
100
+ const result = (0, compare_js_1.compareRuns)(current, baseline, { test: "percentage", threshold: 5 });
101
+ strict_1.default.equal(result.entries[0].status, "stable");
102
+ strict_1.default.equal(result.entries[0].percentChange, 3);
103
+ strict_1.default.equal(result.hasRegression, false);
104
+ });
105
+ (0, node_test_1.it)("skips new benchmarks with no baseline", () => {
106
+ const baseline = [
107
+ makeBatch([
108
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op" },
109
+ ]),
110
+ ];
111
+ const current = makeBatch([
112
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op" },
113
+ { scenario: "BenchNew", metric: "ns_per_op", value: 200, unit: "ns/op" },
114
+ ]);
115
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
116
+ strict_1.default.equal(result.entries.length, 1);
117
+ strict_1.default.equal(result.entries[0].benchmark, "BenchA");
118
+ });
119
+ (0, node_test_1.it)("averages across multiple baseline runs", () => {
120
+ const baseline = [
121
+ makeBatch([
122
+ { scenario: "BenchA", metric: "ns_per_op", value: 90, unit: "ns/op", direction: "smaller_is_better" },
123
+ ]),
124
+ makeBatch([
125
+ { scenario: "BenchA", metric: "ns_per_op", value: 110, unit: "ns/op", direction: "smaller_is_better" },
126
+ ]),
127
+ ];
128
+ const current = makeBatch([
129
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op", direction: "smaller_is_better" },
130
+ ]);
131
+ // baseline avg = 100, current = 100, change = 0%
132
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
133
+ strict_1.default.equal(result.entries[0].baseline, 100);
134
+ strict_1.default.equal(result.entries[0].percentChange, 0);
135
+ strict_1.default.equal(result.entries[0].status, "stable");
136
+ });
137
+ (0, node_test_1.it)("infers direction from unit when not explicit", () => {
138
+ const baseline = [
139
+ makeBatch([
140
+ { scenario: "BenchA", metric: "throughput", value: 1000, unit: "ops/s" },
141
+ ]),
142
+ ];
143
+ const current = makeBatch([
144
+ { scenario: "BenchA", metric: "throughput", value: 800, unit: "ops/s" },
145
+ ]);
146
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
147
+ // ops/s → bigger_is_better; drop from 1000→800 = regressed
148
+ strict_1.default.equal(result.entries[0].direction, "bigger_is_better");
149
+ strict_1.default.equal(result.entries[0].status, "regressed");
150
+ });
151
+ (0, node_test_1.it)("handles multiple benchmarks and metrics", () => {
152
+ const baseline = [
153
+ makeBatch([
154
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op", direction: "smaller_is_better" },
155
+ { scenario: "BenchA", metric: "bytes_per_op", value: 200, unit: "B/op", direction: "smaller_is_better" },
156
+ { scenario: "BenchB", metric: "ns_per_op", value: 500, unit: "ns/op", direction: "smaller_is_better" },
157
+ ]),
158
+ ];
159
+ const current = makeBatch([
160
+ { scenario: "BenchA", metric: "ns_per_op", value: 90, unit: "ns/op", direction: "smaller_is_better" },
161
+ { scenario: "BenchA", metric: "bytes_per_op", value: 250, unit: "B/op", direction: "smaller_is_better" },
162
+ { scenario: "BenchB", metric: "ns_per_op", value: 550, unit: "ns/op", direction: "smaller_is_better" },
163
+ ]);
164
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
165
+ strict_1.default.equal(result.entries.length, 3);
166
+ const benchANs = result.entries.find((e) => e.benchmark === "BenchA" && e.metric === "ns_per_op");
167
+ strict_1.default.equal(benchANs?.status, "improved"); // 100→90 = -10%
168
+ const benchABytes = result.entries.find((e) => e.benchmark === "BenchA" && e.metric === "bytes_per_op");
169
+ strict_1.default.equal(benchABytes?.status, "regressed"); // 200→250 = +25%
170
+ const benchBNs = result.entries.find((e) => e.benchmark === "BenchB" && e.metric === "ns_per_op");
171
+ strict_1.default.equal(benchBNs?.status, "regressed"); // 500→550 = +10%
172
+ strict_1.default.equal(result.hasRegression, true);
173
+ });
174
+ (0, node_test_1.it)("uses custom threshold", () => {
175
+ const baseline = [
176
+ makeBatch([
177
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op", direction: "smaller_is_better" },
178
+ ]),
179
+ ];
180
+ const current = makeBatch([
181
+ { scenario: "BenchA", metric: "ns_per_op", value: 115, unit: "ns/op", direction: "smaller_is_better" },
182
+ ]);
183
+ // 15% change, 20% threshold → stable
184
+ const result = (0, compare_js_1.compareRuns)(current, baseline, { test: "percentage", threshold: 20 });
185
+ strict_1.default.equal(result.entries[0].status, "stable");
186
+ // 15% change, 10% threshold → regressed
187
+ const result2 = (0, compare_js_1.compareRuns)(current, baseline, { test: "percentage", threshold: 10 });
188
+ strict_1.default.equal(result2.entries[0].status, "regressed");
189
+ });
190
+ (0, node_test_1.it)("skips metrics with zero baseline and returns warnings", () => {
191
+ const baseline = [
192
+ makeBatch([
193
+ { scenario: "BenchA", metric: "allocs", value: 0, unit: "allocs/op", direction: "smaller_is_better" },
194
+ ]),
195
+ ];
196
+ const current = makeBatch([
197
+ { scenario: "BenchA", metric: "allocs", value: 5, unit: "allocs/op", direction: "smaller_is_better" },
198
+ ]);
199
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
200
+ strict_1.default.equal(result.entries.length, 0);
201
+ strict_1.default.ok(result.warnings);
202
+ strict_1.default.equal(result.warnings.length, 1);
203
+ strict_1.default.match(result.warnings[0], /allocs/);
204
+ strict_1.default.match(result.warnings[0], /BenchA/);
205
+ strict_1.default.match(result.warnings[0], /baseline mean is zero/);
206
+ });
207
+ (0, node_test_1.it)("omits warnings key when no metrics are skipped", () => {
208
+ const baseline = [
209
+ makeBatch([
210
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op", direction: "smaller_is_better" },
211
+ ]),
212
+ ];
213
+ const current = makeBatch([
214
+ { scenario: "BenchA", metric: "ns_per_op", value: 105, unit: "ns/op", direction: "smaller_is_better" },
215
+ ]);
216
+ const result = (0, compare_js_1.compareRuns)(current, baseline);
217
+ strict_1.default.equal(result.warnings, undefined);
218
+ });
219
+ (0, node_test_1.it)("boundary: exactly at threshold is stable", () => {
220
+ const baseline = [
221
+ makeBatch([
222
+ { scenario: "BenchA", metric: "ns_per_op", value: 100, unit: "ns/op", direction: "smaller_is_better" },
223
+ ]),
224
+ ];
225
+ const current = makeBatch([
226
+ { scenario: "BenchA", metric: "ns_per_op", value: 105, unit: "ns/op", direction: "smaller_is_better" },
227
+ ]);
228
+ // 5% change with 5% threshold → stable (<=)
229
+ const result = (0, compare_js_1.compareRuns)(current, baseline, { test: "percentage", threshold: 5 });
230
+ strict_1.default.equal(result.entries[0].status, "stable");
231
+ });
232
+ });
233
+ //# sourceMappingURL=compare.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.test.js","sourceRoot":"","sources":["../src/compare.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ComparisonResult, FormatComparisonMarkdownOptions } from "./types.js";
2
+ export declare function formatComparisonMarkdown(result: ComparisonResult, options?: FormatComparisonMarkdownOptions): string;
3
+ //# sourceMappingURL=format-comparison-markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-comparison-markdown.d.ts","sourceRoot":"","sources":["../src/format-comparison-markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,+BAA+B,EAChC,MAAM,YAAY,CAAC;AAqGpB,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CA+DR"}