-
-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import { render, waitFor } from "@testing-library/svelte"; | ||
import userEvent from "@testing-library/user-event"; | ||
import { axe } from "jest-axe"; | ||
import { describe, it } from "vitest"; | ||
import { testKbd as kbd } from "../utils.js"; | ||
import CalendarTest from "./CalendarTest.svelte"; | ||
import type { Calendar } from "$lib"; | ||
import { CalendarDate, CalendarDateTime, toZoned } from "@internationalized/date"; | ||
import { tick } from "svelte"; | ||
|
||
const calendarDate = new CalendarDate(1980, 1, 20); | ||
const calendarDateTime = new CalendarDateTime(1980, 1, 20, 12, 30, 0, 0); | ||
const zonedDateTime = toZoned(calendarDateTime, "America/New_York"); | ||
|
||
const narrowWeekdays = ["S", "M", "T", "W", "T", "F", "S"]; | ||
const shortWeekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; | ||
const longWeekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; | ||
// prettier-ignore | ||
const months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October" ,"November", "December"]; | ||
|
||
function setup(props: Calendar.Props = {}) { | ||
const user = userEvent.setup(); | ||
const returned = render(CalendarTest, { ...props }); | ||
const calendar = returned.getByTestId("calendar"); | ||
expect(calendar).toBeVisible(); | ||
return { ...returned, user, calendar }; | ||
} | ||
|
||
describe("Calendar", () => { | ||
it("has no accessibility violations", async () => { | ||
const { container } = render(CalendarTest); | ||
expect(await axe(container)).toHaveNoViolations(); | ||
}); | ||
|
||
it("respects a default value if provided - `CalendarDate`", async () => { | ||
const { calendar, getByTestId } = setup({ value: calendarDate }); | ||
|
||
const selectedDay = calendar.querySelector("[data-selected]"); | ||
expect(selectedDay).toHaveTextContent(String(calendarDate.day)); | ||
|
||
expect(getByTestId("heading")).toHaveTextContent("January 1980"); | ||
}); | ||
|
||
it("respects a default value if provided - `CalendarDateTime`", async () => { | ||
const { calendar, getByTestId } = setup({ value: calendarDateTime }); | ||
|
||
const selectedDay = calendar.querySelector("[data-selected]"); | ||
expect(selectedDay).toHaveTextContent(String(calendarDateTime.day)); | ||
|
||
expect(getByTestId("heading")).toHaveTextContent("January 1980"); | ||
}); | ||
|
||
it("respects a default value if provided - `ZonedDateTime`", async () => { | ||
const { calendar, getByTestId } = setup({ value: zonedDateTime }); | ||
|
||
const selectedDay = calendar.querySelector("[data-selected]"); | ||
expect(selectedDay).toHaveTextContent(String(zonedDateTime.day)); | ||
|
||
expect(getByTestId("heading")).toHaveTextContent("January 1980"); | ||
}); | ||
|
||
it("properly binds to `value` - `CalendarDate`", async () => { | ||
const { getByTestId, user } = setup({ value: calendarDate }); | ||
|
||
const addDayBtn = getByTestId("add-day"); | ||
await user.click(addDayBtn); | ||
const valueEl = getByTestId("value"); | ||
expect(valueEl).toHaveTextContent("1980-01-21"); | ||
|
||
const addMonthBtn = getByTestId("add-month"); | ||
await user.click(addMonthBtn); | ||
expect(valueEl).toHaveTextContent("1980-02-21"); | ||
|
||
const addYearBtn = getByTestId("add-year"); | ||
await user.click(addYearBtn); | ||
expect(valueEl).toHaveTextContent("1981-02-21"); | ||
}); | ||
|
||
it("properly binds to `value` - `CalendarDateTime`", async () => { | ||
const { getByTestId, user } = setup({ value: calendarDateTime }); | ||
|
||
const addDayBtn = getByTestId("add-day"); | ||
await user.click(addDayBtn); | ||
const valueEl = getByTestId("value"); | ||
expect(valueEl).toHaveTextContent("1980-01-21"); | ||
|
||
const addMonthBtn = getByTestId("add-month"); | ||
await user.click(addMonthBtn); | ||
expect(valueEl).toHaveTextContent("1980-02-21"); | ||
|
||
const addYearBtn = getByTestId("add-year"); | ||
await user.click(addYearBtn); | ||
expect(valueEl).toHaveTextContent("1981-02-21"); | ||
}); | ||
|
||
it("properly binds to `value` - `ZonedDateTime`", async () => { | ||
const { getByTestId, user } = setup({ value: zonedDateTime }); | ||
|
||
const addDayBtn = getByTestId("add-day"); | ||
await user.click(addDayBtn); | ||
const valueEl = getByTestId("value"); | ||
expect(valueEl).toHaveTextContent("1980-01-21"); | ||
|
||
const addMonthBtn = getByTestId("add-month"); | ||
await user.click(addMonthBtn); | ||
expect(valueEl).toHaveTextContent("1980-02-21"); | ||
|
||
const addYearBtn = getByTestId("add-year"); | ||
await user.click(addYearBtn); | ||
expect(valueEl).toHaveTextContent("1981-02-21"); | ||
}); | ||
|
||
it("navigates the months forward using the next button", async () => { | ||
const { getByTestId, user } = setup({ value: calendarDate }); | ||
|
||
const heading = getByTestId("heading"); | ||
const nextBtn = getByTestId("next-button"); | ||
|
||
for (const month of months) { | ||
expect(heading).toHaveTextContent(month + " 1980"); | ||
await user.click(nextBtn); | ||
} | ||
expect(heading).toHaveTextContent("January 1981"); | ||
}); | ||
|
||
it("navigates the months backwards using the prev button", async () => { | ||
const { getByTestId, user } = setup({ value: calendarDate }); | ||
|
||
const heading = getByTestId("heading"); | ||
const prevBtn = getByTestId("prev-button"); | ||
const newMonths = [...months].reverse(); | ||
newMonths.pop(); | ||
|
||
expect(heading).toHaveTextContent("January 1980"); | ||
await user.click(prevBtn); | ||
|
||
for (const month of newMonths) { | ||
expect(heading).toHaveTextContent(month + " 1979"); | ||
await user.click(prevBtn); | ||
} | ||
expect(heading).toHaveTextContent("January 1979"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<script lang="ts"> | ||
import { Calendar } from "$lib"; | ||
type $$Props = Calendar.Props; | ||
export let placeholder: $$Props["placeholder"] = undefined; | ||
export let value: $$Props["value"] = undefined; | ||
function changeValue(field: "day" | "month" | "year") { | ||
if (value) { | ||
value = value.cycle(field, 1); | ||
} | ||
} | ||
</script> | ||
|
||
<main> | ||
<div data-testid="value">{value}</div> | ||
<button on:click={() => changeValue("day")} data-testid="add-day"> | ||
Add Day | ||
</button> | ||
<button on:click={() => changeValue("month")} data-testid="add-month" | ||
>Add Month</button | ||
> | ||
<button on:click={() => changeValue("year")} data-testid="add-year" | ||
>Add Year</button | ||
> | ||
<Calendar.Root | ||
let:months | ||
let:weekdays | ||
bind:placeholder | ||
bind:value | ||
{...$$restProps} | ||
data-testid="calendar" | ||
> | ||
<Calendar.Header data-testid="header"> | ||
<Calendar.PrevButton data-testid="prev-button">Prev</Calendar.PrevButton> | ||
<Calendar.Heading data-testid="heading" /> | ||
<Calendar.NextButton data-testid="next-button">Next</Calendar.NextButton> | ||
</Calendar.Header> | ||
<div> | ||
{#each months as month} | ||
{@const m = month.value.month} | ||
<Calendar.Grid data-testid="grid-{m}"> | ||
<Calendar.GridHead data-testid="grid-head-{m}"> | ||
<Calendar.GridRow data-testid="grid-row-{m}"> | ||
{#each weekdays as day, i} | ||
<Calendar.HeadCell data-testid="head-cell-{i}"> | ||
{day} | ||
</Calendar.HeadCell> | ||
{/each} | ||
</Calendar.GridRow> | ||
</Calendar.GridHead> | ||
<Calendar.GridBody data-testid="grid-body-{m}"> | ||
{#each month.weeks as weekDates, i} | ||
<Calendar.GridRow data-testid="grid-row-{m}-{i}"> | ||
{#each weekDates as date, d} | ||
<Calendar.Cell {date} data-testid="cell-{date.month}-{d}"> | ||
<Calendar.Date | ||
{date} | ||
month={month.value} | ||
data-testid="date-{date.month}-{date.day}" | ||
> | ||
{date.day} | ||
</Calendar.Date> | ||
</Calendar.Cell> | ||
{/each} | ||
</Calendar.GridRow> | ||
{/each} | ||
</Calendar.GridBody> | ||
</Calendar.Grid> | ||
{/each} | ||
</div> | ||
</Calendar.Root> | ||
</main> |