mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-04 12:57:39 +08:00
🐛 fix(i18n): 收口 dev 合并后的业务提示多语言遗漏
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
import { setCurrentLanguage, t } from '../i18n';
|
||||
import {
|
||||
formatExportElapsed,
|
||||
formatExportProgressRows,
|
||||
@@ -9,6 +10,10 @@ import {
|
||||
} from './exportProgress';
|
||||
|
||||
describe('exportProgress', () => {
|
||||
afterEach(() => {
|
||||
setCurrentLanguage('zh-CN');
|
||||
});
|
||||
|
||||
it('uses actual percent when total row count is known', () => {
|
||||
expect(resolveExportProgressPercent('running', 25, 100, true)).toBe(25);
|
||||
});
|
||||
@@ -21,15 +26,26 @@ describe('exportProgress', () => {
|
||||
});
|
||||
|
||||
it('falls back to indeterminate progress when total row hint is zero', () => {
|
||||
setCurrentLanguage('en-US');
|
||||
expect(resolveExportProgressPercent('running', 754000, 0, true)).toBe(0);
|
||||
expect(shouldUseExactExportProgress('running', 0, true)).toBe(false);
|
||||
expect(shouldUseIndeterminateExportProgress('running', 0, true)).toBe(true);
|
||||
expect(formatExportProgressRows(754000, 0, true)).toBe('已写入 754,000 行');
|
||||
expect(formatExportProgressRows(754000, 0, true)).toBe(
|
||||
t('data_export.progress.rows_written', { current: '754,000' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('formats row summary for known and unknown totals', () => {
|
||||
expect(formatExportProgressRows(12345, 0, false)).toBe('已写入 12,345 行');
|
||||
expect(formatExportProgressRows(12345, 880000, true)).toBe('已写入 12,345 / 880,000 行');
|
||||
it('formats row summary with localized text and number separators', () => {
|
||||
setCurrentLanguage('de-DE');
|
||||
expect(formatExportProgressRows(12345, 0, false)).toBe(
|
||||
t('data_export.progress.rows_written', { current: '12.345' }),
|
||||
);
|
||||
expect(formatExportProgressRows(12345, 880000, true)).toBe(
|
||||
t('data_export.progress.rows_written_with_total', {
|
||||
current: '12.345',
|
||||
total: '880.000',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('resolves and formats elapsed export duration', () => {
|
||||
@@ -38,4 +54,12 @@ describe('exportProgress', () => {
|
||||
expect(formatExportElapsed(30_500)).toBe('00:30');
|
||||
expect(formatExportElapsed(3_723_000)).toBe('01:02:03');
|
||||
});
|
||||
|
||||
it('keeps export progress source free of hard-coded Chinese row summaries', async () => {
|
||||
const { readFileSync } = await import('node:fs');
|
||||
const source = readFileSync(new URL('./exportProgress.ts', import.meta.url), 'utf8');
|
||||
|
||||
expect(source).not.toContain('已写入 ');
|
||||
expect(source).not.toContain("Intl.NumberFormat('zh-CN')");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { getCurrentLanguage, t } from '../i18n';
|
||||
|
||||
export type ExportProgressStatus = 'idle' | 'start' | 'running' | 'finalizing' | 'done' | 'error';
|
||||
|
||||
const hasUsableExportTotal = (total: number, totalRowsKnown: boolean): boolean => {
|
||||
@@ -54,13 +56,16 @@ export const formatExportProgressRows = (
|
||||
total: number,
|
||||
totalRowsKnown: boolean,
|
||||
): string => {
|
||||
const formatter = new Intl.NumberFormat('zh-CN');
|
||||
const formatter = new Intl.NumberFormat(getCurrentLanguage());
|
||||
const safeCurrent = formatter.format(Math.max(0, Math.trunc(Number(current) || 0)));
|
||||
if (!hasUsableExportTotal(total, totalRowsKnown)) {
|
||||
return `已写入 ${safeCurrent} 行`;
|
||||
return t('data_export.progress.rows_written', { current: safeCurrent });
|
||||
}
|
||||
const safeTotal = formatter.format(Math.max(0, Math.trunc(Number(total) || 0)));
|
||||
return `已写入 ${safeCurrent} / ${safeTotal} 行`;
|
||||
return t('data_export.progress.rows_written_with_total', {
|
||||
current: safeCurrent,
|
||||
total: safeTotal,
|
||||
});
|
||||
};
|
||||
|
||||
export const resolveExportElapsedMs = (
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
import { setCurrentLanguage, t } from '../i18n'
|
||||
import { buildSqlAnalysisWorkbenchTab, resolveSqlAnalysisWorkbenchTabId } from './sqlAnalysisTab'
|
||||
|
||||
describe('sqlAnalysisTab', () => {
|
||||
afterEach(() => {
|
||||
setCurrentLanguage('zh-CN')
|
||||
})
|
||||
|
||||
it('builds a stable workbench tab per connection and database', () => {
|
||||
expect(resolveSqlAnalysisWorkbenchTabId('conn-1', 'analytics')).toBe('sql-analysis-conn-1-analytics')
|
||||
expect(resolveSqlAnalysisWorkbenchTabId('conn-1')).toBe('sql-analysis-conn-1-default')
|
||||
@@ -18,7 +23,7 @@ describe('sqlAnalysisTab', () => {
|
||||
|
||||
expect(tab).toMatchObject({
|
||||
id: 'sql-analysis-conn-1-analytics',
|
||||
title: 'SQL 分析 · analytics',
|
||||
title: t('sql_analysis.workbench.tab_title_with_database', { database: 'analytics' }),
|
||||
type: 'sql-analysis',
|
||||
connectionId: 'conn-1',
|
||||
dbName: 'analytics',
|
||||
@@ -39,4 +44,28 @@ describe('sqlAnalysisTab', () => {
|
||||
expect(tab.sqlAnalysisView).toBe('slow-query')
|
||||
expect(tab.sqlAnalysisRequestKey).toBe('slow-1')
|
||||
})
|
||||
|
||||
it('localizes default sql analysis tab titles', () => {
|
||||
setCurrentLanguage('en-US')
|
||||
|
||||
expect(buildSqlAnalysisWorkbenchTab({
|
||||
connectionId: 'conn-1',
|
||||
dbName: 'analytics',
|
||||
}).title).toBe(
|
||||
t('sql_analysis.workbench.tab_title_with_database', { database: 'analytics' }),
|
||||
)
|
||||
expect(buildSqlAnalysisWorkbenchTab({
|
||||
connectionId: 'conn-1',
|
||||
}).title).toBe(
|
||||
t('sql_analysis.workbench.tab_title'),
|
||||
)
|
||||
})
|
||||
|
||||
it('keeps sql analysis tab source free of hard-coded Chinese titles', async () => {
|
||||
const { readFileSync } = await import('node:fs')
|
||||
const source = readFileSync(new URL('./sqlAnalysisTab.ts', import.meta.url), 'utf8')
|
||||
|
||||
expect(source).not.toContain('SQL 分析 ·')
|
||||
expect(source).not.toContain("'SQL 分析'")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { TabData } from '../types'
|
||||
import { t } from '../i18n'
|
||||
|
||||
export type SqlAnalysisView = 'diagnose' | 'slow-query'
|
||||
|
||||
@@ -26,12 +27,15 @@ export const buildSqlAnalysisWorkbenchTab = (
|
||||
const connectionId = String(input.connectionId || '').trim()
|
||||
const dbName = String(input.dbName || '').trim()
|
||||
const view = input.view === 'slow-query' ? 'slow-query' : 'diagnose'
|
||||
const title = String(input.title || (dbName ? `SQL 分析 · ${dbName}` : 'SQL 分析')).trim()
|
||||
const defaultTitle = dbName
|
||||
? t('sql_analysis.workbench.tab_title_with_database', { database: dbName })
|
||||
: t('sql_analysis.workbench.tab_title')
|
||||
const title = String(input.title || defaultTitle).trim()
|
||||
const query = typeof input.query === 'string' ? input.query : ''
|
||||
|
||||
return {
|
||||
id: resolveSqlAnalysisWorkbenchTabId(connectionId, dbName || undefined),
|
||||
title: title || (dbName ? `SQL 分析 · ${dbName}` : 'SQL 分析'),
|
||||
title: title || defaultTitle,
|
||||
type: 'sql-analysis',
|
||||
connectionId,
|
||||
...(dbName ? { dbName } : {}),
|
||||
|
||||
Reference in New Issue
Block a user