feat(FN-4238): export merger errors from engine and polish workflow results
Exports merger error types from the engine package for use in the dashboard and CLI. Adds tests for the engine barrel exports and fixes workflow results tab styling to align the edit toggle with button styles. Fusion-Task-Id: FN-4238
This commit is contained in:
5
.changeset/fn-4238-export-merger-errors.md
Normal file
5
.changeset/fn-4238-export-merger-errors.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@runfusion/fusion": minor
|
||||
---
|
||||
|
||||
Export `DiffVolumeRegressionError`, `MergeAbortedError`, and `SquashAuditError` from `@fusion/engine` so consumers can use `instanceof` checks without deep-importing.
|
||||
@@ -54,19 +54,13 @@
|
||||
|
||||
.workflow-results-edit-toggle {
|
||||
width: auto;
|
||||
height: calc(var(--space-lg) * 2 - var(--space-xs));
|
||||
padding: 0 calc(var(--space-sm) + var(--space-xs) * 0.5);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--surface);
|
||||
min-height: calc(var(--space-lg) * 2 - var(--space-xs));
|
||||
padding-inline: calc(var(--space-sm) + var(--space-xs) * 0.5);
|
||||
color: var(--text-muted);
|
||||
font-size: calc(var(--space-sm) + var(--space-xs));
|
||||
font-weight: 500;
|
||||
gap: calc(var(--space-xs) + var(--space-xs) * 0.5);
|
||||
}
|
||||
|
||||
.workflow-results-edit-toggle:hover {
|
||||
background: var(--card-hover);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
@@ -229,7 +223,7 @@
|
||||
/* Phase badge base and modifier classes */
|
||||
.phase-badge {
|
||||
margin-inline-start: var(--space-xs);
|
||||
font-size: 11px;
|
||||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
||||
padding: var(--space-xs) var(--space-sm);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
@@ -293,6 +287,7 @@
|
||||
|
||||
.workflow-result-output-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-sm);
|
||||
margin-bottom: var(--space-xs);
|
||||
@@ -307,6 +302,8 @@
|
||||
}
|
||||
|
||||
.workflow-result-output-preview {
|
||||
flex: 1 1 calc(var(--space-2xl) * 6);
|
||||
min-width: 0;
|
||||
font-size: calc(var(--space-sm) + var(--space-xs) * 0.75);
|
||||
color: var(--text-dim);
|
||||
font-style: italic;
|
||||
@@ -504,6 +501,19 @@
|
||||
min-height: calc(var(--space-lg) * 2 + var(--space-xs));
|
||||
}
|
||||
|
||||
.workflow-result-output-header {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.workflow-result-output-preview {
|
||||
flex-basis: 100%;
|
||||
order: 3;
|
||||
}
|
||||
|
||||
.workflow-result-mode-toggle {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.workflow-configured-header {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
@@ -570,7 +570,7 @@ export function WorkflowResultsTab({
|
||||
const editButton = canEdit ? (
|
||||
<button
|
||||
type="button"
|
||||
className="modal-edit-btn workflow-results-edit-toggle"
|
||||
className="btn btn-sm workflow-results-edit-toggle"
|
||||
onClick={() => setIsEditing((prev) => !prev)}
|
||||
data-testid="workflow-steps-edit-toggle"
|
||||
aria-label={isEditing ? "Done editing workflow steps" : "Edit workflow steps"}
|
||||
|
||||
@@ -873,6 +873,17 @@ describe("WorkflowResultsTab", () => {
|
||||
expect(css).toMatch(/\.workflow-output-modal-name\s*\{[^}]*min-width:\s*0;[^}]*overflow-wrap:\s*anywhere;/);
|
||||
});
|
||||
|
||||
it("keeps workflow output header actions visible without hardcoded badge sizing", () => {
|
||||
const baseCss = loadAllAppCssBaseOnly();
|
||||
const allCss = loadAllAppCss();
|
||||
|
||||
expect(baseCss).toMatch(/\.phase-badge\s*\{[^}]*font-size:\s*calc\(var\(--space-sm\) \+ var\(--space-xs\) \* 0\.75\);/);
|
||||
expect(baseCss).toMatch(/\.workflow-result-output-header\s*\{[^}]*flex-wrap:\s*wrap;/);
|
||||
expect(baseCss).toMatch(/\.workflow-result-output-preview\s*\{[^}]*flex:\s*1 1 calc\(var\(--space-2xl\) \* 6\);[^}]*min-width:\s*0;/);
|
||||
expect(allCss).toMatch(/@media \(max-width: 768px\)\s*\{[\s\S]*?\.workflow-result-output-preview\s*\{[^}]*flex-basis:\s*100%;[^}]*order:\s*3;/);
|
||||
expect(allCss).toMatch(/@media \(max-width: 768px\)\s*\{[\s\S]*?\.workflow-result-mode-toggle\s*\{[^}]*margin-left:\s*0;/);
|
||||
});
|
||||
|
||||
it("allows workflow modal controls to wrap on mobile so the close button stays visible", () => {
|
||||
const css = loadAllAppCss();
|
||||
|
||||
|
||||
60
packages/engine/src/__tests__/engine-public-api.test.ts
Normal file
60
packages/engine/src/__tests__/engine-public-api.test.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
BranchConflictError,
|
||||
DiffVolumeRegressionError,
|
||||
MergeAbortedError,
|
||||
SquashAuditError,
|
||||
type SquashAuditFindings,
|
||||
} from "../index.js";
|
||||
|
||||
const emptySquashAuditFindings: SquashAuditFindings = {
|
||||
strategy: "squash",
|
||||
squashSha: "abc12345",
|
||||
parentSha: "def67890",
|
||||
squashSubject: "squash subject",
|
||||
auditTargetLabel: "abc12345",
|
||||
lookback: 30,
|
||||
branchSubjects: [],
|
||||
recentMainSubjects: [],
|
||||
duplicateSubjects: [],
|
||||
touchedFiles: [],
|
||||
touchedFileOverlaps: [],
|
||||
findings: [],
|
||||
issueCount: 0,
|
||||
clean: true,
|
||||
};
|
||||
|
||||
describe("engine public api barrel", () => {
|
||||
it.each([
|
||||
{
|
||||
name: "BranchConflictError",
|
||||
ctor: () => new BranchConflictError({
|
||||
branchName: "task/fn-4238",
|
||||
conflictingWorktreePath: "/tmp/worktree",
|
||||
existingTipSha: "0123456789ab",
|
||||
strandedCommits: [],
|
||||
startPoint: "main",
|
||||
recommendedAction: "Rebase the task branch.",
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "DiffVolumeRegressionError",
|
||||
ctor: () => new DiffVolumeRegressionError([]),
|
||||
},
|
||||
{
|
||||
name: "MergeAbortedError",
|
||||
ctor: () => new MergeAbortedError("merge aborted"),
|
||||
},
|
||||
{
|
||||
name: "SquashAuditError",
|
||||
ctor: () => new SquashAuditError("FN-4238", "abc12345", emptySquashAuditFindings),
|
||||
},
|
||||
])("exports $name from ../index.js", ({ name, ctor }) => {
|
||||
expect(ctor).toBeTypeOf("function");
|
||||
|
||||
const error = ctor();
|
||||
|
||||
expect(error).toBeInstanceOf(Error);
|
||||
expect(error.name).toBe(name);
|
||||
});
|
||||
});
|
||||
@@ -28,6 +28,9 @@ export {
|
||||
dropAutostashBySha,
|
||||
getAutostashDiff,
|
||||
notifyAutostashOrphans,
|
||||
DiffVolumeRegressionError,
|
||||
MergeAbortedError,
|
||||
SquashAuditError,
|
||||
type MergerOptions,
|
||||
type AutostashOrphanRecord,
|
||||
} from "./merger.js";
|
||||
|
||||
Reference in New Issue
Block a user