fix: mock next/font in tests and remove broken shared export
This commit is contained in:
@@ -0,0 +1,48 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import { formatYearRange } from './formatDate';
|
||||||
|
|
||||||
|
describe('formatYearRange', () => {
|
||||||
|
describe('Success Paths', () => {
|
||||||
|
it('formats a date range within the same year', () => {
|
||||||
|
const start = '2024-01-01 12:00:00.000Z';
|
||||||
|
const end = '2024-12-31 12:00:00.000Z';
|
||||||
|
expect(formatYearRange(start, end)).toBe('2024');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats a range between different years', () => {
|
||||||
|
const start = '2021-05-15 12:00:00.000Z';
|
||||||
|
const end = '2024-03-20 12:00:00.000Z';
|
||||||
|
expect(formatYearRange(start, end)).toBe('2021 — 2024');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('formats a range with null end date as "Present"', () => {
|
||||||
|
const start = '2022-08-01 12:00:00.000Z';
|
||||||
|
const end = null;
|
||||||
|
expect(formatYearRange(start, end)).toBe('2022 — Present');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Error & Edge Cases', () => {
|
||||||
|
it('throws if start date is invalid', () => {
|
||||||
|
const start = 'not-a-date';
|
||||||
|
const end = '2024-01-01';
|
||||||
|
expect(() => formatYearRange(start, end)).toThrow('Invalid start date');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws if end date is provided but invalid', () => {
|
||||||
|
const start = '2024-01-01';
|
||||||
|
const end = 'invalid';
|
||||||
|
expect(() => formatYearRange(start, end)).toThrow('Invalid end date');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws if start year is after end year', () => {
|
||||||
|
const start = '2024-01-01';
|
||||||
|
const end = '2020-01-01';
|
||||||
|
expect(() => formatYearRange(start, end)).toThrow('Start year cannot be after end year');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles empty strings by throwing', () => {
|
||||||
|
expect(() => formatYearRange('', null)).toThrow('Invalid start date');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Formats a PocketBase date string into a localized year string or "Present".
|
||||||
|
* @throws {Error} if any date is invalid or if the range is logically impossible.
|
||||||
|
*/
|
||||||
|
export function formatYearRange(start: string, end: string | null): string {
|
||||||
|
const startDate = new Date(start);
|
||||||
|
if (Number.isNaN(startDate.getTime())) {
|
||||||
|
throw new Error('Invalid start date');
|
||||||
|
}
|
||||||
|
const startYear = startDate.getFullYear();
|
||||||
|
|
||||||
|
if (end === null) {
|
||||||
|
return `${startYear} — Present`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const endDate = new Date(end);
|
||||||
|
if (Number.isNaN(endDate.getTime())) {
|
||||||
|
throw new Error('Invalid end date');
|
||||||
|
}
|
||||||
|
const endYear = endDate.getFullYear();
|
||||||
|
|
||||||
|
if (startYear > endYear) {
|
||||||
|
throw new Error('Start year cannot be after end year');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startYear === endYear) {
|
||||||
|
return `${startYear}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${startYear} — ${endYear}`;
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
export { cn } from './cn';
|
|
||||||
export type { ClassValue } from 'clsx';
|
export type { ClassValue } from 'clsx';
|
||||||
|
export { cn } from './cn';
|
||||||
export * from './fonts';
|
export * from './fonts';
|
||||||
|
export * from './formatDate';
|
||||||
|
|||||||
+5
-10
@@ -1,17 +1,12 @@
|
|||||||
export { Badge } from './Badge';
|
|
||||||
export type { BadgeVariant } from './Badge';
|
export type { BadgeVariant } from './Badge';
|
||||||
|
export { Badge } from './Badge';
|
||||||
|
export type { ButtonSize, ButtonVariant } from './Button';
|
||||||
export { Button } from './Button';
|
export { Button } from './Button';
|
||||||
export type { ButtonVariant, ButtonSize } from './Button';
|
|
||||||
|
|
||||||
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from './Card';
|
|
||||||
export type { CardBackground } from './Card';
|
export type { CardBackground } from './Card';
|
||||||
|
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './Card';
|
||||||
|
|
||||||
export { Input, Textarea } from './Input';
|
export { Input, Textarea } from './Input';
|
||||||
|
export type { ContainerSize, SectionBackground } from './Section';
|
||||||
export { Section, Container } from './Section';
|
export { Container, Section } from './Section';
|
||||||
export type { SectionBackground, ContainerSize } from './Section';
|
|
||||||
|
|
||||||
export { SectionAccordion } from './SectionAccordion';
|
|
||||||
|
|
||||||
export { TechStackBrick, TechStackGrid } from './TechStack';
|
export { TechStackBrick, TechStackGrid } from './TechStack';
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { vi } from 'vitest';
|
||||||
|
|
||||||
|
const mockFont = () => ({
|
||||||
|
variable: '--font-mock',
|
||||||
|
className: 'mock-font',
|
||||||
|
style: { fontFamily: 'mock-font' },
|
||||||
|
});
|
||||||
|
|
||||||
|
vi.mock('next/font/google', () => ({
|
||||||
|
Fraunces: mockFont,
|
||||||
|
Public_Sans: mockFont,
|
||||||
|
}));
|
||||||
@@ -1 +1,2 @@
|
|||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
|
import './__mocks__/next-font-google';
|
||||||
|
|||||||
Reference in New Issue
Block a user