git.iko.soy/rowtype-yoga/purescript-yoga-react-native
on feature/macos-ios-support help sign in
77 lines 2.5 kB history raw
1import { afterEach, describe, expect, it, vi } from "vitest";
2import { Appearance } from "react-native";
3import {
4 addChangeListenerImpl,
5 disposeAppearanceSubscriptionImpl,
6 getColorSchemeImpl,
7 setColorSchemeImpl,
8 useColorSchemeImpl,
9} from "../src/Yoga/React/Native/Appearance.js";
11const originalAddChangeListener = Appearance.addChangeListener;
13afterEach(() => {
14 vi.restoreAllMocks();
15 if (originalAddChangeListener === undefined) {
16 delete Appearance.addChangeListener;
17 } else {
18 Appearance.addChangeListener = originalAddChangeListener;
19 }
20});
22describe("Appearance FFI", () => {
23 it.each([
24 { nativeScheme: "light", expected: "light" },
25 { nativeScheme: "dark", expected: "dark" },
26 { nativeScheme: null, expected: null },
27 { nativeScheme: "sepia", expected: "sepia" },
28 { nativeScheme: { unexpected: true }, expected: null },
29 ])(
30 "normalizes native getter scheme $nativeScheme to $expected",
31 ({ nativeScheme, expected }) => {
32 vi.spyOn(Appearance, "getColorScheme").mockReturnValue(nativeScheme);
34 expect(getColorSchemeImpl()).toBe(expected);
35 },
36 );
38 it("passes primitive and null schemes through the uncurried setter bridge", () => {
39 const setColorScheme = vi.spyOn(Appearance, "setColorScheme");
41 setColorSchemeImpl("dark");
42 setColorSchemeImpl(null);
44 expect(setColorScheme.mock.calls).toEqual([["dark"], [null]]);
45 });
47 it("returns the hook's primitive scheme without an Effect thunk", () => {
48 expect(useColorSchemeImpl()).toBe("light");
49 });
51 it("delivers each native event once, preserves strings, and normalizes malformed values", () => {
52 let nativeListener;
53 Appearance.addChangeListener = vi.fn((listener) => {
54 nativeListener = listener;
55 return { remove: vi.fn() };
56 });
57 const callback = vi.fn();
59 addChangeListenerImpl(callback);
60 nativeListener({ colorScheme: "dark" });
61 nativeListener({ colorScheme: "sepia" });
62 nativeListener({ colorScheme: { unexpected: true } });
64 expect(callback.mock.calls).toEqual([["dark"], ["sepia"], [null]]);
65 });
67 it("removes the same native subscription only once when disposed twice", () => {
68 const remove = vi.fn();
69 Appearance.addChangeListener = vi.fn(() => ({ remove }));
70 const subscription = addChangeListenerImpl(vi.fn());
72 disposeAppearanceSubscriptionImpl(subscription);
73 disposeAppearanceSubscriptionImpl(subscription);
75 expect(remove).toHaveBeenCalledTimes(1);
76 });
77});