Compare commits

...

2 Commits

Author SHA1 Message Date
CodeRabbit Fixer
ce6588b523 fix: test(changeTracker): add regression test for multilineOrOptions forwarding in wrapped prompt (#9418)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 15:22:21 +01:00
Johnpaul Chiwetelu
7cb07f9b2d fix: standardize i18n pluralization to two-part English format (#9384)
## Summary

Standardize 5 English pluralization strings from incorrect 3-part format
to proper 2-part `"singular | plural"` format.

## Changes

- **What**: Convert `nodesCount`, `asset`, `errorCount`,
`downloadsFailed`, and `exportFailed` i18n keys from redundant 3-part
pluralization (zero/one/many) to standard 2-part English format
(singular/plural)

## Review Focus

The 3-part format (`a | b | a`) was redundant for English since the
first and third parts were identical. vue-i18n only needs 2 parts for
English pluralization.

Fixes #9277

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9384-fix-standardize-i18n-pluralization-to-two-part-English-format-3196d73d365081cf97c4e7cfa310ce8e)
by [Unito](https://www.unito.io)
2026-03-06 14:53:13 +01:00
3 changed files with 76 additions and 7 deletions

View File

@@ -178,7 +178,7 @@
"uploadAlreadyInProgress": "Upload already in progress",
"capture": "capture",
"nodes": "Nodes",
"nodesCount": "{count} nodes | {count} node | {count} nodes",
"nodesCount": "{count} node | {count} nodes",
"addNode": "Add a node...",
"filterBy": "Filter by:",
"filterByType": "Filter by {type}...",
@@ -222,7 +222,7 @@
"failed": "Failed",
"cancelled": "Cancelled",
"job": "Job",
"asset": "{count} assets | {count} asset | {count} assets",
"asset": "{count} asset | {count} assets",
"untitled": "Untitled",
"emDash": "—",
"enabling": "Enabling {id}",
@@ -3347,7 +3347,7 @@
}
},
"errorOverlay": {
"errorCount": "{count} ERRORS | {count} ERROR | {count} ERRORS",
"errorCount": "{count} ERROR | {count} ERRORS",
"seeErrors": "See Errors"
},
"help": {
@@ -3357,7 +3357,7 @@
"progressToast": {
"importingModels": "Importing Models",
"downloadingModel": "Downloading model...",
"downloadsFailed": "{count} downloads failed | {count} download failed | {count} downloads failed",
"downloadsFailed": "{count} download failed | {count} downloads failed",
"allDownloadsCompleted": "All downloads completed",
"noImportsInQueue": "No {filter} in queue",
"failed": "Failed",
@@ -3374,7 +3374,7 @@
"exportingAssets": "Exporting Assets",
"preparingExport": "Preparing export...",
"exportError": "Export failed",
"exportFailed": "{count} export failed | {count} export failed | {count} exports failed",
"exportFailed": "{count} export failed | {count} exports failed",
"allExportsCompleted": "All exports completed",
"noExportsInQueue": "No {filter} exports in queue",
"exportStarted": "Preparing ZIP download...",

View File

@@ -0,0 +1,62 @@
import { describe, expect, it, vi } from 'vitest'
import type { CanvasPointerEvent } from '@/lib/litegraph/src/litegraph'
import { LGraphCanvas } from '@/lib/litegraph/src/litegraph'
import { ChangeTracker } from './changeTracker'
vi.mock('@/platform/workflow/management/stores/workflowStore', () => ({
useWorkflowStore: vi.fn(() => ({
activeWorkflow: null
})),
ComfyWorkflow: vi.fn()
}))
vi.mock('./api', () => ({
api: {
addEventListener: vi.fn(),
apiURL: vi.fn((path: string) => path)
}
}))
vi.mock('./app', () => ({
app: {
ui: { autoQueueEnabled: false, autoQueueMode: 'instant' },
canvas: { ds: { scale: 1, offset: [0, 0] } },
constructor: { maskeditor_is_opended: undefined }
},
ComfyApp: vi.fn()
}))
describe('ChangeTracker.init', () => {
it('forwards multiline argument to original prompt', () => {
const originalPrompt = vi.fn()
LGraphCanvas.prototype.prompt = originalPrompt
ChangeTracker.init()
const wrappedPrompt = LGraphCanvas.prototype.prompt
expect(wrappedPrompt).not.toBe(originalPrompt)
const mockCallback = vi.fn()
const mockEvent = {} as CanvasPointerEvent
const multilineValue = true
wrappedPrompt.call(
{} as LGraphCanvas,
'Title',
'value',
mockCallback,
mockEvent,
multilineValue
)
expect(originalPrompt).toHaveBeenCalledWith(
'Title',
'value',
expect.any(Function),
mockEvent,
true
)
})
})

View File

@@ -307,14 +307,21 @@ export class ChangeTracker {
title: string,
value: string | number,
callback: (v: string) => void,
event: CanvasPointerEvent
event: CanvasPointerEvent,
multiline?: boolean
) {
const extendedCallback = (v: string) => {
callback(v)
checkState()
}
logger.debug('checkState on prompt')
return prompt.apply(this, [title, value, extendedCallback, event])
return prompt.apply(this, [
title,
value,
extendedCallback,
event,
multiline
])
}
// Handle litegraph context menu for COMBO widgets