Skip to content

Commit 9d3220f

Browse files
committed
Add unit tests to relative time component
1 parent 9699fd6 commit 9d3220f

3 files changed

Lines changed: 129 additions & 1 deletion

File tree

.github/codeql/codeql-config.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
name: CodeQL config
22

3-
# Unavoidable checkoutin untrusted environment to use
3+
# Unavoidable checkout in untrusted environment to use
44
# "astro db verify" and "astro db push --remote" commands
5+
# @see PR https://github.com/withastro/astro/pull/15069
56
paths-ignore:
67
- .github/workflows/deployment-preview.yml
78
- .github/workflows/deployment-production.yml
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// @vitest-environment node
2+
3+
import { beforeEach, describe, expect, test, vi } from 'vitest'
4+
import { experimental_AstroContainer as AstroContainer } from 'astro/container'
5+
import { withJsdomEnvironment } from '@test/unit/helpers/litRuntime'
6+
7+
describe('Time (Astro)', () => {
8+
let container: AstroContainer
9+
10+
beforeEach(async () => {
11+
container = await AstroContainer.create()
12+
})
13+
14+
test('renders a <relative-time> element and keeps slot fallback content', async () => {
15+
const Time = (await import('@components/Time/index.astro')).default
16+
17+
const renderedHtml = await container.renderToString(Time, {
18+
props: {
19+
format: 'relative',
20+
datetime: '2020-01-01T00:00:00Z',
21+
},
22+
slots: {
23+
default: 'Fallback text',
24+
},
25+
})
26+
27+
await withJsdomEnvironment(async ({ window }) => {
28+
window.document.body.innerHTML = renderedHtml
29+
30+
const element = window.document.querySelector('relative-time')
31+
expect(element).toBeTruthy()
32+
expect(element?.getAttribute('datetime')).toBe('2020-01-01T00:00:00Z')
33+
expect(element?.textContent).toContain('Fallback text')
34+
})
35+
})
36+
37+
test('serializes Date datetime to ISO string', async () => {
38+
const Time = (await import('@components/Time/index.astro')).default
39+
const date = new Date('2024-02-29T12:34:56.000Z')
40+
41+
const renderedHtml = await container.renderToString(Time, {
42+
props: {
43+
format: 'datetime',
44+
datetime: date,
45+
},
46+
})
47+
48+
await withJsdomEnvironment(async ({ window }) => {
49+
window.document.body.innerHTML = renderedHtml
50+
51+
const element = window.document.querySelector('relative-time')
52+
expect(element?.getAttribute('datetime')).toBe('2024-02-29T12:34:56.000Z')
53+
})
54+
})
55+
56+
test('uses current time when now=true and datetime is omitted', async () => {
57+
vi.useFakeTimers()
58+
vi.setSystemTime(new Date('2030-01-02T03:04:05.000Z'))
59+
60+
try {
61+
const Time = (await import('@components/Time/index.astro')).default
62+
63+
const renderedHtml = await container.renderToString(Time, {
64+
props: {
65+
format: 'relative',
66+
now: true,
67+
},
68+
})
69+
70+
await withJsdomEnvironment(async ({ window }) => {
71+
window.document.body.innerHTML = renderedHtml
72+
73+
const element = window.document.querySelector('relative-time')
74+
expect(element?.getAttribute('datetime')).toBe('2030-01-02T03:04:05.000Z')
75+
})
76+
} finally {
77+
vi.useRealTimers()
78+
}
79+
})
80+
81+
test('maps formatStyle and timeZoneName to kebab-case attributes', async () => {
82+
const Time = (await import('@components/Time/index.astro')).default
83+
84+
const renderedHtml = await container.renderToString(Time, {
85+
props: {
86+
format: 'datetime',
87+
datetime: '2020-01-01T00:00:00Z',
88+
formatStyle: 'short',
89+
timeZoneName: 'shortOffset',
90+
},
91+
})
92+
93+
await withJsdomEnvironment(async ({ window }) => {
94+
window.document.body.innerHTML = renderedHtml
95+
96+
const element = window.document.querySelector('relative-time')
97+
expect(element?.getAttribute('format-style')).toBe('short')
98+
expect(element?.getAttribute('time-zone-name')).toBe('shortOffset')
99+
})
100+
})
101+
102+
test('passes through supported attributes to <relative-time>', async () => {
103+
const Time = (await import('@components/Time/index.astro')).default
104+
105+
const renderedHtml = await container.renderToString(Time, {
106+
props: {
107+
format: 'relative',
108+
datetime: '2020-01-01T00:00:00Z',
109+
tense: 'past',
110+
precision: 'day',
111+
threshold: 'P1D',
112+
prefix: 'about',
113+
},
114+
})
115+
116+
await withJsdomEnvironment(async ({ window }) => {
117+
window.document.body.innerHTML = renderedHtml
118+
119+
const element = window.document.querySelector('relative-time')
120+
expect(element?.getAttribute('format')).toBe('relative')
121+
expect(element?.getAttribute('tense')).toBe('past')
122+
expect(element?.getAttribute('precision')).toBe('day')
123+
expect(element?.getAttribute('threshold')).toBe('P1D')
124+
expect(element?.getAttribute('prefix')).toBe('about')
125+
})
126+
})
127+
})

src/components/Time/client/__tests__/index.spec.ts

Whitespace-only changes.

0 commit comments

Comments
 (0)