import { HeroSlider } from './HeroSlider' const mockActivities = [ { id: '1', title: '活动标题1', titleEn: 'Activity Title 1', desc: '活动描述1', descEn: 'Activity Description 1', coverUrl: 'https://example.com/image1.jpg', link: '/activity/1', }, { id: '2', title: '活动标题2', desc: '活动描述2', coverUrl: 'https://example.com/image2.jpg', link: '/activity/2', }, ] describe('HeroSlider Component', () => { describe('Component Export', () => { it('should be defined', () => { expect(HeroSlider).toBeDefined() }) it('should be a function component', () => { expect(typeof HeroSlider).toBe('function') }) }) describe('Props Interface', () => { it('should accept activities prop', () => { const props = { activities: mockActivities } expect(props.activities).toEqual(mockActivities) expect(props.activities.length).toBe(2) }) it('should accept onActivityPress callback', () => { const onActivityPress = jest.fn() expect(typeof onActivityPress).toBe('function') }) it('should have activity with required fields', () => { const activity = mockActivities[0] expect(activity.id).toBeDefined() expect(activity.title).toBeDefined() expect(activity.desc).toBeDefined() expect(activity.coverUrl).toBeDefined() expect(activity.link).toBeDefined() }) it('should have activity with optional fields', () => { const activity = mockActivities[0] expect(activity.titleEn).toBeDefined() expect(activity.descEn).toBeDefined() }) }) describe('Empty State', () => { it('should return null when activities is empty array', () => { const result = HeroSlider({ activities: [] }) expect(result).toBeNull() }) it('should return null when activities is undefined', () => { const result = HeroSlider({ activities: undefined as any }) expect(result).toBeNull() }) }) describe('Render Behavior', () => { it('should return JSX element when activities has items', () => { const result = HeroSlider({ activities: mockActivities }) expect(result).not.toBeNull() }) }) describe('Callback Behavior', () => { it('should call onActivityPress with link when activity is pressed', () => { const onActivityPress = jest.fn() const props: { activities: typeof mockActivities; onActivityPress?: (link: string) => void } = { activities: mockActivities, onActivityPress, } // Verify callback can be invoked with link props.onActivityPress(mockActivities[0].link) expect(onActivityPress).toHaveBeenCalledWith('/activity/1') }) it('should not throw when onActivityPress is not provided', () => { const props: { activities: typeof mockActivities; onActivityPress?: (link: string) => void } = { activities: mockActivities } expect(() => { if (props.onActivityPress) { props.onActivityPress(mockActivities[0].link) } }).not.toThrow() }) }) describe('Slider Layout', () => { it('should have fixed width for slide container to enable horizontal scrolling', () => { const { StyleSheet } = require('react-native') const { HeroSlider } = require('./HeroSlider') // 读取组件文件内容来验证样式定义 const fs = require('fs') const path = require('path') const componentPath = path.join(__dirname, 'HeroSlider.tsx') const componentContent = fs.readFileSync(componentPath, 'utf-8') // 验证 heroMainSlide 样式包含固定宽度265 expect(componentContent).toContain('heroMainSlide: {') expect(componentContent).toContain('width: 265') // 验证不包含 width: '100%' const heroMainSlideMatch = componentContent.match(/heroMainSlide:\s*{[^}]*}/s) expect(heroMainSlideMatch).toBeTruthy() expect(heroMainSlideMatch![0]).not.toContain("width: '100%'") }) }) })