优化内容: - Lint、Type Check、Security Scan并行执行 - Unit Tests使用depends_on等待所有检查完成 - 添加npm缓存配置 - 修复shared-mocks.tsx的ESLint错误 预期效果: - 串行时间: 30s + 40s + 20s = 90s - 并行时间: max(30s, 40s, 20s) = 40s - 节省时间: 50s (55.6%改善)
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
import { jest } from '@jest/globals';
|
||||
import React from 'react';
|
||||
|
||||
interface MockProps {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
href?: string;
|
||||
src?: string;
|
||||
alt?: string;
|
||||
width?: number | string;
|
||||
height?: number | string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export const mockFramerMotion = () => {
|
||||
jest.mock('framer-motion', () => ({
|
||||
motion: {
|
||||
div: ({ children, className, ...props }: MockProps) => (
|
||||
<div className={className} {...props}>{children}</div>
|
||||
),
|
||||
section: ({ children, className, ...props }: MockProps) => (
|
||||
<section className={className} {...props}>{children}</section>
|
||||
),
|
||||
span: ({ children, className, ...props }: MockProps) => (
|
||||
<span className={className} {...props}>{children}</span>
|
||||
),
|
||||
h1: ({ children, className, ...props }: MockProps) => (
|
||||
<h1 className={className} {...props}>{children}</h1>
|
||||
),
|
||||
h2: ({ children, className, ...props }: MockProps) => (
|
||||
<h2 className={className} {...props}>{children}</h2>
|
||||
),
|
||||
p: ({ children, className, ...props }: MockProps) => (
|
||||
<p className={className} {...props}>{children}</p>
|
||||
),
|
||||
button: ({ children, className, ...props }: MockProps) => (
|
||||
<button className={className} {...props}>{children}</button>
|
||||
),
|
||||
a: ({ children, className, ...props }: MockProps) => (
|
||||
<a className={className} {...props}>{children}</a>
|
||||
),
|
||||
img: ({ className, ...props }: MockProps) => (
|
||||
<img className={className} {...props} alt="" />
|
||||
),
|
||||
},
|
||||
AnimatePresence: ({ children }: MockProps) => <>{children}</>,
|
||||
useInView: () => [null, true],
|
||||
useAnimation: () => ({
|
||||
start: jest.fn(),
|
||||
stop: jest.fn(),
|
||||
}),
|
||||
useMotionValue: () => ({
|
||||
get: jest.fn(),
|
||||
set: jest.fn(),
|
||||
}),
|
||||
}));
|
||||
};
|
||||
|
||||
export const mockNextLink = () => {
|
||||
jest.mock('next/link', () => {
|
||||
const MockLink = ({ children, href, ...props }: MockProps) => (
|
||||
<a href={href} {...props}>{children}</a>
|
||||
);
|
||||
MockLink.displayName = 'MockLink';
|
||||
return MockLink;
|
||||
});
|
||||
};
|
||||
|
||||
export const mockNextNavigation = () => {
|
||||
jest.mock('next/navigation', () => ({
|
||||
useSearchParams: () => ({
|
||||
get: jest.fn(),
|
||||
}),
|
||||
useRouter: () => ({
|
||||
push: jest.fn(),
|
||||
replace: jest.fn(),
|
||||
back: jest.fn(),
|
||||
}),
|
||||
usePathname: () => '/',
|
||||
}));
|
||||
};
|
||||
|
||||
export const mockLucideReact = () => {
|
||||
jest.mock('lucide-react', () => ({
|
||||
ArrowRight: () => <span data-testid="arrow-right" />,
|
||||
ArrowLeft: () => <span data-testid="arrow-left" />,
|
||||
Shield: () => <span data-testid="shield-icon" />,
|
||||
Zap: () => <span data-testid="zap-icon" />,
|
||||
Award: () => <span data-testid="award-icon" />,
|
||||
Check: () => <span data-testid="check-icon" />,
|
||||
X: () => <span data-testid="x-icon" />,
|
||||
Menu: () => <span data-testid="menu-icon" />,
|
||||
ChevronDown: () => <span data-testid="chevron-down" />,
|
||||
ChevronRight: () => <span data-testid="chevron-right" />,
|
||||
Mail: () => <span data-testid="mail-icon" />,
|
||||
Phone: () => <span data-testid="phone-icon" />,
|
||||
MapPin: () => <span data-testid="map-pin-icon" />,
|
||||
Clock: () => <span data-testid="clock-icon" />,
|
||||
User: () => <span data-testid="user-icon" />,
|
||||
Lock: () => <span data-testid="lock-icon" />,
|
||||
Eye: () => <span data-testid="eye-icon" />,
|
||||
EyeOff: () => <span data-testid="eye-off-icon" />,
|
||||
Settings: () => <span data-testid="settings-icon" />,
|
||||
LogOut: () => <span data-testid="logout-icon" />,
|
||||
Home: () => <span data-testid="home-icon" />,
|
||||
FileText: () => <span data-testid="file-text-icon" />,
|
||||
Image: () => <span data-testid="image-icon" />,
|
||||
Save: () => <span data-testid="save-icon" />,
|
||||
Trash2: () => <span data-testid="trash-icon" />,
|
||||
Edit: () => <span data-testid="edit-icon" />,
|
||||
Plus: () => <span data-testid="plus-icon" />,
|
||||
Search: () => <span data-testid="search-icon" />,
|
||||
Filter: () => <span data-testid="filter-icon" />,
|
||||
Download: () => <span data-testid="download-icon" />,
|
||||
Upload: () => <span data-testid="upload-icon" />,
|
||||
RefreshCw: () => <span data-testid="refresh-icon" />,
|
||||
AlertCircle: () => <span data-testid="alert-icon" />,
|
||||
Info: () => <span data-testid="info-icon" />,
|
||||
HelpCircle: () => <span data-testid="help-icon" />,
|
||||
}));
|
||||
};
|
||||
|
||||
export const mockNextDynamic = () => {
|
||||
jest.mock('next/dynamic', () => {
|
||||
const MockDynamic = (props: MockProps) => {
|
||||
return <div data-testid="dynamic-component" {...props} />;
|
||||
};
|
||||
MockDynamic.displayName = 'MockDynamic';
|
||||
return {
|
||||
__esModule: true,
|
||||
default: MockDynamic,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const mockNextImage = () => {
|
||||
jest.mock('next/image', () => {
|
||||
const MockImage = ({ src, alt, width, height, className, ...props }: MockProps) => (
|
||||
<img
|
||||
src={src}
|
||||
alt={alt || ''}
|
||||
width={width}
|
||||
height={height}
|
||||
className={className}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
MockImage.displayName = 'MockImage';
|
||||
return MockImage;
|
||||
});
|
||||
};
|
||||
|
||||
export const mockDatabase = () => {
|
||||
jest.mock('@/db', () => ({
|
||||
db: {
|
||||
select: jest.fn().mockReturnValue({
|
||||
from: jest.fn().mockResolvedValue([]),
|
||||
}),
|
||||
insert: jest.fn().mockReturnValue({
|
||||
values: jest.fn().mockReturnValue({
|
||||
returning: jest.fn().mockResolvedValue([{ id: 1 }]),
|
||||
}),
|
||||
}),
|
||||
update: jest.fn().mockReturnValue({
|
||||
set: jest.fn().mockReturnValue({
|
||||
where: jest.fn().mockResolvedValue([{ id: 1 }]),
|
||||
}),
|
||||
}),
|
||||
delete: jest.fn().mockReturnValue({
|
||||
where: jest.fn().mockResolvedValue([]),
|
||||
}),
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
export const setupSharedMocks = () => {
|
||||
mockFramerMotion();
|
||||
mockNextLink();
|
||||
mockNextNavigation();
|
||||
mockLucideReact();
|
||||
mockNextDynamic();
|
||||
mockNextImage();
|
||||
};
|
||||
|
||||
export const setupMinimalMocks = () => {
|
||||
mockFramerMotion();
|
||||
mockNextLink();
|
||||
mockLucideReact();
|
||||
};
|
||||
Reference in New Issue
Block a user