@flanksource/clicky-ui 0.3.46 → 0.3.48
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/NOTICE.md +11 -0
- package/README.md +49 -0
- package/dist/ai.cjs +13 -8
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.js +7 -2
- package/dist/ai.js.map +1 -1
- package/dist/comments/CommentSidePanel.cjs +10 -4
- package/dist/comments/CommentSidePanel.cjs.map +1 -1
- package/dist/comments/CommentSidePanel.d.ts +2 -0
- package/dist/comments/CommentSidePanel.d.ts.map +1 -1
- package/dist/comments/CommentSidePanel.js +10 -4
- package/dist/comments/CommentSidePanel.js.map +1 -1
- package/dist/comments/CommentThread.cjs +2 -0
- package/dist/comments/CommentThread.cjs.map +1 -1
- package/dist/comments/CommentThread.d.ts +2 -1
- package/dist/comments/CommentThread.d.ts.map +1 -1
- package/dist/comments/CommentThread.js +2 -0
- package/dist/comments/CommentThread.js.map +1 -1
- package/dist/comments/CommentThreadList.cjs +3 -0
- package/dist/comments/CommentThreadList.cjs.map +1 -1
- package/dist/comments/CommentThreadList.d.ts +3 -1
- package/dist/comments/CommentThreadList.d.ts.map +1 -1
- package/dist/comments/CommentThreadList.js +3 -0
- package/dist/comments/CommentThreadList.js.map +1 -1
- package/dist/components/ErrorWrapper.cjs +2 -3
- package/dist/components/ErrorWrapper.cjs.map +1 -1
- package/dist/components/ErrorWrapper.d.ts.map +1 -1
- package/dist/components/ErrorWrapper.js +3 -4
- package/dist/components/ErrorWrapper.js.map +1 -1
- package/dist/data/Clicky.cjs +3 -0
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.js +3 -0
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/CodeLine.cjs +4 -2
- package/dist/data/CodeLine.cjs.map +1 -1
- package/dist/data/CodeLine.d.ts.map +1 -1
- package/dist/data/CodeLine.js +4 -2
- package/dist/data/CodeLine.js.map +1 -1
- package/dist/data/FilterPill.cjs +15 -2
- package/dist/data/FilterPill.cjs.map +1 -1
- package/dist/data/FilterPill.d.ts +1 -1
- package/dist/data/FilterPill.d.ts.map +1 -1
- package/dist/data/FilterPill.js +15 -2
- package/dist/data/FilterPill.js.map +1 -1
- package/dist/data/LogViewer.cjs +27 -8
- package/dist/data/LogViewer.cjs.map +1 -1
- package/dist/data/LogViewer.d.ts +11 -3
- package/dist/data/LogViewer.d.ts.map +1 -1
- package/dist/data/LogViewer.js +27 -8
- package/dist/data/LogViewer.js.map +1 -1
- package/dist/data/Properties.cjs +2 -15
- package/dist/data/Properties.cjs.map +1 -1
- package/dist/data/Properties.d.ts +4 -0
- package/dist/data/Properties.d.ts.map +1 -1
- package/dist/data/Properties.js +2 -15
- package/dist/data/Properties.js.map +1 -1
- package/dist/data/PropertyValue.cjs +37 -0
- package/dist/data/PropertyValue.cjs.map +1 -0
- package/dist/data/PropertyValue.d.ts +6 -0
- package/dist/data/PropertyValue.d.ts.map +1 -0
- package/dist/data/PropertyValue.js +37 -0
- package/dist/data/PropertyValue.js.map +1 -0
- package/dist/data/SymbolBadge.cjs +61 -0
- package/dist/data/SymbolBadge.cjs.map +1 -0
- package/dist/data/SymbolBadge.d.ts +21 -0
- package/dist/data/SymbolBadge.d.ts.map +1 -0
- package/dist/data/SymbolBadge.js +61 -0
- package/dist/data/SymbolBadge.js.map +1 -0
- package/dist/data/Tree.cjs +4 -3
- package/dist/data/Tree.cjs.map +1 -1
- package/dist/data/Tree.d.ts +3 -1
- package/dist/data/Tree.d.ts.map +1 -1
- package/dist/data/Tree.js +4 -3
- package/dist/data/Tree.js.map +1 -1
- package/dist/data/ai/ChatFab.cjs +1 -1
- package/dist/data/ai/ChatFab.cjs.map +1 -1
- package/dist/data/ai/ChatFab.js +1 -1
- package/dist/data/ai/ChatFab.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +106 -171
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts +6 -2
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.header.cjs +104 -0
- package/dist/data/ai/ChatWindow.header.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.header.d.ts +29 -0
- package/dist/data/ai/ChatWindow.header.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.header.js +104 -0
- package/dist/data/ai/ChatWindow.header.js.map +1 -0
- package/dist/data/ai/ChatWindow.js +107 -172
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/ChatWindow.placement.cjs +95 -0
- package/dist/data/ai/ChatWindow.placement.cjs.map +1 -0
- package/dist/data/ai/ChatWindow.placement.d.ts +32 -0
- package/dist/data/ai/ChatWindow.placement.d.ts.map +1 -0
- package/dist/data/ai/ChatWindow.placement.js +95 -0
- package/dist/data/ai/ChatWindow.placement.js.map +1 -0
- package/dist/data/ai/SessionChatComposer.cjs +3 -1
- package/dist/data/ai/SessionChatComposer.cjs.map +1 -1
- package/dist/data/ai/SessionChatComposer.d.ts +4 -1
- package/dist/data/ai/SessionChatComposer.d.ts.map +1 -1
- package/dist/data/ai/SessionChatComposer.js +3 -1
- package/dist/data/ai/SessionChatComposer.js.map +1 -1
- package/dist/data/ai/SessionInspector.cjs +68 -72
- package/dist/data/ai/SessionInspector.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.composer-slot.cjs +8 -0
- package/dist/data/ai/SessionInspector.composer-slot.cjs.map +1 -0
- package/dist/data/ai/SessionInspector.composer-slot.d.ts +9 -0
- package/dist/data/ai/SessionInspector.composer-slot.d.ts.map +1 -0
- package/dist/data/ai/SessionInspector.composer-slot.js +8 -0
- package/dist/data/ai/SessionInspector.composer-slot.js.map +1 -0
- package/dist/data/ai/SessionInspector.d.ts +6 -1
- package/dist/data/ai/SessionInspector.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.js +69 -73
- package/dist/data/ai/SessionInspector.js.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.cjs +41 -42
- package/dist/data/ai/SessionInspector.legacy.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.legacy.js +41 -42
- package/dist/data/ai/SessionInspector.legacy.js.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.cjs +14 -9
- package/dist/data/ai/SessionInspector.remote-view.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.d.ts +6 -2
- package/dist/data/ai/SessionInspector.remote-view.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.remote-view.js +14 -9
- package/dist/data/ai/SessionInspector.remote-view.js.map +1 -1
- package/dist/data/ai/SessionInspector.remote.cjs +84 -16
- package/dist/data/ai/SessionInspector.remote.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.remote.d.ts +42 -7
- package/dist/data/ai/SessionInspector.remote.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.remote.js +86 -18
- package/dist/data/ai/SessionInspector.remote.js.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.cjs +5 -0
- package/dist/data/ai/SessionInspector.transcript.cjs.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.d.ts.map +1 -1
- package/dist/data/ai/SessionInspector.transcript.js +5 -0
- package/dist/data/ai/SessionInspector.transcript.js.map +1 -1
- package/dist/data/ai/SessionTail.cjs +63 -0
- package/dist/data/ai/SessionTail.cjs.map +1 -0
- package/dist/data/ai/SessionTail.d.ts +14 -0
- package/dist/data/ai/SessionTail.d.ts.map +1 -0
- package/dist/data/ai/SessionTail.js +63 -0
- package/dist/data/ai/SessionTail.js.map +1 -0
- package/dist/data/ai/SessionViewer.cjs +10 -3
- package/dist/data/ai/SessionViewer.cjs.map +1 -1
- package/dist/data/ai/SessionViewer.d.ts +7 -1
- package/dist/data/ai/SessionViewer.d.ts.map +1 -1
- package/dist/data/ai/SessionViewer.js +10 -3
- package/dist/data/ai/SessionViewer.js.map +1 -1
- package/dist/data/ai/SessionViewer.unified.d.ts +14 -0
- package/dist/data/ai/SessionViewer.unified.d.ts.map +1 -1
- package/dist/data/ai/index.d.ts +4 -3
- package/dist/data/ai/index.d.ts.map +1 -1
- package/dist/data/ai/use-session-scroll.cjs +30 -6
- package/dist/data/ai/use-session-scroll.cjs.map +1 -1
- package/dist/data/ai/use-session-scroll.d.ts +7 -0
- package/dist/data/ai/use-session-scroll.d.ts.map +1 -1
- package/dist/data/ai/use-session-scroll.js +30 -6
- package/dist/data/ai/use-session-scroll.js.map +1 -1
- package/dist/data/chat/Chat.cjs +1 -1
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.js +1 -1
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.cjs +4 -4
- package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
- package/dist/data/chat/ChatRuntimeToolbar.js +4 -4
- package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
- package/dist/data/chat/PromptInput.cjs +4 -2
- package/dist/data/chat/PromptInput.cjs.map +1 -1
- package/dist/data/chat/PromptInput.d.ts +5 -1
- package/dist/data/chat/PromptInput.d.ts.map +1 -1
- package/dist/data/chat/PromptInput.js +4 -2
- package/dist/data/chat/PromptInput.js.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.cjs +13 -2
- package/dist/data/diagnostics/ErrorDetails.cjs.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.d.ts +3 -1
- package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -1
- package/dist/data/diagnostics/ErrorDetails.js +14 -3
- package/dist/data/diagnostics/ErrorDetails.js.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.cjs +3 -2
- package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
- package/dist/data/diagnostics/FrameSourceWindow.js +3 -2
- package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.cjs +5 -0
- package/dist/data/diagnostics/error-diagnostics.cjs.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.d.ts +1 -0
- package/dist/data/diagnostics/error-diagnostics.d.ts.map +1 -1
- package/dist/data/diagnostics/error-diagnostics.js +6 -1
- package/dist/data/diagnostics/error-diagnostics.js.map +1 -1
- package/dist/data/har/HarPanel.cjs +3 -1
- package/dist/data/har/HarPanel.cjs.map +1 -1
- package/dist/data/har/HarPanel.d.ts +4 -1
- package/dist/data/har/HarPanel.d.ts.map +1 -1
- package/dist/data/har/HarPanel.js +3 -1
- package/dist/data/har/HarPanel.js.map +1 -1
- package/dist/data/test-runner/Expectation.cjs +57 -0
- package/dist/data/test-runner/Expectation.cjs.map +1 -0
- package/dist/data/test-runner/Expectation.d.ts +19 -0
- package/dist/data/test-runner/Expectation.d.ts.map +1 -0
- package/dist/data/test-runner/Expectation.js +57 -0
- package/dist/data/test-runner/Expectation.js.map +1 -0
- package/dist/data/test-runner/MarkIcons.cjs +38 -0
- package/dist/data/test-runner/MarkIcons.cjs.map +1 -0
- package/dist/data/test-runner/MarkIcons.d.ts +15 -0
- package/dist/data/test-runner/MarkIcons.d.ts.map +1 -0
- package/dist/data/test-runner/MarkIcons.js +38 -0
- package/dist/data/test-runner/MarkIcons.js.map +1 -0
- package/dist/data/test-runner/TestDetailPanel.cjs +99 -53
- package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -1
- package/dist/data/test-runner/TestDetailPanel.js +101 -55
- package/dist/data/test-runner/TestDetailPanel.js.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.cjs +23 -27
- package/dist/data/test-runner/TestFailureDetail.cjs.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.d.ts +2 -2
- package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -1
- package/dist/data/test-runner/TestFailureDetail.js +23 -27
- package/dist/data/test-runner/TestFailureDetail.js.map +1 -1
- package/dist/data/test-runner/TestFilterBar.cjs +87 -93
- package/dist/data/test-runner/TestFilterBar.cjs.map +1 -1
- package/dist/data/test-runner/TestFilterBar.d.ts +3 -2
- package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -1
- package/dist/data/test-runner/TestFilterBar.js +89 -95
- package/dist/data/test-runner/TestFilterBar.js.map +1 -1
- package/dist/data/test-runner/TestRunSummary.cjs +35 -21
- package/dist/data/test-runner/TestRunSummary.cjs.map +1 -1
- package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunSummary.js +35 -21
- package/dist/data/test-runner/TestRunSummary.js.map +1 -1
- package/dist/data/test-runner/TestRunner.cjs +58 -30
- package/dist/data/test-runner/TestRunner.cjs.map +1 -1
- package/dist/data/test-runner/TestRunner.d.ts +6 -3
- package/dist/data/test-runner/TestRunner.d.ts.map +1 -1
- package/dist/data/test-runner/TestRunner.js +58 -30
- package/dist/data/test-runner/TestRunner.js.map +1 -1
- package/dist/data/test-runner/TestTree.cjs +5 -2
- package/dist/data/test-runner/TestTree.cjs.map +1 -1
- package/dist/data/test-runner/TestTree.d.ts +5 -2
- package/dist/data/test-runner/TestTree.d.ts.map +1 -1
- package/dist/data/test-runner/TestTree.js +5 -2
- package/dist/data/test-runner/TestTree.js.map +1 -1
- package/dist/data/test-runner/TestTreeNode.cjs +28 -19
- package/dist/data/test-runner/TestTreeNode.cjs.map +1 -1
- package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -1
- package/dist/data/test-runner/TestTreeNode.js +29 -20
- package/dist/data/test-runner/TestTreeNode.js.map +1 -1
- package/dist/data/test-runner/adapter.cjs +15 -0
- package/dist/data/test-runner/adapter.cjs.map +1 -1
- package/dist/data/test-runner/adapter.d.ts +27 -7
- package/dist/data/test-runner/adapter.d.ts.map +1 -1
- package/dist/data/test-runner/adapter.js +15 -0
- package/dist/data/test-runner/adapter.js.map +1 -1
- package/dist/data/test-runner/context.cjs.map +1 -1
- package/dist/data/test-runner/context.d.ts +2 -0
- package/dist/data/test-runner/context.d.ts.map +1 -1
- package/dist/data/test-runner/context.js.map +1 -1
- package/dist/data/test-runner/copy.cjs +114 -0
- package/dist/data/test-runner/copy.cjs.map +1 -0
- package/dist/data/test-runner/copy.d.ts +47 -0
- package/dist/data/test-runner/copy.d.ts.map +1 -0
- package/dist/data/test-runner/copy.js +114 -0
- package/dist/data/test-runner/copy.js.map +1 -0
- package/dist/data/test-runner/index.d.ts +6 -3
- package/dist/data/test-runner/index.d.ts.map +1 -1
- package/dist/data/test-runner/marks.cjs +184 -0
- package/dist/data/test-runner/marks.cjs.map +1 -0
- package/dist/data/test-runner/marks.d.ts +40 -0
- package/dist/data/test-runner/marks.d.ts.map +1 -0
- package/dist/data/test-runner/marks.js +184 -0
- package/dist/data/test-runner/marks.js.map +1 -0
- package/dist/data/test-runner/status.cjs +27 -44
- package/dist/data/test-runner/status.cjs.map +1 -1
- package/dist/data/test-runner/status.d.ts +12 -3
- package/dist/data/test-runner/status.d.ts.map +1 -1
- package/dist/data/test-runner/status.js +27 -44
- package/dist/data/test-runner/status.js.map +1 -1
- package/dist/data/traces/TerminalCastPlayer.d.ts +21 -0
- package/dist/data/traces/TerminalCastPlayer.d.ts.map +1 -0
- package/dist/data/traces/TraceHarView.d.ts +13 -0
- package/dist/data/traces/TraceHarView.d.ts.map +1 -0
- package/dist/data/traces/cast.d.ts +9 -0
- package/dist/data/traces/cast.d.ts.map +1 -0
- package/dist/data/traces/fixtures.d.ts +8 -0
- package/dist/data/traces/fixtures.d.ts.map +1 -0
- package/dist/data/traces/har-adapter.d.ts +13 -0
- package/dist/data/traces/har-adapter.d.ts.map +1 -0
- package/dist/data/traces/terminal-screen.d.ts +45 -0
- package/dist/data/traces/terminal-screen.d.ts.map +1 -0
- package/dist/data/traces/terminal-timeline.d.ts +26 -0
- package/dist/data/traces/terminal-timeline.d.ts.map +1 -0
- package/dist/data/traces/types.d.ts +141 -0
- package/dist/data/traces/types.d.ts.map +1 -0
- package/dist/data/verification/VerificationResults.cjs +4 -0
- package/dist/data/verification/VerificationResults.cjs.map +1 -1
- package/dist/data/verification/VerificationResults.d.ts +3 -1
- package/dist/data/verification/VerificationResults.d.ts.map +1 -1
- package/dist/data/verification/VerificationResults.js +4 -0
- package/dist/data/verification/VerificationResults.js.map +1 -1
- package/dist/data/verification/adapterViews.cjs +28 -44
- package/dist/data/verification/adapterViews.cjs.map +1 -1
- package/dist/data/verification/adapterViews.d.ts +4 -1
- package/dist/data/verification/adapterViews.d.ts.map +1 -1
- package/dist/data/verification/adapterViews.js +28 -44
- package/dist/data/verification/adapterViews.js.map +1 -1
- package/dist/data/verification/adapters.cjs +163 -8
- package/dist/data/verification/adapters.cjs.map +1 -1
- package/dist/data/verification/adapters.d.ts +7 -1
- package/dist/data/verification/adapters.d.ts.map +1 -1
- package/dist/data/verification/adapters.js +163 -8
- package/dist/data/verification/adapters.js.map +1 -1
- package/dist/data/verification/index.d.ts +4 -2
- package/dist/data/verification/index.d.ts.map +1 -1
- package/dist/data/verification/stepKind.cjs +217 -0
- package/dist/data/verification/stepKind.cjs.map +1 -0
- package/dist/data/verification/stepKind.d.ts +87 -0
- package/dist/data/verification/stepKind.d.ts.map +1 -0
- package/dist/data/verification/stepKind.js +217 -0
- package/dist/data/verification/stepKind.js.map +1 -0
- package/dist/data/verification/stepKindViews.cjs +111 -0
- package/dist/data/verification/stepKindViews.cjs.map +1 -0
- package/dist/data/verification/stepKindViews.d.ts +18 -0
- package/dist/data/verification/stepKindViews.d.ts.map +1 -0
- package/dist/data/verification/stepKindViews.js +111 -0
- package/dist/data/verification/stepKindViews.js.map +1 -0
- package/dist/data/verification/verifyReportTests.cjs +1 -0
- package/dist/data/verification/verifyReportTests.cjs.map +1 -1
- package/dist/data/verification/verifyReportTests.d.ts +2 -1
- package/dist/data/verification/verifyReportTests.d.ts.map +1 -1
- package/dist/data/verification/verifyReportTests.js +1 -0
- package/dist/data/verification/verifyReportTests.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +58 -3
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +3 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +60 -5
- package/dist/data.js.map +1 -1
- package/dist/icons/components/UiLogoEslint.cjs +10 -0
- package/dist/icons/components/UiLogoEslint.cjs.map +1 -0
- package/dist/icons/components/UiLogoEslint.d.ts +9 -0
- package/dist/icons/components/UiLogoEslint.d.ts.map +1 -0
- package/dist/icons/components/UiLogoEslint.js +10 -0
- package/dist/icons/components/UiLogoEslint.js.map +1 -0
- package/dist/icons/components/UiLogoGo.cjs +10 -0
- package/dist/icons/components/UiLogoGo.cjs.map +1 -0
- package/dist/icons/components/UiLogoGo.d.ts +9 -0
- package/dist/icons/components/UiLogoGo.d.ts.map +1 -0
- package/dist/icons/components/UiLogoGo.js +10 -0
- package/dist/icons/components/UiLogoGo.js.map +1 -0
- package/dist/icons/components/UiLogoJest.cjs +10 -0
- package/dist/icons/components/UiLogoJest.cjs.map +1 -0
- package/dist/icons/components/UiLogoJest.d.ts +9 -0
- package/dist/icons/components/UiLogoJest.d.ts.map +1 -0
- package/dist/icons/components/UiLogoJest.js +10 -0
- package/dist/icons/components/UiLogoJest.js.map +1 -0
- package/dist/icons/components/UiLogoMarkdown.cjs +10 -0
- package/dist/icons/components/UiLogoMarkdown.cjs.map +1 -0
- package/dist/icons/components/UiLogoMarkdown.d.ts +9 -0
- package/dist/icons/components/UiLogoMarkdown.d.ts.map +1 -0
- package/dist/icons/components/UiLogoMarkdown.js +10 -0
- package/dist/icons/components/UiLogoMarkdown.js.map +1 -0
- package/dist/icons/components/UiLogoOxc.cjs +10 -0
- package/dist/icons/components/UiLogoOxc.cjs.map +1 -0
- package/dist/icons/components/UiLogoOxc.d.ts +9 -0
- package/dist/icons/components/UiLogoOxc.d.ts.map +1 -0
- package/dist/icons/components/UiLogoOxc.js +10 -0
- package/dist/icons/components/UiLogoOxc.js.map +1 -0
- package/dist/icons/components/UiLogoPlaywright.cjs +10 -0
- package/dist/icons/components/UiLogoPlaywright.cjs.map +1 -0
- package/dist/icons/components/UiLogoPlaywright.d.ts +9 -0
- package/dist/icons/components/UiLogoPlaywright.d.ts.map +1 -0
- package/dist/icons/components/UiLogoPlaywright.js +10 -0
- package/dist/icons/components/UiLogoPlaywright.js.map +1 -0
- package/dist/icons/components/UiLogoPython.cjs +10 -0
- package/dist/icons/components/UiLogoPython.cjs.map +1 -0
- package/dist/icons/components/UiLogoPython.d.ts +9 -0
- package/dist/icons/components/UiLogoPython.d.ts.map +1 -0
- package/dist/icons/components/UiLogoPython.js +10 -0
- package/dist/icons/components/UiLogoPython.js.map +1 -0
- package/dist/icons/components/UiLogoReact.cjs +10 -0
- package/dist/icons/components/UiLogoReact.cjs.map +1 -0
- package/dist/icons/components/UiLogoReact.d.ts +9 -0
- package/dist/icons/components/UiLogoReact.d.ts.map +1 -0
- package/dist/icons/components/UiLogoReact.js +10 -0
- package/dist/icons/components/UiLogoReact.js.map +1 -0
- package/dist/icons/components/UiLogoRuff.cjs +10 -0
- package/dist/icons/components/UiLogoRuff.cjs.map +1 -0
- package/dist/icons/components/UiLogoRuff.d.ts +9 -0
- package/dist/icons/components/UiLogoRuff.d.ts.map +1 -0
- package/dist/icons/components/UiLogoRuff.js +10 -0
- package/dist/icons/components/UiLogoRuff.js.map +1 -0
- package/dist/icons/components/UiLogoTypescript.cjs +10 -0
- package/dist/icons/components/UiLogoTypescript.cjs.map +1 -0
- package/dist/icons/components/UiLogoTypescript.d.ts +9 -0
- package/dist/icons/components/UiLogoTypescript.d.ts.map +1 -0
- package/dist/icons/components/UiLogoTypescript.js +10 -0
- package/dist/icons/components/UiLogoTypescript.js.map +1 -0
- package/dist/icons/components/UiLogoVitest.cjs +10 -0
- package/dist/icons/components/UiLogoVitest.cjs.map +1 -0
- package/dist/icons/components/UiLogoVitest.d.ts +9 -0
- package/dist/icons/components/UiLogoVitest.d.ts.map +1 -0
- package/dist/icons/components/UiLogoVitest.js +10 -0
- package/dist/icons/components/UiLogoVitest.js.map +1 -0
- package/dist/icons/index.d.ts +11 -0
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/registry.cjs +22 -0
- package/dist/icons/registry.cjs.map +1 -1
- package/dist/icons/registry.d.ts.map +1 -1
- package/dist/icons/registry.js +22 -0
- package/dist/icons/registry.js.map +1 -1
- package/dist/icons.cjs +22 -0
- package/dist/icons.cjs.map +1 -1
- package/dist/icons.js +22 -0
- package/dist/icons.js.map +1 -1
- package/dist/index.cjs +60 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +62 -5
- package/dist/index.js.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.cjs +4 -4
- package/dist/overlay/DropdownMenuSubmenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenuSubmenu.js +4 -4
- package/dist/overlay/DropdownMenuSubmenu.js.map +1 -1
- package/dist/rpc/FilterForm.cjs +9 -0
- package/dist/rpc/FilterForm.cjs.map +1 -1
- package/dist/rpc/FilterForm.d.ts +5 -1
- package/dist/rpc/FilterForm.d.ts.map +1 -1
- package/dist/rpc/FilterForm.js +9 -0
- package/dist/rpc/FilterForm.js.map +1 -1
- package/dist/rpc/InlineError.cjs +12 -43
- package/dist/rpc/InlineError.cjs.map +1 -1
- package/dist/rpc/InlineError.d.ts.map +1 -1
- package/dist/rpc/InlineError.js +13 -44
- package/dist/rpc/InlineError.js.map +1 -1
- package/dist/rpc/OperationArgsForm.cjs +153 -0
- package/dist/rpc/OperationArgsForm.cjs.map +1 -0
- package/dist/rpc/OperationArgsForm.d.ts +16 -0
- package/dist/rpc/OperationArgsForm.d.ts.map +1 -0
- package/dist/rpc/OperationArgsForm.js +153 -0
- package/dist/rpc/OperationArgsForm.js.map +1 -0
- package/dist/rpc/OperationScheduleDialog.cjs +119 -22
- package/dist/rpc/OperationScheduleDialog.cjs.map +1 -1
- package/dist/rpc/OperationScheduleDialog.d.ts +7 -0
- package/dist/rpc/OperationScheduleDialog.d.ts.map +1 -1
- package/dist/rpc/OperationScheduleDialog.js +120 -23
- package/dist/rpc/OperationScheduleDialog.js.map +1 -1
- package/dist/rpc/OperationSchedules.cjs +17 -2
- package/dist/rpc/OperationSchedules.cjs.map +1 -1
- package/dist/rpc/OperationSchedules.d.ts.map +1 -1
- package/dist/rpc/OperationSchedules.js +17 -2
- package/dist/rpc/OperationSchedules.js.map +1 -1
- package/dist/rpc/operation-schedule-model.cjs +2 -7
- package/dist/rpc/operation-schedule-model.cjs.map +1 -1
- package/dist/rpc/operation-schedule-model.d.ts +0 -2
- package/dist/rpc/operation-schedule-model.d.ts.map +1 -1
- package/dist/rpc/operation-schedule-model.js +2 -7
- package/dist/rpc/operation-schedule-model.js.map +1 -1
- package/dist/rpc/operation-schedule-types.d.ts +12 -1
- package/dist/rpc/operation-schedule-types.d.ts.map +1 -1
- package/dist/rpc.cjs +2 -0
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +1 -0
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -0
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/data/test-runner/frameworkIcon.cjs +0 -27
- package/dist/data/test-runner/frameworkIcon.cjs.map +0 -1
- package/dist/data/test-runner/frameworkIcon.d.ts +0 -3
- package/dist/data/test-runner/frameworkIcon.d.ts.map +0 -1
- package/dist/data/test-runner/frameworkIcon.js +0 -27
- package/dist/data/test-runner/frameworkIcon.js.map +0 -1
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { STATUS_LABELS } from "./status.js";
|
|
2
|
+
import { UiInfo } from "../../icons/components/UiInfo.js";
|
|
3
|
+
import { UiWarningTriangle } from "../../icons/components/UiWarningTriangle.js";
|
|
4
|
+
import { UiCircleX } from "../../icons/components/UiCircleX.js";
|
|
5
|
+
import { UiLoader } from "../../icons/components/UiLoader.js";
|
|
6
|
+
import { UiCircleOutline } from "../../icons/components/UiCircleOutline.js";
|
|
7
|
+
import { UiSkipForward } from "../../icons/components/UiSkipForward.js";
|
|
8
|
+
import { UiPass } from "../../icons/components/UiPass.js";
|
|
9
|
+
import { UiTimer } from "../../icons/components/UiTimer.js";
|
|
10
|
+
import { UiProhibit } from "../../icons/components/UiProhibit.js";
|
|
11
|
+
import { UiLogoReact } from "../../icons/components/UiLogoReact.js";
|
|
12
|
+
import { UiCopy } from "../../icons/components/UiCopy.js";
|
|
13
|
+
import { UiKey } from "../../icons/components/UiKey.js";
|
|
14
|
+
import { UiLogoRuff } from "../../icons/components/UiLogoRuff.js";
|
|
15
|
+
import { UiLogoPython } from "../../icons/components/UiLogoPython.js";
|
|
16
|
+
import { UiLogoMarkdown } from "../../icons/components/UiLogoMarkdown.js";
|
|
17
|
+
import { UiLogoTypescript } from "../../icons/components/UiLogoTypescript.js";
|
|
18
|
+
import { UiLogoOxc } from "../../icons/components/UiLogoOxc.js";
|
|
19
|
+
import { UiLogoEslint } from "../../icons/components/UiLogoEslint.js";
|
|
20
|
+
import { UiLogoGo } from "../../icons/components/UiLogoGo.js";
|
|
21
|
+
import { UiSealCheck } from "../../icons/components/UiSealCheck.js";
|
|
22
|
+
import { UiCursorClick } from "../../icons/components/UiCursorClick.js";
|
|
23
|
+
import { UiLogoPlaywright } from "../../icons/components/UiLogoPlaywright.js";
|
|
24
|
+
import { UiGlobe } from "../../icons/components/UiGlobe.js";
|
|
25
|
+
import { UiRobotAi } from "../../icons/components/UiRobotAi.js";
|
|
26
|
+
import { UiChatDots } from "../../icons/components/UiChatDots.js";
|
|
27
|
+
import { UiClipboardText } from "../../icons/components/UiClipboardText.js";
|
|
28
|
+
import { UiServer } from "../../icons/components/UiServer.js";
|
|
29
|
+
import { UiDatabase } from "../../icons/components/UiDatabase.js";
|
|
30
|
+
import { UiSparkles } from "../../icons/components/UiSparkles.js";
|
|
31
|
+
import { UiListChecks } from "../../icons/components/UiListChecks.js";
|
|
32
|
+
import { UiBeaker } from "../../icons/components/UiBeaker.js";
|
|
33
|
+
import { UiTerminal } from "../../icons/components/UiTerminal.js";
|
|
34
|
+
import { UiLogoJest } from "../../icons/components/UiLogoJest.js";
|
|
35
|
+
import { UiLogoVitest } from "../../icons/components/UiLogoVitest.js";
|
|
36
|
+
const LABEL = Object.fromEntries(STATUS_LABELS.map((s) => [s.key, s.label]));
|
|
37
|
+
const RED = "text-red-600 dark:text-red-400";
|
|
38
|
+
const AMBER = "text-amber-600 dark:text-amber-400";
|
|
39
|
+
const TEST_OUTCOMES = {
|
|
40
|
+
failed: { icon: UiCircleX, label: LABEL.failed, className: RED },
|
|
41
|
+
errored: { icon: UiProhibit, label: "Could not run", className: RED },
|
|
42
|
+
timedout: { icon: UiTimer, label: LABEL.timedout, className: AMBER },
|
|
43
|
+
warned: { icon: UiWarningTriangle, label: LABEL.warned, className: AMBER },
|
|
44
|
+
passed: {
|
|
45
|
+
icon: UiPass,
|
|
46
|
+
label: LABEL.passed,
|
|
47
|
+
className: "text-emerald-600 dark:text-emerald-400"
|
|
48
|
+
},
|
|
49
|
+
skipped: { icon: UiSkipForward, label: LABEL.skipped, className: "text-slate-500" },
|
|
50
|
+
pending: {
|
|
51
|
+
icon: UiCircleOutline,
|
|
52
|
+
label: LABEL.pending,
|
|
53
|
+
className: "text-slate-400 dark:text-slate-500"
|
|
54
|
+
},
|
|
55
|
+
running: {
|
|
56
|
+
icon: UiLoader,
|
|
57
|
+
label: LABEL.running,
|
|
58
|
+
className: "text-blue-600 dark:text-blue-400",
|
|
59
|
+
spin: true
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const LINT_SEVERITIES = {
|
|
63
|
+
error: { ...TEST_OUTCOMES.failed, label: "Error" },
|
|
64
|
+
warning: { ...TEST_OUTCOMES.warned, label: "Warning" },
|
|
65
|
+
info: { icon: UiInfo, label: "Info", className: "text-sky-600 dark:text-sky-400" }
|
|
66
|
+
};
|
|
67
|
+
const GO = "text-[#00add8]";
|
|
68
|
+
const MARKDOWN = "text-foreground";
|
|
69
|
+
const MUTED = "text-muted-foreground";
|
|
70
|
+
const TEST_TOOLS = {
|
|
71
|
+
"go test": { icon: UiLogoGo, label: "go test", kind: "test", className: GO },
|
|
72
|
+
ginkgo: { icon: UiLogoGo, label: "Ginkgo", kind: "test", className: GO },
|
|
73
|
+
vitest: { icon: UiLogoVitest, label: "Vitest", kind: "test", className: "text-[#6e9f18]" },
|
|
74
|
+
jest: { icon: UiLogoJest, label: "Jest", kind: "test", className: "text-[#c21325] dark:text-[#e5576a]" },
|
|
75
|
+
playwright: {
|
|
76
|
+
icon: UiLogoPlaywright,
|
|
77
|
+
label: "Playwright",
|
|
78
|
+
kind: "test",
|
|
79
|
+
className: "text-[#2ead33]"
|
|
80
|
+
},
|
|
81
|
+
fixture: { icon: UiLogoMarkdown, label: "Markdown fixture", kind: "test", className: MARKDOWN },
|
|
82
|
+
task: { icon: UiTerminal, label: "Task", kind: "runner", className: MUTED },
|
|
83
|
+
// Fixture step types (gavel fixtures FixtureResult.Type) and the
|
|
84
|
+
// "checklist" node verifyReportTests synthesizes for acceptance criteria.
|
|
85
|
+
exec: { icon: UiTerminal, label: "Command", kind: "fixture", className: MUTED },
|
|
86
|
+
test: { icon: UiBeaker, label: "Test step", kind: "fixture", className: MUTED },
|
|
87
|
+
lint: { icon: UiListChecks, label: "Lint step", kind: "fixture", className: MUTED },
|
|
88
|
+
verify: {
|
|
89
|
+
icon: UiSparkles,
|
|
90
|
+
label: "AI review",
|
|
91
|
+
kind: "fixture",
|
|
92
|
+
className: "text-violet-600 dark:text-violet-400"
|
|
93
|
+
},
|
|
94
|
+
query: { icon: UiDatabase, label: "Query", kind: "fixture", className: MUTED },
|
|
95
|
+
// Typed step kinds (gavel fixtures/kind registry): the node's `framework`
|
|
96
|
+
// is the kind name. `ai` is the runner behind `verify` but is a prompt/CEL
|
|
97
|
+
// round-trip rather than an acceptance-criteria review, so it takes the
|
|
98
|
+
// same violet family with its own glyph and label.
|
|
99
|
+
services: { icon: UiServer, label: "Services", kind: "fixture", className: MUTED },
|
|
100
|
+
todo: { icon: UiClipboardText, label: "TODO step", kind: "fixture", className: MUTED },
|
|
101
|
+
todo_prompt: { icon: UiChatDots, label: "TODO prompt run", kind: "fixture", className: MUTED },
|
|
102
|
+
ai: {
|
|
103
|
+
icon: UiRobotAi,
|
|
104
|
+
label: "AI step",
|
|
105
|
+
kind: "fixture",
|
|
106
|
+
className: "text-violet-600 dark:text-violet-400"
|
|
107
|
+
},
|
|
108
|
+
browser: { icon: UiGlobe, label: "Browser", kind: "fixture", className: MUTED },
|
|
109
|
+
// The fixture-step twin of the `playwright` test framework above; both
|
|
110
|
+
// arrive as framework "playwright", so toolKeyFor() picks this key when the
|
|
111
|
+
// node carries `detail.step`. Muted like every other fixture step, so the
|
|
112
|
+
// brand green stays on the spec results the framework reports.
|
|
113
|
+
"playwright-step": {
|
|
114
|
+
icon: UiLogoPlaywright,
|
|
115
|
+
label: "Playwright step",
|
|
116
|
+
kind: "fixture",
|
|
117
|
+
className: MUTED
|
|
118
|
+
},
|
|
119
|
+
"agent-browser": { icon: UiCursorClick, label: "Agent browser", kind: "fixture", className: MUTED },
|
|
120
|
+
criterion: { icon: UiSealCheck, label: "Acceptance criterion", kind: "fixture", className: MUTED },
|
|
121
|
+
checklist: { icon: UiSealCheck, label: "Acceptance criteria", kind: "fixture", className: MUTED },
|
|
122
|
+
"golangci-lint": { icon: UiLogoGo, label: "golangci-lint", kind: "lint", className: GO },
|
|
123
|
+
eslint: {
|
|
124
|
+
icon: UiLogoEslint,
|
|
125
|
+
label: "ESLint",
|
|
126
|
+
kind: "lint",
|
|
127
|
+
className: "text-[#4b32c3] dark:text-[#8080f2]"
|
|
128
|
+
},
|
|
129
|
+
oxlint: {
|
|
130
|
+
icon: UiLogoOxc,
|
|
131
|
+
label: "oxlint",
|
|
132
|
+
kind: "lint",
|
|
133
|
+
className: "text-[#0891b2] dark:text-[#00f7f1]"
|
|
134
|
+
},
|
|
135
|
+
tsc: {
|
|
136
|
+
icon: UiLogoTypescript,
|
|
137
|
+
label: "TypeScript compiler",
|
|
138
|
+
kind: "lint",
|
|
139
|
+
className: "text-[#3178c6]"
|
|
140
|
+
},
|
|
141
|
+
markdownlint: { icon: UiLogoMarkdown, label: "markdownlint", kind: "lint", className: MARKDOWN },
|
|
142
|
+
vale: { icon: UiLogoMarkdown, label: "Vale (prose)", kind: "lint", className: MARKDOWN },
|
|
143
|
+
pyright: {
|
|
144
|
+
icon: UiLogoPython,
|
|
145
|
+
label: "Pyright",
|
|
146
|
+
kind: "lint",
|
|
147
|
+
className: "text-[#3776ab] dark:text-[#ffd43b]"
|
|
148
|
+
},
|
|
149
|
+
ruff: {
|
|
150
|
+
icon: UiLogoRuff,
|
|
151
|
+
label: "Ruff",
|
|
152
|
+
kind: "lint",
|
|
153
|
+
className: "text-[#261230] dark:text-[#d7ff64]"
|
|
154
|
+
},
|
|
155
|
+
// A secret scanner's finding is about a credential, not a language.
|
|
156
|
+
betterleaks: { icon: UiKey, label: "betterleaks (secrets)", kind: "lint", className: MUTED },
|
|
157
|
+
jscpd: { icon: UiCopy, label: "jscpd (duplicate code)", kind: "lint", className: MUTED },
|
|
158
|
+
reactdoctor: {
|
|
159
|
+
icon: UiLogoReact,
|
|
160
|
+
label: "React Doctor",
|
|
161
|
+
kind: "lint",
|
|
162
|
+
className: "text-[#0e7490] dark:text-[#61dafb]"
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
function toolMark(tool) {
|
|
166
|
+
return tool && TEST_TOOLS[tool] || null;
|
|
167
|
+
}
|
|
168
|
+
function hasStepInfo(detail) {
|
|
169
|
+
if (detail === null || typeof detail !== "object" || Array.isArray(detail)) return false;
|
|
170
|
+
const step = detail.step;
|
|
171
|
+
return step !== null && typeof step === "object" && !Array.isArray(step);
|
|
172
|
+
}
|
|
173
|
+
function toolKeyFor(node) {
|
|
174
|
+
if (node.framework === "playwright" && hasStepInfo(node.detail)) return "playwright-step";
|
|
175
|
+
return node.framework;
|
|
176
|
+
}
|
|
177
|
+
export {
|
|
178
|
+
LINT_SEVERITIES,
|
|
179
|
+
TEST_OUTCOMES,
|
|
180
|
+
TEST_TOOLS,
|
|
181
|
+
toolKeyFor,
|
|
182
|
+
toolMark
|
|
183
|
+
};
|
|
184
|
+
//# sourceMappingURL=marks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marks.js","sources":["../../../src/data/test-runner/marks.ts"],"sourcesContent":["// The shared iconography for test and lint results: what happened (outcome),\n// how bad a finding is (lint severity), and what produced it (tool).\n//\n// Every outcome has its own outline glyph, so a result never reads by colour\n// alone.\n// Tool marks are bundled Simple Icons brand glyphs (offline, no runtime icon\n// names), coloured per theme here because one brand hex can't hold up on both\n// light and dark surfaces.\n\nimport type { StaticIconComponent } from \"../Icon\";\nimport {\n UiCircleOutline,\n UiCircleX,\n UiBeaker,\n UiChatDots,\n UiClipboardText,\n UiCopy,\n UiCursorClick,\n UiDatabase,\n UiGlobe,\n UiInfo,\n UiKey,\n UiListChecks,\n UiLoader,\n UiLogoEslint,\n UiLogoGo,\n UiLogoJest,\n UiLogoMarkdown,\n UiLogoOxc,\n UiLogoPlaywright,\n UiLogoPython,\n UiLogoReact,\n UiLogoRuff,\n UiLogoTypescript,\n UiLogoVitest,\n UiPass,\n UiProhibit,\n UiRobotAi,\n UiSealCheck,\n UiServer,\n UiSkipForward,\n UiSparkles,\n UiTerminal,\n UiTimer,\n UiWarningTriangle,\n} from \"../../icons\";\nimport { STATUS_LABELS, type TestOutcome } from \"./status\";\n\nexport type { TestOutcome } from \"./status\";\n\nexport type ResultMark = {\n icon: StaticIconComponent;\n label: string;\n /** Text colour classes for light and dark themes. */\n className: string;\n spin?: boolean;\n};\n\nconst LABEL = Object.fromEntries(STATUS_LABELS.map((s) => [s.key, s.label]));\n\nconst RED = \"text-red-600 dark:text-red-400\";\nconst AMBER = \"text-amber-600 dark:text-amber-400\";\n\nexport const TEST_OUTCOMES: Record<TestOutcome, ResultMark> = {\n failed: { icon: UiCircleX, label: LABEL.failed!, className: RED },\n errored: { icon: UiProhibit, label: \"Could not run\", className: RED },\n timedout: { icon: UiTimer, label: LABEL.timedout!, className: AMBER },\n warned: { icon: UiWarningTriangle, label: LABEL.warned!, className: AMBER },\n passed: {\n icon: UiPass,\n label: LABEL.passed!,\n className: \"text-emerald-600 dark:text-emerald-400\",\n },\n skipped: { icon: UiSkipForward, label: LABEL.skipped!, className: \"text-slate-500\" },\n pending: {\n icon: UiCircleOutline,\n label: LABEL.pending!,\n className: \"text-slate-400 dark:text-slate-500\",\n },\n running: {\n icon: UiLoader,\n label: LABEL.running!,\n className: \"text-blue-600 dark:text-blue-400\",\n spin: true,\n },\n};\n\nexport type LintSeverity = \"error\" | \"warning\" | \"info\";\n\n/** An error-severity finding fails the verdict and a warning warns it, so they share those outcomes' marks. */\nexport const LINT_SEVERITIES: Record<LintSeverity, ResultMark> = {\n error: { ...TEST_OUTCOMES.failed, label: \"Error\" },\n warning: { ...TEST_OUTCOMES.warned, label: \"Warning\" },\n info: { icon: UiInfo, label: \"Info\", className: \"text-sky-600 dark:text-sky-400\" },\n};\n\nexport type ToolKind = \"test\" | \"lint\" | \"fixture\" | \"runner\";\n\nexport type ToolMark = {\n icon: StaticIconComponent;\n label: string;\n kind: ToolKind;\n className: string;\n};\n\nconst GO = \"text-[#00add8]\";\nconst MARKDOWN = \"text-foreground\";\nconst MUTED = \"text-muted-foreground\";\n\n/**\n * Keyed by the identifiers gavel reports: testrunner/parsers Framework values\n * and each linter's Name(). A tool without a mark of its own takes its\n * language's (golangci-lint → Go, pyright → Python).\n */\nexport const TEST_TOOLS: Record<string, ToolMark> = {\n \"go test\": { icon: UiLogoGo, label: \"go test\", kind: \"test\", className: GO },\n ginkgo: { icon: UiLogoGo, label: \"Ginkgo\", kind: \"test\", className: GO },\n vitest: { icon: UiLogoVitest, label: \"Vitest\", kind: \"test\", className: \"text-[#6e9f18]\" },\n jest: { icon: UiLogoJest, label: \"Jest\", kind: \"test\", className: \"text-[#c21325] dark:text-[#e5576a]\" },\n playwright: {\n icon: UiLogoPlaywright,\n label: \"Playwright\",\n kind: \"test\",\n className: \"text-[#2ead33]\",\n },\n fixture: { icon: UiLogoMarkdown, label: \"Markdown fixture\", kind: \"test\", className: MARKDOWN },\n task: { icon: UiTerminal, label: \"Task\", kind: \"runner\", className: MUTED },\n // Fixture step types (gavel fixtures FixtureResult.Type) and the\n // \"checklist\" node verifyReportTests synthesizes for acceptance criteria.\n exec: { icon: UiTerminal, label: \"Command\", kind: \"fixture\", className: MUTED },\n test: { icon: UiBeaker, label: \"Test step\", kind: \"fixture\", className: MUTED },\n lint: { icon: UiListChecks, label: \"Lint step\", kind: \"fixture\", className: MUTED },\n verify: {\n icon: UiSparkles,\n label: \"AI review\",\n kind: \"fixture\",\n className: \"text-violet-600 dark:text-violet-400\",\n },\n query: { icon: UiDatabase, label: \"Query\", kind: \"fixture\", className: MUTED },\n // Typed step kinds (gavel fixtures/kind registry): the node's `framework`\n // is the kind name. `ai` is the runner behind `verify` but is a prompt/CEL\n // round-trip rather than an acceptance-criteria review, so it takes the\n // same violet family with its own glyph and label.\n services: { icon: UiServer, label: \"Services\", kind: \"fixture\", className: MUTED },\n todo: { icon: UiClipboardText, label: \"TODO step\", kind: \"fixture\", className: MUTED },\n todo_prompt: { icon: UiChatDots, label: \"TODO prompt run\", kind: \"fixture\", className: MUTED },\n ai: {\n icon: UiRobotAi,\n label: \"AI step\",\n kind: \"fixture\",\n className: \"text-violet-600 dark:text-violet-400\",\n },\n browser: { icon: UiGlobe, label: \"Browser\", kind: \"fixture\", className: MUTED },\n // The fixture-step twin of the `playwright` test framework above; both\n // arrive as framework \"playwright\", so toolKeyFor() picks this key when the\n // node carries `detail.step`. Muted like every other fixture step, so the\n // brand green stays on the spec results the framework reports.\n \"playwright-step\": {\n icon: UiLogoPlaywright,\n label: \"Playwright step\",\n kind: \"fixture\",\n className: MUTED,\n },\n \"agent-browser\": { icon: UiCursorClick, label: \"Agent browser\", kind: \"fixture\", className: MUTED },\n criterion: { icon: UiSealCheck, label: \"Acceptance criterion\", kind: \"fixture\", className: MUTED },\n checklist: { icon: UiSealCheck, label: \"Acceptance criteria\", kind: \"fixture\", className: MUTED },\n \"golangci-lint\": { icon: UiLogoGo, label: \"golangci-lint\", kind: \"lint\", className: GO },\n eslint: {\n icon: UiLogoEslint,\n label: \"ESLint\",\n kind: \"lint\",\n className: \"text-[#4b32c3] dark:text-[#8080f2]\",\n },\n oxlint: {\n icon: UiLogoOxc,\n label: \"oxlint\",\n kind: \"lint\",\n className: \"text-[#0891b2] dark:text-[#00f7f1]\",\n },\n tsc: {\n icon: UiLogoTypescript,\n label: \"TypeScript compiler\",\n kind: \"lint\",\n className: \"text-[#3178c6]\",\n },\n markdownlint: { icon: UiLogoMarkdown, label: \"markdownlint\", kind: \"lint\", className: MARKDOWN },\n vale: { icon: UiLogoMarkdown, label: \"Vale (prose)\", kind: \"lint\", className: MARKDOWN },\n pyright: {\n icon: UiLogoPython,\n label: \"Pyright\",\n kind: \"lint\",\n className: \"text-[#3776ab] dark:text-[#ffd43b]\",\n },\n ruff: {\n icon: UiLogoRuff,\n label: \"Ruff\",\n kind: \"lint\",\n className: \"text-[#261230] dark:text-[#d7ff64]\",\n },\n // A secret scanner's finding is about a credential, not a language.\n betterleaks: { icon: UiKey, label: \"betterleaks (secrets)\", kind: \"lint\", className: MUTED },\n jscpd: { icon: UiCopy, label: \"jscpd (duplicate code)\", kind: \"lint\", className: MUTED },\n reactdoctor: {\n icon: UiLogoReact,\n label: \"React Doctor\",\n kind: \"lint\",\n className: \"text-[#0e7490] dark:text-[#61dafb]\",\n },\n};\n\n/** The tool's mark, or null for a tool the catalog doesn't know (render its name alone). */\nexport function toolMark(tool: string | undefined): ToolMark | null {\n return (tool && TEST_TOOLS[tool]) || null;\n}\n\nfunction hasStepInfo(detail: unknown): boolean {\n if (detail === null || typeof detail !== \"object\" || Array.isArray(detail)) return false;\n const step = (detail as Record<string, unknown>).step;\n return step !== null && typeof step === \"object\" && !Array.isArray(step);\n}\n\n/**\n * The TEST_TOOLS key for a node. A node's `framework` is the key, except that\n * \"playwright\" names both the test framework and the `playwright` fixture-step\n * kind: a node carrying `detail.step` (the fixture verifier's step id and\n * kind) is the step.\n */\nexport function toolKeyFor(node: { framework?: string | undefined; detail?: unknown }): string | undefined {\n if (node.framework === \"playwright\" && hasStepInfo(node.detail)) return \"playwright-step\";\n return node.framework;\n}\n\n"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const filterState = require("./filterState.cjs");
|
|
4
|
-
const UiHourglass = require("../../icons/components/UiHourglass.cjs");
|
|
5
|
-
const UiLoader = require("../../icons/components/UiLoader.cjs");
|
|
6
|
-
const UiPause = require("../../icons/components/UiPause.cjs");
|
|
7
|
-
const UiError = require("../../icons/components/UiError.cjs");
|
|
8
|
-
const UiWarningTriangle = require("../../icons/components/UiWarningTriangle.cjs");
|
|
9
|
-
const UiPass = require("../../icons/components/UiPass.cjs");
|
|
10
|
-
const UiClass = require("../../icons/components/UiClass.cjs");
|
|
11
4
|
const emptyCounts = () => ({
|
|
12
5
|
total: 0,
|
|
13
6
|
passed: 0,
|
|
@@ -113,44 +106,34 @@ function testStatus(t) {
|
|
|
113
106
|
if (t.passed) return "passed";
|
|
114
107
|
return null;
|
|
115
108
|
}
|
|
116
|
-
function
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (
|
|
120
|
-
if (t.
|
|
121
|
-
|
|
122
|
-
if (t
|
|
123
|
-
if (
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (s.running > 0) return UiLoader.UiLoader;
|
|
130
|
-
if (s.pending > 0) return UiPause.UiPause;
|
|
131
|
-
return UiPass.UiPass;
|
|
132
|
-
}
|
|
133
|
-
return UiClass.UiClass;
|
|
109
|
+
function outcomeFor(t) {
|
|
110
|
+
var _a;
|
|
111
|
+
const own = testStatus(t);
|
|
112
|
+
if (own) return own;
|
|
113
|
+
if (!((_a = t.children) == null ? void 0 : _a.length)) return null;
|
|
114
|
+
const s = sum(t);
|
|
115
|
+
if (hasTimedOutDescendant(t)) return "timedout";
|
|
116
|
+
if (s.failed > 0) return "failed";
|
|
117
|
+
if (s.warned > 0) return "warned";
|
|
118
|
+
if (s.running > 0) return "running";
|
|
119
|
+
if (s.pending > 0) return "pending";
|
|
120
|
+
if (s.total > 0 && s.skipped === s.total) return "skipped";
|
|
121
|
+
return "passed";
|
|
134
122
|
}
|
|
135
123
|
function statusToneFor(t) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (s.pending > 0) return "neutral";
|
|
150
|
-
return "success";
|
|
151
|
-
}
|
|
152
|
-
return "neutral";
|
|
153
|
-
}
|
|
124
|
+
const outcome = outcomeFor(t);
|
|
125
|
+
return outcome ? OUTCOME_TONE[outcome] : "neutral";
|
|
126
|
+
}
|
|
127
|
+
const OUTCOME_TONE = {
|
|
128
|
+
failed: "danger",
|
|
129
|
+
errored: "danger",
|
|
130
|
+
timedout: "warning",
|
|
131
|
+
warned: "warning",
|
|
132
|
+
skipped: "warning",
|
|
133
|
+
running: "info",
|
|
134
|
+
pending: "neutral",
|
|
135
|
+
passed: "success"
|
|
136
|
+
};
|
|
154
137
|
function formatTestDuration(ns) {
|
|
155
138
|
if (ns <= 0) return "";
|
|
156
139
|
const ms = ns / 1e6;
|
|
@@ -241,7 +224,7 @@ exports.formatTestDuration = formatTestDuration;
|
|
|
241
224
|
exports.hasFailed = hasFailed;
|
|
242
225
|
exports.hasPending = hasPending;
|
|
243
226
|
exports.humanizeName = humanizeName;
|
|
244
|
-
exports.
|
|
227
|
+
exports.outcomeFor = outcomeFor;
|
|
245
228
|
exports.statusToneFor = statusToneFor;
|
|
246
229
|
exports.sum = sum;
|
|
247
230
|
exports.sumNonTaskTests = sumNonTaskTests;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.cjs","sources":["../../../src/data/test-runner/status.ts"],"sourcesContent":["// Pure status/roll-up helpers for the test runner — ported from Gavel's\n// utils.ts (Tests-only subset). No JSX here. The two status mappers\n// (statusIconFor / statusToneFor) replace Gavel's raw-Tailwind statusIcon /\n// statusColor with clicky's icon set and semantic Badge tones.\n\nimport type { StaticIconComponent } from \"../Icon\";\nimport type { BadgeTone } from \"../Badge\";\nimport {\n UiClass,\n UiError,\n UiHourglass,\n UiLoader,\n UiPass,\n UiPause,\n UiWarningTriangle,\n} from \"../../icons\";\nimport type { Test, TestSummary } from \"./types\";\nimport { matchesFilterState, type FilterState } from \"./filterState\";\n\n// --- roll-up counts ------------------------------------------------------\n\n/**\n * Tallied verdict breakdown a `Test` subtree rolls up to. `warned` is amber and\n * orthogonal to a real failure — a warned-only leaf counts in total + warned,\n * never in failed.\n */\nexport type StatusCounts = {\n total: number;\n passed: number;\n failed: number;\n warned: number;\n skipped: number;\n pending: number;\n running: number;\n timedout: number;\n};\n\nconst emptyCounts = (): StatusCounts => ({\n total: 0,\n passed: 0,\n failed: 0,\n warned: 0,\n skipped: 0,\n pending: 0,\n running: 0,\n timedout: 0,\n});\n\nconst addCounts = (r: StatusCounts, s: StatusCounts) => {\n r.total += s.total;\n r.passed += s.passed;\n r.failed += s.failed;\n r.warned += s.warned;\n r.skipped += s.skipped;\n r.pending += s.pending;\n r.running += s.running;\n r.timedout += s.timedout;\n};\n\nconst countsFromSummary = (summary: TestSummary): StatusCounts => ({\n total: summary.Total,\n passed: summary.Passed,\n failed: summary.Failed,\n warned: summary.Warned || 0,\n skipped: summary.Skipped,\n pending: summary.Pending || 0,\n running: summary.Running || 0,\n timedout: summary.Timedout || 0,\n});\n\nconst countsFromLeaf = (t: Test): StatusCounts => {\n const isTimedOut = !!t.timed_out;\n const counted =\n isTimedOut || t.passed || t.failed || t.warned || t.skipped || t.pending || t.running;\n return {\n total: counted ? 1 : 0,\n passed: !isTimedOut && t.passed ? 1 : 0,\n failed: !isTimedOut && t.failed ? 1 : 0,\n warned: !isTimedOut && t.warned ? 1 : 0,\n skipped: !isTimedOut && t.skipped ? 1 : 0,\n pending: !isTimedOut && t.pending ? 1 : 0,\n running: !isTimedOut && t.running ? 1 : 0,\n timedout: isTimedOut ? 1 : 0,\n };\n};\n\nexport function sum(t: Test): StatusCounts {\n if (t.summary) return countsFromSummary(t.summary);\n if (!t.children || t.children.length === 0) return countsFromLeaf(t);\n const r = emptyCounts();\n for (const c of t.children) addCounts(r, sum(c));\n return r;\n}\n\n/** Roll up a forest's non-task status counts. Shared by `TestRunner`'s filter\n * bar and `TestRunSummary`'s chips so both read the same tally. */\nexport function aggregateStatusCounts(tests: Test[]): StatusCounts {\n const r = emptyCounts();\n for (const t of tests) addCounts(r, sumNonTaskTests(t));\n return r;\n}\n\n/** Ordered status key → label list, driving both the filter bar's pills and a\n * host's status filter option list, so the seven rows aren't hand-duplicated. */\nexport const STATUS_LABELS: { key: keyof StatusCounts; label: string }[] = [\n { key: \"failed\", label: \"Failed\" },\n { key: \"warned\", label: \"Warned\" },\n { key: \"timedout\", label: \"Timed out\" },\n { key: \"passed\", label: \"Passed\" },\n { key: \"skipped\", label: \"Skipped\" },\n { key: \"running\", label: \"Running\" },\n { key: \"pending\", label: \"Queued\" },\n];\n\n/** Like {@link sum} but excludes `task`-framework pseudo-nodes from the tally. */\nexport function sumNonTaskTests(t: Test): StatusCounts {\n if (t.framework === \"task\") {\n const r = emptyCounts();\n for (const c of t.children || []) addCounts(r, sumNonTaskTests(c));\n return r;\n }\n if (t.summary) return countsFromSummary(t.summary);\n if (!t.children || t.children.length === 0) return countsFromLeaf(t);\n const r = emptyCounts();\n for (const c of t.children) addCounts(r, sumNonTaskTests(c));\n return r;\n}\n\nexport function hasFailed(t: Test): boolean {\n if (t.failed) return true;\n return (t.children || []).some(hasFailed);\n}\n\nexport function hasPending(t: Test): boolean {\n if (t.pending) return true;\n return (t.children || []).some(hasPending);\n}\n\nfunction hasTimedOutDescendant(t: Test): boolean {\n if (t.timed_out) return true;\n return (t.children || []).some(hasTimedOutDescendant);\n}\n\nexport function totalDuration(t: Test): number {\n if (t.duration && t.duration > 0) return t.duration;\n let d = 0;\n for (const c of t.children || []) d += totalDuration(c);\n return d;\n}\n\n// --- status classification ----------------------------------------------\n\nexport type TestStatus =\n | \"passed\"\n | \"failed\"\n | \"warned\"\n | \"skipped\"\n | \"pending\"\n | \"running\"\n | \"timedout\";\n\n/** Resolve a leaf node's single status, or null for a status-less container. */\nexport function testStatus(t: Test): TestStatus | null {\n if (t.timed_out) return \"timedout\";\n if (t.running) return \"running\";\n if (t.pending) return \"pending\";\n if (t.failed) return \"failed\";\n if (t.warned) return \"warned\";\n if (t.skipped) return \"skipped\";\n if (t.passed) return \"passed\";\n return null;\n}\n\n/** Pick the clicky icon for a node, rolling up container state. */\nexport function statusIconFor(t: Test): StaticIconComponent {\n if (t.timed_out) return UiHourglass;\n if (t.running) return UiLoader;\n if (t.pending) return UiPause;\n if (t.failed) return UiError;\n if (t.warned) return UiWarningTriangle;\n if (t.skipped) return UiPause;\n if (t.passed) return UiPass;\n if (t.children && t.children.length > 0) {\n const s = sum(t);\n if (hasTimedOutDescendant(t)) return UiHourglass;\n if (s.failed > 0) return UiError;\n if (s.warned > 0) return UiWarningTriangle;\n if (s.running > 0) return UiLoader;\n if (s.pending > 0) return UiPause;\n return UiPass;\n }\n return UiClass;\n}\n\n/** Map a node's status to a semantic Badge tone, rolling up container state. */\nexport function statusToneFor(t: Test): BadgeTone {\n if (t.timed_out) return \"warning\";\n if (t.running) return \"info\";\n if (t.pending) return \"neutral\";\n if (t.failed) return \"danger\";\n if (t.warned) return \"warning\";\n if (t.skipped) return \"warning\";\n if (t.passed) return \"success\";\n if (t.children && t.children.length > 0) {\n const s = sum(t);\n if (hasTimedOutDescendant(t)) return \"warning\";\n if (s.failed > 0) return \"danger\";\n if (s.warned > 0) return \"warning\";\n if (s.running > 0) return \"info\";\n if (s.pending > 0) return \"neutral\";\n return \"success\";\n }\n return \"neutral\";\n}\n\n// --- formatting ----------------------------------------------------------\n\n/**\n * Format a nanosecond duration as \"123ms\" or \"1.2s\". Empty for non-positive.\n * Named distinctly from clicky's ms/s `formatDuration` (lib/format) since the\n * test-runner wire format is nanoseconds.\n */\nexport function formatTestDuration(ns: number): string {\n if (ns <= 0) return \"\";\n const ms = ns / 1e6;\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction compactWithUnit(value: number, unit: string): string {\n const rounded =\n Math.abs(value) >= 10 ? Math.round(value).toString() : value.toFixed(1).replace(/\\.0$/, \"\");\n return `${rounded}${unit}`;\n}\n\n/** Compact integer counts: <1000 raw, then \"k\", then \"M\". */\nexport function formatCount(n: number): string {\n const abs = Math.abs(n);\n if (abs < 1000) return String(n);\n if (abs < 1_000_000) return compactWithUnit(n / 1000, \"k\");\n return compactWithUnit(n / 1_000_000, \"M\");\n}\n\n/** Strip Go's `Test` prefix and split CamelCase / subtest names into words. */\nexport function humanizeName(name: string, framework?: string): string {\n if (!name) return \"\";\n if (framework !== \"go test\") return name;\n if (name.endsWith(\"/\")) return name;\n return name\n .split(\"/\")\n .map((p, i) => {\n if (i === 0) {\n return p.replace(/^Test/, \"\").replace(/([a-z0-9])([A-Z])/g, \"$1 $2\");\n }\n return p.replace(/_/g, \" \");\n })\n .join(\" / \");\n}\n\n// --- tree transforms -----------------------------------------------------\n\n/** Unique non-task frameworks present in the forest, sorted. */\nexport function collectFrameworks(tests: Test[]): string[] {\n const set = new Set<string>();\n const walk = (t: Test) => {\n if (t.framework && t.framework !== \"task\") set.add(t.framework);\n (t.children || []).forEach(walk);\n };\n tests.forEach(walk);\n return Array.from(set).sort();\n}\n\nfunction joinChainNames(parent: string | undefined, child: string | undefined): string {\n const p = (parent ?? \"\").trim();\n const c = (child ?? \"\").trim();\n if (!p) return c;\n if (!c) return p;\n return `${p} > ${c}`;\n}\n\nfunction isCollapsibleContainer(t: Test): boolean {\n return !(t.passed || t.failed || t.skipped || t.pending);\n}\n\n// Re-deriving a collapsed/filtered node invalidates any cached summary; drop it\n// so callers re-roll-up from the surviving children.\nfunction withoutSummary(t: Test): Omit<Test, \"summary\"> & { summary?: never } {\n const { summary: _summary, ...rest } = t;\n return rest;\n}\n\nfunction collapseNode(t: Test): Test {\n const children = t.children ?? [];\n if (children.length === 0) return t;\n\n const collapsedChildren = children.map(collapseNode);\n\n const onlyChild = collapsedChildren.length === 1 ? collapsedChildren[0] : undefined;\n if (onlyChild && isCollapsibleContainer(t)) {\n return { ...withoutSummary(onlyChild), name: joinChainNames(t.name, onlyChild.name) };\n }\n\n return { ...t, children: collapsedChildren };\n}\n\n/**\n * Compress any status-less container with exactly one child into that child,\n * joining names with \" > \". Recursive, so chains collapse into a single row.\n */\nexport function collapseSingleChildChains(tests: Test[]): Test[] {\n return tests.map(collapseNode);\n}\n\nfunction matchesLeaf(\n t: Test,\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): boolean {\n const s = testStatus(t);\n if (s === null) return false;\n return matchesFilterState(s, statusFilter) && matchesFilterState(t.framework, frameworkFilter);\n}\n\nfunction filterNode(\n t: Test,\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): Test | null {\n if (t.children && t.children.length > 0) {\n const filtered = t.children\n .map((c) => filterNode(c, statusFilter, frameworkFilter))\n .filter(Boolean) as Test[];\n if (filtered.length === 0) return null;\n return { ...withoutSummary(t), children: filtered };\n }\n return matchesLeaf(t, statusFilter, frameworkFilter) ? t : null;\n}\n\n/** Prune leaves not matching the status/framework filters; drop empty branches. */\nexport function filterTests(\n tests: Test[],\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): Test[] {\n if (statusFilter.size === 0 && frameworkFilter.size === 0) return tests;\n return tests\n .map((t) => filterNode(t, statusFilter, frameworkFilter))\n .filter(Boolean) as Test[];\n}\n"],"names":["r","UiHourglass","UiLoader","UiPause","UiError","UiWarningTriangle","UiPass","UiClass","matchesFilterState"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"status.cjs","sources":["../../../src/data/test-runner/status.ts"],"sourcesContent":["// Pure status/roll-up helpers for the test runner — ported from Gavel's\n// utils.ts (Tests-only subset). No JSX here. `outcomeFor` resolves the outcome\n// marks.tsx draws; `statusToneFor` maps it to a semantic Badge tone.\n\nimport type { BadgeTone } from \"../Badge\";\nimport type { Test, TestSummary } from \"./types\";\nimport { matchesFilterState, type FilterState } from \"./filterState\";\n\n// --- roll-up counts ------------------------------------------------------\n\n/**\n * Tallied verdict breakdown a `Test` subtree rolls up to. `warned` is amber and\n * orthogonal to a real failure — a warned-only leaf counts in total + warned,\n * never in failed.\n */\nexport type StatusCounts = {\n total: number;\n passed: number;\n failed: number;\n warned: number;\n skipped: number;\n pending: number;\n running: number;\n timedout: number;\n};\n\nconst emptyCounts = (): StatusCounts => ({\n total: 0,\n passed: 0,\n failed: 0,\n warned: 0,\n skipped: 0,\n pending: 0,\n running: 0,\n timedout: 0,\n});\n\nconst addCounts = (r: StatusCounts, s: StatusCounts) => {\n r.total += s.total;\n r.passed += s.passed;\n r.failed += s.failed;\n r.warned += s.warned;\n r.skipped += s.skipped;\n r.pending += s.pending;\n r.running += s.running;\n r.timedout += s.timedout;\n};\n\nconst countsFromSummary = (summary: TestSummary): StatusCounts => ({\n total: summary.Total,\n passed: summary.Passed,\n failed: summary.Failed,\n warned: summary.Warned || 0,\n skipped: summary.Skipped,\n pending: summary.Pending || 0,\n running: summary.Running || 0,\n timedout: summary.Timedout || 0,\n});\n\nconst countsFromLeaf = (t: Test): StatusCounts => {\n const isTimedOut = !!t.timed_out;\n const counted =\n isTimedOut || t.passed || t.failed || t.warned || t.skipped || t.pending || t.running;\n return {\n total: counted ? 1 : 0,\n passed: !isTimedOut && t.passed ? 1 : 0,\n failed: !isTimedOut && t.failed ? 1 : 0,\n warned: !isTimedOut && t.warned ? 1 : 0,\n skipped: !isTimedOut && t.skipped ? 1 : 0,\n pending: !isTimedOut && t.pending ? 1 : 0,\n running: !isTimedOut && t.running ? 1 : 0,\n timedout: isTimedOut ? 1 : 0,\n };\n};\n\nexport function sum(t: Test): StatusCounts {\n if (t.summary) return countsFromSummary(t.summary);\n if (!t.children || t.children.length === 0) return countsFromLeaf(t);\n const r = emptyCounts();\n for (const c of t.children) addCounts(r, sum(c));\n return r;\n}\n\n/** Roll up a forest's non-task status counts. Shared by `TestRunner`'s filter\n * bar and `TestRunSummary`'s chips so both read the same tally. */\nexport function aggregateStatusCounts(tests: Test[]): StatusCounts {\n const r = emptyCounts();\n for (const t of tests) addCounts(r, sumNonTaskTests(t));\n return r;\n}\n\n/** Ordered status key → label list, driving both the filter bar's pills and a\n * host's status filter option list, so the seven rows aren't hand-duplicated. */\nexport const STATUS_LABELS: { key: keyof StatusCounts; label: string }[] = [\n { key: \"failed\", label: \"Failed\" },\n { key: \"warned\", label: \"Warned\" },\n { key: \"timedout\", label: \"Timed out\" },\n { key: \"passed\", label: \"Passed\" },\n { key: \"skipped\", label: \"Skipped\" },\n { key: \"running\", label: \"Running\" },\n { key: \"pending\", label: \"Queued\" },\n];\n\n/** Like {@link sum} but excludes `task`-framework pseudo-nodes from the tally. */\nexport function sumNonTaskTests(t: Test): StatusCounts {\n if (t.framework === \"task\") {\n const r = emptyCounts();\n for (const c of t.children || []) addCounts(r, sumNonTaskTests(c));\n return r;\n }\n if (t.summary) return countsFromSummary(t.summary);\n if (!t.children || t.children.length === 0) return countsFromLeaf(t);\n const r = emptyCounts();\n for (const c of t.children) addCounts(r, sumNonTaskTests(c));\n return r;\n}\n\nexport function hasFailed(t: Test): boolean {\n if (t.failed) return true;\n return (t.children || []).some(hasFailed);\n}\n\nexport function hasPending(t: Test): boolean {\n if (t.pending) return true;\n return (t.children || []).some(hasPending);\n}\n\nfunction hasTimedOutDescendant(t: Test): boolean {\n if (t.timed_out) return true;\n return (t.children || []).some(hasTimedOutDescendant);\n}\n\nexport function totalDuration(t: Test): number {\n if (t.duration && t.duration > 0) return t.duration;\n let d = 0;\n for (const c of t.children || []) d += totalDuration(c);\n return d;\n}\n\n// --- status classification ----------------------------------------------\n\nexport type TestStatus =\n | \"passed\"\n | \"failed\"\n | \"warned\"\n | \"skipped\"\n | \"pending\"\n | \"running\"\n | \"timedout\";\n\n/** Resolve a leaf node's single status, or null for a status-less container. */\nexport function testStatus(t: Test): TestStatus | null {\n if (t.timed_out) return \"timedout\";\n if (t.running) return \"running\";\n if (t.pending) return \"pending\";\n if (t.failed) return \"failed\";\n if (t.warned) return \"warned\";\n if (t.skipped) return \"skipped\";\n if (t.passed) return \"passed\";\n return null;\n}\n\n/**\n * A test or lint result's outcome. `errored` is a result the runner could not\n * produce at all (the engine crashed, the child run never reported) — distinct\n * from a test that ran and failed.\n */\nexport type TestOutcome = TestStatus | \"errored\";\n\n/**\n * Resolve a node's outcome, rolling a container up to its worst child: a\n * timeout anywhere, then failed, warned, running, queued, else passed. Null for\n * a status-less leaf.\n */\nexport function outcomeFor(t: Test): TestOutcome | null {\n const own = testStatus(t);\n if (own) return own;\n if (!t.children?.length) return null;\n const s = sum(t);\n if (hasTimedOutDescendant(t)) return \"timedout\";\n if (s.failed > 0) return \"failed\";\n if (s.warned > 0) return \"warned\";\n if (s.running > 0) return \"running\";\n if (s.pending > 0) return \"pending\";\n if (s.total > 0 && s.skipped === s.total) return \"skipped\";\n return \"passed\";\n}\n\n/** Map a node's status to a semantic Badge tone, rolling up container state. */\nexport function statusToneFor(t: Test): BadgeTone {\n const outcome = outcomeFor(t);\n return outcome ? OUTCOME_TONE[outcome] : \"neutral\";\n}\n\nconst OUTCOME_TONE: Record<TestOutcome, BadgeTone> = {\n failed: \"danger\",\n errored: \"danger\",\n timedout: \"warning\",\n warned: \"warning\",\n skipped: \"warning\",\n running: \"info\",\n pending: \"neutral\",\n passed: \"success\",\n};\n\n// --- formatting ----------------------------------------------------------\n\n/**\n * Format a nanosecond duration as \"123ms\" or \"1.2s\". Empty for non-positive.\n * Named distinctly from clicky's ms/s `formatDuration` (lib/format) since the\n * test-runner wire format is nanoseconds.\n */\nexport function formatTestDuration(ns: number): string {\n if (ns <= 0) return \"\";\n const ms = ns / 1e6;\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction compactWithUnit(value: number, unit: string): string {\n const rounded =\n Math.abs(value) >= 10 ? Math.round(value).toString() : value.toFixed(1).replace(/\\.0$/, \"\");\n return `${rounded}${unit}`;\n}\n\n/** Compact integer counts: <1000 raw, then \"k\", then \"M\". */\nexport function formatCount(n: number): string {\n const abs = Math.abs(n);\n if (abs < 1000) return String(n);\n if (abs < 1_000_000) return compactWithUnit(n / 1000, \"k\");\n return compactWithUnit(n / 1_000_000, \"M\");\n}\n\n/** Strip Go's `Test` prefix and split CamelCase / subtest names into words. */\nexport function humanizeName(name: string, framework?: string): string {\n if (!name) return \"\";\n if (framework !== \"go test\") return name;\n if (name.endsWith(\"/\")) return name;\n return name\n .split(\"/\")\n .map((p, i) => {\n if (i === 0) {\n return p.replace(/^Test/, \"\").replace(/([a-z0-9])([A-Z])/g, \"$1 $2\");\n }\n return p.replace(/_/g, \" \");\n })\n .join(\" / \");\n}\n\n// --- tree transforms -----------------------------------------------------\n\n/** Unique non-task frameworks present in the forest, sorted. */\nexport function collectFrameworks(tests: Test[]): string[] {\n const set = new Set<string>();\n const walk = (t: Test) => {\n if (t.framework && t.framework !== \"task\") set.add(t.framework);\n (t.children || []).forEach(walk);\n };\n tests.forEach(walk);\n return Array.from(set).sort();\n}\n\nfunction joinChainNames(parent: string | undefined, child: string | undefined): string {\n const p = (parent ?? \"\").trim();\n const c = (child ?? \"\").trim();\n if (!p) return c;\n if (!c) return p;\n return `${p} > ${c}`;\n}\n\nfunction isCollapsibleContainer(t: Test): boolean {\n return !(t.passed || t.failed || t.skipped || t.pending);\n}\n\n// Re-deriving a collapsed/filtered node invalidates any cached summary; drop it\n// so callers re-roll-up from the surviving children.\nfunction withoutSummary(t: Test): Omit<Test, \"summary\"> & { summary?: never } {\n const { summary: _summary, ...rest } = t;\n return rest;\n}\n\nfunction collapseNode(t: Test): Test {\n const children = t.children ?? [];\n if (children.length === 0) return t;\n\n const collapsedChildren = children.map(collapseNode);\n\n const onlyChild = collapsedChildren.length === 1 ? collapsedChildren[0] : undefined;\n if (onlyChild && isCollapsibleContainer(t)) {\n return { ...withoutSummary(onlyChild), name: joinChainNames(t.name, onlyChild.name) };\n }\n\n return { ...t, children: collapsedChildren };\n}\n\n/**\n * Compress any status-less container with exactly one child into that child,\n * joining names with \" > \". Recursive, so chains collapse into a single row.\n */\nexport function collapseSingleChildChains(tests: Test[]): Test[] {\n return tests.map(collapseNode);\n}\n\nfunction matchesLeaf(\n t: Test,\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): boolean {\n const s = testStatus(t);\n if (s === null) return false;\n return matchesFilterState(s, statusFilter) && matchesFilterState(t.framework, frameworkFilter);\n}\n\nfunction filterNode(\n t: Test,\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): Test | null {\n if (t.children && t.children.length > 0) {\n const filtered = t.children\n .map((c) => filterNode(c, statusFilter, frameworkFilter))\n .filter(Boolean) as Test[];\n if (filtered.length === 0) return null;\n return { ...withoutSummary(t), children: filtered };\n }\n return matchesLeaf(t, statusFilter, frameworkFilter) ? t : null;\n}\n\n/** Prune leaves not matching the status/framework filters; drop empty branches. */\nexport function filterTests(\n tests: Test[],\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): Test[] {\n if (statusFilter.size === 0 && frameworkFilter.size === 0) return tests;\n return tests\n .map((t) => filterNode(t, statusFilter, frameworkFilter))\n .filter(Boolean) as Test[];\n}\n"],"names":["r","matchesFilterState"],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { StaticIconComponent } from '../Icon.js';
|
|
2
1
|
import { BadgeTone } from '../Badge.js';
|
|
3
2
|
import { Test } from './types.js';
|
|
4
3
|
import { FilterState } from './filterState.js';
|
|
@@ -35,8 +34,18 @@ export declare function totalDuration(t: Test): number;
|
|
|
35
34
|
export type TestStatus = "passed" | "failed" | "warned" | "skipped" | "pending" | "running" | "timedout";
|
|
36
35
|
/** Resolve a leaf node's single status, or null for a status-less container. */
|
|
37
36
|
export declare function testStatus(t: Test): TestStatus | null;
|
|
38
|
-
/**
|
|
39
|
-
|
|
37
|
+
/**
|
|
38
|
+
* A test or lint result's outcome. `errored` is a result the runner could not
|
|
39
|
+
* produce at all (the engine crashed, the child run never reported) — distinct
|
|
40
|
+
* from a test that ran and failed.
|
|
41
|
+
*/
|
|
42
|
+
export type TestOutcome = TestStatus | "errored";
|
|
43
|
+
/**
|
|
44
|
+
* Resolve a node's outcome, rolling a container up to its worst child: a
|
|
45
|
+
* timeout anywhere, then failed, warned, running, queued, else passed. Null for
|
|
46
|
+
* a status-less leaf.
|
|
47
|
+
*/
|
|
48
|
+
export declare function outcomeFor(t: Test): TestOutcome | null;
|
|
40
49
|
/** Map a node's status to a semantic Badge tone, rolling up container state. */
|
|
41
50
|
export declare function statusToneFor(t: Test): BadgeTone;
|
|
42
51
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/status.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/data/test-runner/status.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,SAAS,CAAC;AACjD,OAAO,EAAsB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAIrE;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAmDF,wBAAgB,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,YAAY,CAMzC;AAED;oEACoE;AACpE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,YAAY,CAIjE;AAED;kFACkF;AAClF,eAAO,MAAM,aAAa,EAAE;IAAE,GAAG,EAAE,MAAM,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAQrE,CAAC;AAEF,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,CAAC,EAAE,IAAI,GAAG,YAAY,CAWrD;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAG1C;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAG3C;AAOD,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAK7C;AAID,MAAM,MAAM,UAAU,GAClB,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,SAAS,GACT,SAAS,GACT,UAAU,CAAC;AAEf,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,UAAU,GAAG,IAAI,CASrD;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAEjD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,WAAW,GAAG,IAAI,CAYtD;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,GAAG,SAAS,CAGhD;AAeD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAKrD;AAQD,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAarE;AAID,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAQzD;AAmCD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAE/D;AA2BD,mFAAmF;AACnF,wBAAgB,WAAW,CACzB,KAAK,EAAE,IAAI,EAAE,EACb,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,EACjC,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,GACnC,IAAI,EAAE,CAKR"}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
1
|
import { matchesFilterState } from "./filterState.js";
|
|
2
|
-
import { UiHourglass } from "../../icons/components/UiHourglass.js";
|
|
3
|
-
import { UiLoader } from "../../icons/components/UiLoader.js";
|
|
4
|
-
import { UiPause } from "../../icons/components/UiPause.js";
|
|
5
|
-
import { UiError } from "../../icons/components/UiError.js";
|
|
6
|
-
import { UiWarningTriangle } from "../../icons/components/UiWarningTriangle.js";
|
|
7
|
-
import { UiPass } from "../../icons/components/UiPass.js";
|
|
8
|
-
import { UiClass } from "../../icons/components/UiClass.js";
|
|
9
2
|
const emptyCounts = () => ({
|
|
10
3
|
total: 0,
|
|
11
4
|
passed: 0,
|
|
@@ -111,44 +104,34 @@ function testStatus(t) {
|
|
|
111
104
|
if (t.passed) return "passed";
|
|
112
105
|
return null;
|
|
113
106
|
}
|
|
114
|
-
function
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (
|
|
118
|
-
if (t.
|
|
119
|
-
|
|
120
|
-
if (t
|
|
121
|
-
if (
|
|
122
|
-
if (
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (s.running > 0) return UiLoader;
|
|
128
|
-
if (s.pending > 0) return UiPause;
|
|
129
|
-
return UiPass;
|
|
130
|
-
}
|
|
131
|
-
return UiClass;
|
|
107
|
+
function outcomeFor(t) {
|
|
108
|
+
var _a;
|
|
109
|
+
const own = testStatus(t);
|
|
110
|
+
if (own) return own;
|
|
111
|
+
if (!((_a = t.children) == null ? void 0 : _a.length)) return null;
|
|
112
|
+
const s = sum(t);
|
|
113
|
+
if (hasTimedOutDescendant(t)) return "timedout";
|
|
114
|
+
if (s.failed > 0) return "failed";
|
|
115
|
+
if (s.warned > 0) return "warned";
|
|
116
|
+
if (s.running > 0) return "running";
|
|
117
|
+
if (s.pending > 0) return "pending";
|
|
118
|
+
if (s.total > 0 && s.skipped === s.total) return "skipped";
|
|
119
|
+
return "passed";
|
|
132
120
|
}
|
|
133
121
|
function statusToneFor(t) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (s.pending > 0) return "neutral";
|
|
148
|
-
return "success";
|
|
149
|
-
}
|
|
150
|
-
return "neutral";
|
|
151
|
-
}
|
|
122
|
+
const outcome = outcomeFor(t);
|
|
123
|
+
return outcome ? OUTCOME_TONE[outcome] : "neutral";
|
|
124
|
+
}
|
|
125
|
+
const OUTCOME_TONE = {
|
|
126
|
+
failed: "danger",
|
|
127
|
+
errored: "danger",
|
|
128
|
+
timedout: "warning",
|
|
129
|
+
warned: "warning",
|
|
130
|
+
skipped: "warning",
|
|
131
|
+
running: "info",
|
|
132
|
+
pending: "neutral",
|
|
133
|
+
passed: "success"
|
|
134
|
+
};
|
|
152
135
|
function formatTestDuration(ns) {
|
|
153
136
|
if (ns <= 0) return "";
|
|
154
137
|
const ms = ns / 1e6;
|
|
@@ -240,7 +223,7 @@ export {
|
|
|
240
223
|
hasFailed,
|
|
241
224
|
hasPending,
|
|
242
225
|
humanizeName,
|
|
243
|
-
|
|
226
|
+
outcomeFor,
|
|
244
227
|
statusToneFor,
|
|
245
228
|
sum,
|
|
246
229
|
sumNonTaskTests,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sources":["../../../src/data/test-runner/status.ts"],"sourcesContent":["// Pure status/roll-up helpers for the test runner — ported from Gavel's\n// utils.ts (Tests-only subset). No JSX here. The two status mappers\n// (statusIconFor / statusToneFor) replace Gavel's raw-Tailwind statusIcon /\n// statusColor with clicky's icon set and semantic Badge tones.\n\nimport type { StaticIconComponent } from \"../Icon\";\nimport type { BadgeTone } from \"../Badge\";\nimport {\n UiClass,\n UiError,\n UiHourglass,\n UiLoader,\n UiPass,\n UiPause,\n UiWarningTriangle,\n} from \"../../icons\";\nimport type { Test, TestSummary } from \"./types\";\nimport { matchesFilterState, type FilterState } from \"./filterState\";\n\n// --- roll-up counts ------------------------------------------------------\n\n/**\n * Tallied verdict breakdown a `Test` subtree rolls up to. `warned` is amber and\n * orthogonal to a real failure — a warned-only leaf counts in total + warned,\n * never in failed.\n */\nexport type StatusCounts = {\n total: number;\n passed: number;\n failed: number;\n warned: number;\n skipped: number;\n pending: number;\n running: number;\n timedout: number;\n};\n\nconst emptyCounts = (): StatusCounts => ({\n total: 0,\n passed: 0,\n failed: 0,\n warned: 0,\n skipped: 0,\n pending: 0,\n running: 0,\n timedout: 0,\n});\n\nconst addCounts = (r: StatusCounts, s: StatusCounts) => {\n r.total += s.total;\n r.passed += s.passed;\n r.failed += s.failed;\n r.warned += s.warned;\n r.skipped += s.skipped;\n r.pending += s.pending;\n r.running += s.running;\n r.timedout += s.timedout;\n};\n\nconst countsFromSummary = (summary: TestSummary): StatusCounts => ({\n total: summary.Total,\n passed: summary.Passed,\n failed: summary.Failed,\n warned: summary.Warned || 0,\n skipped: summary.Skipped,\n pending: summary.Pending || 0,\n running: summary.Running || 0,\n timedout: summary.Timedout || 0,\n});\n\nconst countsFromLeaf = (t: Test): StatusCounts => {\n const isTimedOut = !!t.timed_out;\n const counted =\n isTimedOut || t.passed || t.failed || t.warned || t.skipped || t.pending || t.running;\n return {\n total: counted ? 1 : 0,\n passed: !isTimedOut && t.passed ? 1 : 0,\n failed: !isTimedOut && t.failed ? 1 : 0,\n warned: !isTimedOut && t.warned ? 1 : 0,\n skipped: !isTimedOut && t.skipped ? 1 : 0,\n pending: !isTimedOut && t.pending ? 1 : 0,\n running: !isTimedOut && t.running ? 1 : 0,\n timedout: isTimedOut ? 1 : 0,\n };\n};\n\nexport function sum(t: Test): StatusCounts {\n if (t.summary) return countsFromSummary(t.summary);\n if (!t.children || t.children.length === 0) return countsFromLeaf(t);\n const r = emptyCounts();\n for (const c of t.children) addCounts(r, sum(c));\n return r;\n}\n\n/** Roll up a forest's non-task status counts. Shared by `TestRunner`'s filter\n * bar and `TestRunSummary`'s chips so both read the same tally. */\nexport function aggregateStatusCounts(tests: Test[]): StatusCounts {\n const r = emptyCounts();\n for (const t of tests) addCounts(r, sumNonTaskTests(t));\n return r;\n}\n\n/** Ordered status key → label list, driving both the filter bar's pills and a\n * host's status filter option list, so the seven rows aren't hand-duplicated. */\nexport const STATUS_LABELS: { key: keyof StatusCounts; label: string }[] = [\n { key: \"failed\", label: \"Failed\" },\n { key: \"warned\", label: \"Warned\" },\n { key: \"timedout\", label: \"Timed out\" },\n { key: \"passed\", label: \"Passed\" },\n { key: \"skipped\", label: \"Skipped\" },\n { key: \"running\", label: \"Running\" },\n { key: \"pending\", label: \"Queued\" },\n];\n\n/** Like {@link sum} but excludes `task`-framework pseudo-nodes from the tally. */\nexport function sumNonTaskTests(t: Test): StatusCounts {\n if (t.framework === \"task\") {\n const r = emptyCounts();\n for (const c of t.children || []) addCounts(r, sumNonTaskTests(c));\n return r;\n }\n if (t.summary) return countsFromSummary(t.summary);\n if (!t.children || t.children.length === 0) return countsFromLeaf(t);\n const r = emptyCounts();\n for (const c of t.children) addCounts(r, sumNonTaskTests(c));\n return r;\n}\n\nexport function hasFailed(t: Test): boolean {\n if (t.failed) return true;\n return (t.children || []).some(hasFailed);\n}\n\nexport function hasPending(t: Test): boolean {\n if (t.pending) return true;\n return (t.children || []).some(hasPending);\n}\n\nfunction hasTimedOutDescendant(t: Test): boolean {\n if (t.timed_out) return true;\n return (t.children || []).some(hasTimedOutDescendant);\n}\n\nexport function totalDuration(t: Test): number {\n if (t.duration && t.duration > 0) return t.duration;\n let d = 0;\n for (const c of t.children || []) d += totalDuration(c);\n return d;\n}\n\n// --- status classification ----------------------------------------------\n\nexport type TestStatus =\n | \"passed\"\n | \"failed\"\n | \"warned\"\n | \"skipped\"\n | \"pending\"\n | \"running\"\n | \"timedout\";\n\n/** Resolve a leaf node's single status, or null for a status-less container. */\nexport function testStatus(t: Test): TestStatus | null {\n if (t.timed_out) return \"timedout\";\n if (t.running) return \"running\";\n if (t.pending) return \"pending\";\n if (t.failed) return \"failed\";\n if (t.warned) return \"warned\";\n if (t.skipped) return \"skipped\";\n if (t.passed) return \"passed\";\n return null;\n}\n\n/** Pick the clicky icon for a node, rolling up container state. */\nexport function statusIconFor(t: Test): StaticIconComponent {\n if (t.timed_out) return UiHourglass;\n if (t.running) return UiLoader;\n if (t.pending) return UiPause;\n if (t.failed) return UiError;\n if (t.warned) return UiWarningTriangle;\n if (t.skipped) return UiPause;\n if (t.passed) return UiPass;\n if (t.children && t.children.length > 0) {\n const s = sum(t);\n if (hasTimedOutDescendant(t)) return UiHourglass;\n if (s.failed > 0) return UiError;\n if (s.warned > 0) return UiWarningTriangle;\n if (s.running > 0) return UiLoader;\n if (s.pending > 0) return UiPause;\n return UiPass;\n }\n return UiClass;\n}\n\n/** Map a node's status to a semantic Badge tone, rolling up container state. */\nexport function statusToneFor(t: Test): BadgeTone {\n if (t.timed_out) return \"warning\";\n if (t.running) return \"info\";\n if (t.pending) return \"neutral\";\n if (t.failed) return \"danger\";\n if (t.warned) return \"warning\";\n if (t.skipped) return \"warning\";\n if (t.passed) return \"success\";\n if (t.children && t.children.length > 0) {\n const s = sum(t);\n if (hasTimedOutDescendant(t)) return \"warning\";\n if (s.failed > 0) return \"danger\";\n if (s.warned > 0) return \"warning\";\n if (s.running > 0) return \"info\";\n if (s.pending > 0) return \"neutral\";\n return \"success\";\n }\n return \"neutral\";\n}\n\n// --- formatting ----------------------------------------------------------\n\n/**\n * Format a nanosecond duration as \"123ms\" or \"1.2s\". Empty for non-positive.\n * Named distinctly from clicky's ms/s `formatDuration` (lib/format) since the\n * test-runner wire format is nanoseconds.\n */\nexport function formatTestDuration(ns: number): string {\n if (ns <= 0) return \"\";\n const ms = ns / 1e6;\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction compactWithUnit(value: number, unit: string): string {\n const rounded =\n Math.abs(value) >= 10 ? Math.round(value).toString() : value.toFixed(1).replace(/\\.0$/, \"\");\n return `${rounded}${unit}`;\n}\n\n/** Compact integer counts: <1000 raw, then \"k\", then \"M\". */\nexport function formatCount(n: number): string {\n const abs = Math.abs(n);\n if (abs < 1000) return String(n);\n if (abs < 1_000_000) return compactWithUnit(n / 1000, \"k\");\n return compactWithUnit(n / 1_000_000, \"M\");\n}\n\n/** Strip Go's `Test` prefix and split CamelCase / subtest names into words. */\nexport function humanizeName(name: string, framework?: string): string {\n if (!name) return \"\";\n if (framework !== \"go test\") return name;\n if (name.endsWith(\"/\")) return name;\n return name\n .split(\"/\")\n .map((p, i) => {\n if (i === 0) {\n return p.replace(/^Test/, \"\").replace(/([a-z0-9])([A-Z])/g, \"$1 $2\");\n }\n return p.replace(/_/g, \" \");\n })\n .join(\" / \");\n}\n\n// --- tree transforms -----------------------------------------------------\n\n/** Unique non-task frameworks present in the forest, sorted. */\nexport function collectFrameworks(tests: Test[]): string[] {\n const set = new Set<string>();\n const walk = (t: Test) => {\n if (t.framework && t.framework !== \"task\") set.add(t.framework);\n (t.children || []).forEach(walk);\n };\n tests.forEach(walk);\n return Array.from(set).sort();\n}\n\nfunction joinChainNames(parent: string | undefined, child: string | undefined): string {\n const p = (parent ?? \"\").trim();\n const c = (child ?? \"\").trim();\n if (!p) return c;\n if (!c) return p;\n return `${p} > ${c}`;\n}\n\nfunction isCollapsibleContainer(t: Test): boolean {\n return !(t.passed || t.failed || t.skipped || t.pending);\n}\n\n// Re-deriving a collapsed/filtered node invalidates any cached summary; drop it\n// so callers re-roll-up from the surviving children.\nfunction withoutSummary(t: Test): Omit<Test, \"summary\"> & { summary?: never } {\n const { summary: _summary, ...rest } = t;\n return rest;\n}\n\nfunction collapseNode(t: Test): Test {\n const children = t.children ?? [];\n if (children.length === 0) return t;\n\n const collapsedChildren = children.map(collapseNode);\n\n const onlyChild = collapsedChildren.length === 1 ? collapsedChildren[0] : undefined;\n if (onlyChild && isCollapsibleContainer(t)) {\n return { ...withoutSummary(onlyChild), name: joinChainNames(t.name, onlyChild.name) };\n }\n\n return { ...t, children: collapsedChildren };\n}\n\n/**\n * Compress any status-less container with exactly one child into that child,\n * joining names with \" > \". Recursive, so chains collapse into a single row.\n */\nexport function collapseSingleChildChains(tests: Test[]): Test[] {\n return tests.map(collapseNode);\n}\n\nfunction matchesLeaf(\n t: Test,\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): boolean {\n const s = testStatus(t);\n if (s === null) return false;\n return matchesFilterState(s, statusFilter) && matchesFilterState(t.framework, frameworkFilter);\n}\n\nfunction filterNode(\n t: Test,\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): Test | null {\n if (t.children && t.children.length > 0) {\n const filtered = t.children\n .map((c) => filterNode(c, statusFilter, frameworkFilter))\n .filter(Boolean) as Test[];\n if (filtered.length === 0) return null;\n return { ...withoutSummary(t), children: filtered };\n }\n return matchesLeaf(t, statusFilter, frameworkFilter) ? t : null;\n}\n\n/** Prune leaves not matching the status/framework filters; drop empty branches. */\nexport function filterTests(\n tests: Test[],\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): Test[] {\n if (statusFilter.size === 0 && frameworkFilter.size === 0) return tests;\n return tests\n .map((t) => filterNode(t, statusFilter, frameworkFilter))\n .filter(Boolean) as Test[];\n}\n"],"names":["r"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"status.js","sources":["../../../src/data/test-runner/status.ts"],"sourcesContent":["// Pure status/roll-up helpers for the test runner — ported from Gavel's\n// utils.ts (Tests-only subset). No JSX here. `outcomeFor` resolves the outcome\n// marks.tsx draws; `statusToneFor` maps it to a semantic Badge tone.\n\nimport type { BadgeTone } from \"../Badge\";\nimport type { Test, TestSummary } from \"./types\";\nimport { matchesFilterState, type FilterState } from \"./filterState\";\n\n// --- roll-up counts ------------------------------------------------------\n\n/**\n * Tallied verdict breakdown a `Test` subtree rolls up to. `warned` is amber and\n * orthogonal to a real failure — a warned-only leaf counts in total + warned,\n * never in failed.\n */\nexport type StatusCounts = {\n total: number;\n passed: number;\n failed: number;\n warned: number;\n skipped: number;\n pending: number;\n running: number;\n timedout: number;\n};\n\nconst emptyCounts = (): StatusCounts => ({\n total: 0,\n passed: 0,\n failed: 0,\n warned: 0,\n skipped: 0,\n pending: 0,\n running: 0,\n timedout: 0,\n});\n\nconst addCounts = (r: StatusCounts, s: StatusCounts) => {\n r.total += s.total;\n r.passed += s.passed;\n r.failed += s.failed;\n r.warned += s.warned;\n r.skipped += s.skipped;\n r.pending += s.pending;\n r.running += s.running;\n r.timedout += s.timedout;\n};\n\nconst countsFromSummary = (summary: TestSummary): StatusCounts => ({\n total: summary.Total,\n passed: summary.Passed,\n failed: summary.Failed,\n warned: summary.Warned || 0,\n skipped: summary.Skipped,\n pending: summary.Pending || 0,\n running: summary.Running || 0,\n timedout: summary.Timedout || 0,\n});\n\nconst countsFromLeaf = (t: Test): StatusCounts => {\n const isTimedOut = !!t.timed_out;\n const counted =\n isTimedOut || t.passed || t.failed || t.warned || t.skipped || t.pending || t.running;\n return {\n total: counted ? 1 : 0,\n passed: !isTimedOut && t.passed ? 1 : 0,\n failed: !isTimedOut && t.failed ? 1 : 0,\n warned: !isTimedOut && t.warned ? 1 : 0,\n skipped: !isTimedOut && t.skipped ? 1 : 0,\n pending: !isTimedOut && t.pending ? 1 : 0,\n running: !isTimedOut && t.running ? 1 : 0,\n timedout: isTimedOut ? 1 : 0,\n };\n};\n\nexport function sum(t: Test): StatusCounts {\n if (t.summary) return countsFromSummary(t.summary);\n if (!t.children || t.children.length === 0) return countsFromLeaf(t);\n const r = emptyCounts();\n for (const c of t.children) addCounts(r, sum(c));\n return r;\n}\n\n/** Roll up a forest's non-task status counts. Shared by `TestRunner`'s filter\n * bar and `TestRunSummary`'s chips so both read the same tally. */\nexport function aggregateStatusCounts(tests: Test[]): StatusCounts {\n const r = emptyCounts();\n for (const t of tests) addCounts(r, sumNonTaskTests(t));\n return r;\n}\n\n/** Ordered status key → label list, driving both the filter bar's pills and a\n * host's status filter option list, so the seven rows aren't hand-duplicated. */\nexport const STATUS_LABELS: { key: keyof StatusCounts; label: string }[] = [\n { key: \"failed\", label: \"Failed\" },\n { key: \"warned\", label: \"Warned\" },\n { key: \"timedout\", label: \"Timed out\" },\n { key: \"passed\", label: \"Passed\" },\n { key: \"skipped\", label: \"Skipped\" },\n { key: \"running\", label: \"Running\" },\n { key: \"pending\", label: \"Queued\" },\n];\n\n/** Like {@link sum} but excludes `task`-framework pseudo-nodes from the tally. */\nexport function sumNonTaskTests(t: Test): StatusCounts {\n if (t.framework === \"task\") {\n const r = emptyCounts();\n for (const c of t.children || []) addCounts(r, sumNonTaskTests(c));\n return r;\n }\n if (t.summary) return countsFromSummary(t.summary);\n if (!t.children || t.children.length === 0) return countsFromLeaf(t);\n const r = emptyCounts();\n for (const c of t.children) addCounts(r, sumNonTaskTests(c));\n return r;\n}\n\nexport function hasFailed(t: Test): boolean {\n if (t.failed) return true;\n return (t.children || []).some(hasFailed);\n}\n\nexport function hasPending(t: Test): boolean {\n if (t.pending) return true;\n return (t.children || []).some(hasPending);\n}\n\nfunction hasTimedOutDescendant(t: Test): boolean {\n if (t.timed_out) return true;\n return (t.children || []).some(hasTimedOutDescendant);\n}\n\nexport function totalDuration(t: Test): number {\n if (t.duration && t.duration > 0) return t.duration;\n let d = 0;\n for (const c of t.children || []) d += totalDuration(c);\n return d;\n}\n\n// --- status classification ----------------------------------------------\n\nexport type TestStatus =\n | \"passed\"\n | \"failed\"\n | \"warned\"\n | \"skipped\"\n | \"pending\"\n | \"running\"\n | \"timedout\";\n\n/** Resolve a leaf node's single status, or null for a status-less container. */\nexport function testStatus(t: Test): TestStatus | null {\n if (t.timed_out) return \"timedout\";\n if (t.running) return \"running\";\n if (t.pending) return \"pending\";\n if (t.failed) return \"failed\";\n if (t.warned) return \"warned\";\n if (t.skipped) return \"skipped\";\n if (t.passed) return \"passed\";\n return null;\n}\n\n/**\n * A test or lint result's outcome. `errored` is a result the runner could not\n * produce at all (the engine crashed, the child run never reported) — distinct\n * from a test that ran and failed.\n */\nexport type TestOutcome = TestStatus | \"errored\";\n\n/**\n * Resolve a node's outcome, rolling a container up to its worst child: a\n * timeout anywhere, then failed, warned, running, queued, else passed. Null for\n * a status-less leaf.\n */\nexport function outcomeFor(t: Test): TestOutcome | null {\n const own = testStatus(t);\n if (own) return own;\n if (!t.children?.length) return null;\n const s = sum(t);\n if (hasTimedOutDescendant(t)) return \"timedout\";\n if (s.failed > 0) return \"failed\";\n if (s.warned > 0) return \"warned\";\n if (s.running > 0) return \"running\";\n if (s.pending > 0) return \"pending\";\n if (s.total > 0 && s.skipped === s.total) return \"skipped\";\n return \"passed\";\n}\n\n/** Map a node's status to a semantic Badge tone, rolling up container state. */\nexport function statusToneFor(t: Test): BadgeTone {\n const outcome = outcomeFor(t);\n return outcome ? OUTCOME_TONE[outcome] : \"neutral\";\n}\n\nconst OUTCOME_TONE: Record<TestOutcome, BadgeTone> = {\n failed: \"danger\",\n errored: \"danger\",\n timedout: \"warning\",\n warned: \"warning\",\n skipped: \"warning\",\n running: \"info\",\n pending: \"neutral\",\n passed: \"success\",\n};\n\n// --- formatting ----------------------------------------------------------\n\n/**\n * Format a nanosecond duration as \"123ms\" or \"1.2s\". Empty for non-positive.\n * Named distinctly from clicky's ms/s `formatDuration` (lib/format) since the\n * test-runner wire format is nanoseconds.\n */\nexport function formatTestDuration(ns: number): string {\n if (ns <= 0) return \"\";\n const ms = ns / 1e6;\n if (ms < 1000) return `${ms.toFixed(0)}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n}\n\nfunction compactWithUnit(value: number, unit: string): string {\n const rounded =\n Math.abs(value) >= 10 ? Math.round(value).toString() : value.toFixed(1).replace(/\\.0$/, \"\");\n return `${rounded}${unit}`;\n}\n\n/** Compact integer counts: <1000 raw, then \"k\", then \"M\". */\nexport function formatCount(n: number): string {\n const abs = Math.abs(n);\n if (abs < 1000) return String(n);\n if (abs < 1_000_000) return compactWithUnit(n / 1000, \"k\");\n return compactWithUnit(n / 1_000_000, \"M\");\n}\n\n/** Strip Go's `Test` prefix and split CamelCase / subtest names into words. */\nexport function humanizeName(name: string, framework?: string): string {\n if (!name) return \"\";\n if (framework !== \"go test\") return name;\n if (name.endsWith(\"/\")) return name;\n return name\n .split(\"/\")\n .map((p, i) => {\n if (i === 0) {\n return p.replace(/^Test/, \"\").replace(/([a-z0-9])([A-Z])/g, \"$1 $2\");\n }\n return p.replace(/_/g, \" \");\n })\n .join(\" / \");\n}\n\n// --- tree transforms -----------------------------------------------------\n\n/** Unique non-task frameworks present in the forest, sorted. */\nexport function collectFrameworks(tests: Test[]): string[] {\n const set = new Set<string>();\n const walk = (t: Test) => {\n if (t.framework && t.framework !== \"task\") set.add(t.framework);\n (t.children || []).forEach(walk);\n };\n tests.forEach(walk);\n return Array.from(set).sort();\n}\n\nfunction joinChainNames(parent: string | undefined, child: string | undefined): string {\n const p = (parent ?? \"\").trim();\n const c = (child ?? \"\").trim();\n if (!p) return c;\n if (!c) return p;\n return `${p} > ${c}`;\n}\n\nfunction isCollapsibleContainer(t: Test): boolean {\n return !(t.passed || t.failed || t.skipped || t.pending);\n}\n\n// Re-deriving a collapsed/filtered node invalidates any cached summary; drop it\n// so callers re-roll-up from the surviving children.\nfunction withoutSummary(t: Test): Omit<Test, \"summary\"> & { summary?: never } {\n const { summary: _summary, ...rest } = t;\n return rest;\n}\n\nfunction collapseNode(t: Test): Test {\n const children = t.children ?? [];\n if (children.length === 0) return t;\n\n const collapsedChildren = children.map(collapseNode);\n\n const onlyChild = collapsedChildren.length === 1 ? collapsedChildren[0] : undefined;\n if (onlyChild && isCollapsibleContainer(t)) {\n return { ...withoutSummary(onlyChild), name: joinChainNames(t.name, onlyChild.name) };\n }\n\n return { ...t, children: collapsedChildren };\n}\n\n/**\n * Compress any status-less container with exactly one child into that child,\n * joining names with \" > \". Recursive, so chains collapse into a single row.\n */\nexport function collapseSingleChildChains(tests: Test[]): Test[] {\n return tests.map(collapseNode);\n}\n\nfunction matchesLeaf(\n t: Test,\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): boolean {\n const s = testStatus(t);\n if (s === null) return false;\n return matchesFilterState(s, statusFilter) && matchesFilterState(t.framework, frameworkFilter);\n}\n\nfunction filterNode(\n t: Test,\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): Test | null {\n if (t.children && t.children.length > 0) {\n const filtered = t.children\n .map((c) => filterNode(c, statusFilter, frameworkFilter))\n .filter(Boolean) as Test[];\n if (filtered.length === 0) return null;\n return { ...withoutSummary(t), children: filtered };\n }\n return matchesLeaf(t, statusFilter, frameworkFilter) ? t : null;\n}\n\n/** Prune leaves not matching the status/framework filters; drop empty branches. */\nexport function filterTests(\n tests: Test[],\n statusFilter: FilterState<string>,\n frameworkFilter: FilterState<string>,\n): Test[] {\n if (statusFilter.size === 0 && frameworkFilter.size === 0) return tests;\n return tests\n .map((t) => filterNode(t, statusFilter, frameworkFilter))\n .filter(Boolean) as Test[];\n}\n"],"names":["r"],"mappings":"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"}
|