Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions site/test-coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = {
guide: { statements: '3.46%', branches: '0%', functions: '0%', lines: '3.77%' },
hooks: { statements: '69.04%', branches: '34.32%', functions: '71.87%', lines: '70%' },
image: { statements: '97.72%', branches: '100%', functions: '92.3%', lines: '97.61%' },
imageViewer: { statements: '8.47%', branches: '2.87%', functions: '0%', lines: '8.84%' },
imageViewer: { statements: '96.61%', branches: '84.89%', functions: '95.65%', lines: '99.11%' },
indexes: { statements: '95.65%', branches: '69.81%', functions: '100%', lines: '96.94%' },
input: { statements: '3.57%', branches: '0%', functions: '0%', lines: '3.7%' },
layout: { statements: '100%', branches: '100%', functions: '100%', lines: '100%' },
Expand Down Expand Up @@ -55,7 +55,7 @@ module.exports = {
steps: { statements: '100%', branches: '100%', functions: '100%', lines: '100%' },
sticky: { statements: '7.14%', branches: '0%', functions: '0%', lines: '7.27%' },
swipeCell: { statements: '4.42%', branches: '0%', functions: '0%', lines: '4.67%' },
swiper: { statements: '3.77%', branches: '0.9%', functions: '1.4%', lines: '3.89%' },
swiper: { statements: '62.79%', branches: '41.17%', functions: '67.6%', lines: '64.61%' },
switch: { statements: '100%', branches: '100%', functions: '100%', lines: '100%' },
tabBar: { statements: '10%', branches: '0%', functions: '0%', lines: '10.81%' },
table: { statements: '100%', branches: '90%', functions: '100%', lines: '100%' },
Expand Down
357 changes: 357 additions & 0 deletions src/image-viewer/__tests__/index.alignment.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,357 @@
import React from 'react';
import { describe, it, expect, render, fireEvent, act, beforeEach, afterEach } from '@test/utils';
import { vi } from 'vitest';
import { ImageViewer } from '../index';

describe('ImageViewer alignment coverage', () => {
beforeEach(() => {
vi.useFakeTimers();

// Mock image dimensions to trigger alignment calculations
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
configurable: true,
value: 300,
});
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
configurable: true,
value: 400,
});
Object.defineProperty(HTMLElement.prototype, 'clientWidth', {
configurable: true,
value: 300,
});
Object.defineProperty(HTMLElement.prototype, 'clientHeight', {
configurable: true,
value: 400,
});
});

afterEach(() => {
vi.useRealTimers();
});

describe('getMaxDraggedY alignment branches (lines 155-172)', () => {
it(':start alignment calculation', () => {
const alignedImages = [
{ url: 'https://example.com/1.jpg', align: 'start' as const },
];

const { container } = render(
<ImageViewer images={alignedImages} visible />,
);

const img = container.querySelector('.t-image-viewer__img') as HTMLElement;

// Zoom to trigger getMaxDraggedY calculation with start alignment
act(() => {
fireEvent.doubleClick(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

// Drag to trigger alignment calculation
act(() => {
fireEvent.touchStart(img, {
touches: [{ clientX: 150, clientY: 200 }],
});
});

act(() => {
fireEvent.touchMove(img, {
touches: [{ clientX: 150, clientY: 250 }],
});
});

act(() => {
fireEvent.touchEnd(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

expect(img).not.toBeNull();
});

it(':center alignment calculation (default)', () => {
const alignedImages = [
{ url: 'https://example.com/1.jpg', align: 'center' as const },
];

const { container } = render(
<ImageViewer images={alignedImages} visible />,
);

const img = container.querySelector('.t-image-viewer__img') as HTMLElement;

// Zoom to trigger getMaxDraggedY calculation with center alignment
act(() => {
fireEvent.doubleClick(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

// Drag to trigger alignment calculation
act(() => {
fireEvent.touchStart(img, {
touches: [{ clientX: 150, clientY: 200 }],
});
});

act(() => {
fireEvent.touchMove(img, {
touches: [{ clientX: 150, clientY: 250 }],
});
});

act(() => {
fireEvent.touchEnd(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

expect(img).not.toBeNull();
});

it(':end alignment calculation', () => {
const alignedImages = [
{ url: 'https://example.com/1.jpg', align: 'end' as const },
];

const { container } = render(
<ImageViewer images={alignedImages} visible />,
);

const img = container.querySelector('.t-image-viewer__img') as HTMLElement;

// Zoom to trigger getMaxDraggedY calculation with end alignment
act(() => {
fireEvent.doubleClick(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

// Drag to trigger alignment calculation
act(() => {
fireEvent.touchStart(img, {
touches: [{ clientX: 150, clientY: 200 }],
});
});

act(() => {
fireEvent.touchMove(img, {
touches: [{ clientX: 150, clientY: 250 }],
});
});

act(() => {
fireEvent.touchEnd(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

expect(img).not.toBeNull();
});

it(':string image without align defaults to center', () => {
const images = ['https://example.com/1.jpg'];

const { container } = render(
<ImageViewer images={images} visible />,
);

const img = container.querySelector('.t-image-viewer__img') as HTMLElement;

// Zoom to trigger getMaxDraggedY calculation with default center alignment
act(() => {
fireEvent.doubleClick(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

// Drag to trigger alignment calculation
act(() => {
fireEvent.touchStart(img, {
touches: [{ clientX: 150, clientY: 200 }],
});
});

act(() => {
fireEvent.touchMove(img, {
touches: [{ clientX: 150, clientY: 250 }],
});
});

act(() => {
fireEvent.touchEnd(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

expect(img).not.toBeNull();
});

it(':image object without align defaults to center', () => {
const alignedImages = [
{ url: 'https://example.com/1.jpg' }, // No align property
];

const { container } = render(
<ImageViewer images={alignedImages} visible />,
);

const img = container.querySelector('.t-image-viewer__img') as HTMLElement;

// Zoom to trigger getMaxDraggedY calculation with default center alignment
act(() => {
fireEvent.doubleClick(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

// Drag to trigger alignment calculation
act(() => {
fireEvent.touchStart(img, {
touches: [{ clientX: 150, clientY: 200 }],
});
});

act(() => {
fireEvent.touchMove(img, {
touches: [{ clientX: 150, clientY: 250 }],
});
});

act(() => {
fireEvent.touchEnd(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

expect(img).not.toBeNull();
});
});

describe('additional branch coverage', () => {
it(':early return when currentImageScaledHeight <= rootOffsetHeight', () => {
// Mock small image dimensions to trigger early return
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
configurable: true,
value: 100, // Smaller than container
});

const { container } = render(
<ImageViewer images={['https://example.com/small.jpg']} visible />,
);

const img = container.querySelector('.t-image-viewer__img') as HTMLElement;

// Try to zoom and drag - should hit early return in getMaxDraggedY
act(() => {
fireEvent.doubleClick(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

act(() => {
fireEvent.touchStart(img, {
touches: [{ clientX: 150, clientY: 200 }],
});
});

act(() => {
fireEvent.touchMove(img, {
touches: [{ clientX: 150, clientY: 250 }],
});
});

act(() => {
fireEvent.touchEnd(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

expect(img).not.toBeNull();

// Restore
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
configurable: true,
value: 400,
});
});

it(':diffHeight calculation and centerDraggedY', () => {
// Mock larger image to ensure diffHeight > 0
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
configurable: true,
value: 800, // Larger than container
});

const { container } = render(
<ImageViewer images={['https://example.com/large.jpg']} visible />,
);

const img = container.querySelector('.t-image-viewer__img') as HTMLElement;

// Zoom to trigger diffHeight and centerDraggedY calculation
act(() => {
fireEvent.doubleClick(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

// Drag to trigger alignment calculation with diffHeight
act(() => {
fireEvent.touchStart(img, {
touches: [{ clientX: 150, clientY: 200 }],
});
});

act(() => {
fireEvent.touchMove(img, {
touches: [{ clientX: 150, clientY: 100 }],
});
});

act(() => {
fireEvent.touchEnd(img);
});

act(() => {
vi.advanceTimersByTime(20);
});

expect(img).not.toBeNull();

// Restore
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
configurable: true,
value: 400,
});
});
});
});
Loading