/**
* @vitest-environment happy-dom
*/
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { render } from '@testing-library/react';
import React from 'react';
import { ErrorBoundary } from '../../../components/common/ErrorBoundary.js';
import { Text, Box } from 'ink';
import { Window } from 'happy-dom';
// Component that throws an error
const ThrowError = ({ shouldThrow }: { shouldThrow: boolean }) => {
if (shouldThrow) {
throw new Error('Test error message');
}
return No error;
};
describe('ErrorBoundary', () => {
beforeEach(() => {
// Setup happy-dom
const window = new Window();
globalThis.window = window as any;
globalThis.document = window.document as any;
// Suppress console.error for expected errors in tests
vi.spyOn(console, 'error').mockImplementation(() => {});
});
it('should render children when no error occurs', () => {
const { getByText } = render(
);
expect(getByText('No error')).toBeDefined();
});
it('should catch errors and display error message', () => {
const { getByText } = render(
);
expect(getByText(/Error:/)).toBeDefined();
expect(getByText(/Test error message/)).toBeDefined();
});
it('should display custom fallback when provided', () => {
const CustomFallback = ({ error }: { error: Error }) => (
Custom Error: {error.message}
);
const { getByText } = render(
);
expect(getByText(/Custom Error:/)).toBeDefined();
expect(getByText(/Test error message/)).toBeDefined();
});
it('should reset error state when children change', () => {
const { rerender, getByText } = render(
);
// Error is shown
expect(getByText(/Error:/)).toBeDefined();
// Rerender with non-throwing component
rerender(
);
// Original children should be rendered
expect(getByText('No error')).toBeDefined();
});
it('should handle errors with no message', () => {
const ThrowNoMessage = () => {
throw new Error();
};
const { getByText } = render(
);
expect(getByText(/Error:/)).toBeDefined();
expect(getByText(/Unknown error/)).toBeDefined();
});
});