mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 02:11:28 +00:00
test(ui): cover bounded code editor scroll mode
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
const boundedConsumers = [
|
||||
{
|
||||
file: 'src/pages/cliproxy-ai-providers.tsx',
|
||||
expectedCount: 2,
|
||||
},
|
||||
{
|
||||
file: 'src/components/cliproxy/provider-editor/raw-editor-section.tsx',
|
||||
expectedCount: 1,
|
||||
},
|
||||
{
|
||||
file: 'src/components/profiles/editor/raw-editor-section.tsx',
|
||||
expectedCount: 1,
|
||||
},
|
||||
{
|
||||
file: 'src/components/copilot/config-form/raw-editor-section.tsx',
|
||||
expectedCount: 1,
|
||||
},
|
||||
{
|
||||
file: 'src/components/compatible-cli/raw-json-settings-editor-panel.tsx',
|
||||
expectedCount: 1,
|
||||
},
|
||||
{
|
||||
file: 'src/components/shared/settings-dialog.tsx',
|
||||
expectedCount: 1,
|
||||
},
|
||||
] as const;
|
||||
|
||||
describe('bounded CodeEditor consumers', () => {
|
||||
it.each(boundedConsumers)('$file opts into fill-parent mode for every bounded editor', ({
|
||||
file,
|
||||
expectedCount,
|
||||
}) => {
|
||||
const source = readFileSync(resolve(process.cwd(), file), 'utf8');
|
||||
const matches = source.match(/heightMode="fill-parent"/g) ?? [];
|
||||
|
||||
expect(matches).toHaveLength(expectedCount);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { render, screen } from '@tests/setup/test-utils';
|
||||
|
||||
import { CodeEditor } from '@/components/shared/code-editor';
|
||||
|
||||
vi.mock('@/hooks/use-theme', () => ({
|
||||
useTheme: () => ({ isDark: false }),
|
||||
}));
|
||||
|
||||
describe('CodeEditor', () => {
|
||||
it('creates an internal scroll viewport in fill-parent mode and keeps status outside it', () => {
|
||||
const { container } = render(
|
||||
<CodeEditor
|
||||
value={'{\n "provider": "openrouter"\n}'}
|
||||
onChange={vi.fn()}
|
||||
language="json"
|
||||
minHeight="100%"
|
||||
heightMode="fill-parent"
|
||||
/>
|
||||
);
|
||||
|
||||
const viewport = container.querySelector('[data-slot="code-editor-viewport"]');
|
||||
|
||||
expect(viewport).toBeInTheDocument();
|
||||
expect(viewport).toHaveStyle({ height: '100%' });
|
||||
expect(viewport).not.toContainElement(screen.getByText('Valid JSON'));
|
||||
});
|
||||
|
||||
it('keeps readonly status outside the scroll viewport for bounded editors', () => {
|
||||
const { container } = render(
|
||||
<CodeEditor
|
||||
value={'{\n "provider": "openrouter"\n}'}
|
||||
onChange={vi.fn()}
|
||||
language="json"
|
||||
readonly
|
||||
minHeight="calc(60vh - 120px)"
|
||||
heightMode="fill-parent"
|
||||
/>
|
||||
);
|
||||
|
||||
const viewport = container.querySelector('[data-slot="code-editor-viewport"]');
|
||||
const textarea = container.querySelector('textarea');
|
||||
|
||||
expect(viewport).toHaveStyle({ height: 'calc(60vh - 120px)' });
|
||||
expect(textarea).toBeDisabled();
|
||||
expect(viewport).not.toContainElement(screen.getByText('(Read-only)'));
|
||||
});
|
||||
|
||||
it('preserves content mode as the default layout contract', () => {
|
||||
const { container } = render(
|
||||
<CodeEditor
|
||||
value={'{\n "provider": "openrouter"\n}'}
|
||||
onChange={vi.fn()}
|
||||
language="json"
|
||||
/>
|
||||
);
|
||||
|
||||
expect(container.querySelector('[data-slot="code-editor-viewport"]')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user