import { renderHook, screen } from "@testing-library/react"
import React, { useEffect } from "react"
import { describe, expect, test, vi } from "vitest"
import { render as BaseRender, RenderOptions } from "../../../tests/render"
import { createMedia } from "./createMedia"
const BREAKPOINTS = {
xs: 0,
sm: 640,
md: 768,
lg: 1025,
xl: 1280,
"2xl": 1440,
container: 1600,
"3xl": 1910,
}
const {
createMediaStyle,
breakpoints,
Media,
useSizeContextSelector,
SizeProvider,
MediaContextProvider,
} = createMedia(BREAKPOINTS, {
initialWindowSize: { width: window.innerWidth, height: window.innerHeight },
})
const render = (ui: React.ReactElement, options?: RenderOptions) => {
return BaseRender(
{ui}
,
options,
)
}
describe("Media", () => {
test("does not fire effects when not matched", () => {
const callback = vi.fn()
const Component = () => {
useEffect(() => {
callback()
}, [])
return
Hello world
}
render(
,
{ viewport: { width: breakpoints.sm } },
)
expect(callback).not.toHaveBeenCalled()
})
describe("at", () => {
const AtSm = () => (
)
test('does not match "sm"', () => {
render(, { viewport: { width: breakpoints.md } })
expect(
screen.queryByRole("button", { name: "Click me" }),
).not.toBeInTheDocument()
})
test('matches "sm"', () => {
render(, { viewport: { width: breakpoints.sm } })
const button = screen.getByRole("button", { name: "Click me" })
expect(button).toBeInTheDocument()
expect(button.parentElement).toHaveClass("fresnel-at-sm")
})
test('matches "sm" with render props', () => {
render(
{(mediaClassName: string) => (
)}
,
{ viewport: { width: breakpoints.sm } },
)
const button = screen.getByRole("button", { name: "Click me" })
expect(button).toBeInTheDocument()
expect(button).toHaveClass("fresnel-at-sm")
})
})
describe("lessThan", () => {
const LessThan = () => (
)
test('does not match "md"', () => {
render(, { viewport: { width: breakpoints.md } })
expect(
screen.queryByRole("button", { name: "Click me" }),
).not.toBeInTheDocument()
})
test('does not match "sm"', () => {
render(, { viewport: { width: breakpoints.sm } })
expect(
screen.queryByRole("button", { name: "Click me" }),
).not.toBeInTheDocument()
})
test('matches less than "sm"', () => {
render(, { viewport: { width: breakpoints.sm - 1 } })
const button = screen.getByRole("button", { name: "Click me" })
expect(button).toBeInTheDocument()
expect(button.parentElement).toHaveClass("fresnel-lessThan-sm")
})
})
describe("greterThan", () => {
const GreaterThanLg = () => (
)
test('does not match "lg"', () => {
render(, { viewport: { width: breakpoints.lg } })
expect(
screen.queryByRole("button", { name: "Click me" }),
).not.toBeInTheDocument()
})
test('matches "xl"', () => {
render(, { viewport: { width: breakpoints.xl } })
const button = screen.getByRole("button", { name: "Click me" })
expect(button).toBeInTheDocument()
expect(button.parentElement).toHaveClass("fresnel-greaterThan-lg")
})
})
describe("greaterThanOrEqual", () => {
const GreaterThanOrEqualLg = () => (
)
test('does not match "md"', () => {
render(, { viewport: { width: breakpoints.md } })
expect(
screen.queryByRole("button", { name: "Click me" }),
).not.toBeInTheDocument()
})
test('matches "lg"', () => {
render(, { viewport: { width: breakpoints.lg } })
const button = screen.getByRole("button", { name: "Click me" })
expect(button).toBeInTheDocument()
expect(button.parentElement).toHaveClass("fresnel-greaterThanOrEqual-lg")
})
test('matches "xl"', () => {
render(, { viewport: { width: breakpoints.xl } })
const button = screen.getByRole("button", { name: "Click me" })
expect(button).toBeInTheDocument()
expect(button.parentElement).toHaveClass("fresnel-greaterThanOrEqual-lg")
})
})
describe("between", () => {
describe("start-inclusive", () => {
const BetweenMdAndLg = () => (
)
test('does not match "sm"', () => {
render(, { viewport: { width: breakpoints.sm } })
expect(
screen.queryByRole("button", { name: "Click me" }),
).not.toBeInTheDocument()
})
test('matches "md"', () => {
render(, { viewport: { width: breakpoints.md } })
const button = screen.getByRole("button", { name: "Click me" })
expect(button).toBeInTheDocument()
expect(button.parentElement).toHaveClass("fresnel-between-md-lg")
})
test('does not match "lg"', () => {
render(, { viewport: { width: breakpoints.lg } })
expect(
screen.queryByRole("button", { name: "Click me" }),
).not.toBeInTheDocument()
})
test('does not match "xl"', () => {
render(, { viewport: { width: breakpoints.xl } })
expect(
screen.queryByRole("button", { name: "Click me" }),
).not.toBeInTheDocument()
})
})
})
describe("multiple medias", () => {
test("not matching", () => {
render(
<>
Media - 1
Media - 2
Media - 3
>,
)
expect(screen.queryByText(/Media/)).not.toBeInTheDocument()
})
})
})
describe("createMediaStyle", () => {
test("generates media styles", () => {
expect(createMediaStyle()).toMatchSnapshot()
})
})
describe("useSizeContextSelector", () => {
test("more than lg", () => {
const { result } = renderHook(
() => useSizeContextSelector(state => state.width < breakpoints.lg),
{ wrapper: ({ children }) => {children} },
)
expect(result.current).toBe(false)
})
})