import React, { ComponentType, ReactNode, Ref, AnchorHTMLAttributes } from "react"; import R from "react-test-renderer"; import { Translate, T, tBind, As, TText } from "./components"; import { TDictionaryRoot } from "./dictionary"; const dictionary: TDictionaryRoot = { $$dict: { site: { en: "Interminimal" }, heading: { en: "Let's Translate!", fr: "Traduisons!", de: "Lassen Sie uns übersetzen!" }, maybe: { $$dict: { site: { en: "Something else" } } } } }; type MyLinkProps = { ref?: Ref; children: ReactNode; } & AnchorHTMLAttributes; const MyLink: ComponentType = React.forwardRef< HTMLAnchorElement, MyLinkProps >(({ children, href }, ref) => { // @ts-ignore return ( {children} ); }); beforeEach(() => { jest.spyOn(console, "error"); // @ts-ignore jest.spyOn adds this functionallity console.error.mockImplementation(() => null); }); afterEach(() => { // @ts-ignore jest.spyOn adds this functionallity console.error.mockRestore(); }); describe("Interminimal Components", () => { it("should render As as a span by default", () => { expect(R.create(Hello).toJSON()).toMatchSnapshot(); }); it("should render ", () => { expect( R.create( ).toJSON() ).toMatchSnapshot(); expect( R.create( ).toJSON() ).toMatchSnapshot(); }); it("should render templates", () => { expect( R.create( ).toJSON() ).toMatchSnapshot(); }); it("should render content", () => { expect( R.create( ).toJSON() ).toMatchSnapshot(); }); it("should allow element of Translate to be overridden", () => { expect( R.create( ).toJSON() ).toMatchSnapshot(); }); it("should bind T as a component", () => { const TMyLink = tBind(MyLink); expect( R.create( ).toJSON() ).toMatchSnapshot(); }); it("should cache bound components", () => { const Tp1 = tBind("p"); const Tp2 = tBind("p"); expect(Tp2).toBe(Tp1); }); it("should resolve tags", () => { expect( R.create( ).toJSON() ).toMatchSnapshot(); }); it("should translate properties", () => { expect( R.create( Some text ).toJSON() ).toMatchSnapshot(); }); it("should pass template fragments down", () => { const ts = { en: "Here is a %1[link] and this %2[is italic]" }; expect( R.create( ).toJSON() ).toMatchSnapshot(); }); it("should pass refs via Format", () => { const ref = React.createRef(); // Test that MyLink gets a ref even though there's no explicit // ref in its properties. expect( R.create( Link ).toJSON() ).toMatchSnapshot(); // expect(ref.current?.href).toBe("/"); }); it("should handle ambience", () => { const dict = { $$dict: { info: { "en-GB": "Spiffing! %1", "en": "Good %1" }, switch: { en: "switch %1" }, caption: { "en-GB": "Tally Ho!", "en": "Let's go" } } }; expect( R.create( ) ).toMatchSnapshot(); }); it("should retain ambience", () => { const dict = { $$dict: { info: { "en-GB": "Spiffing! %1", "en": "Good %1" }, switch: { en: "switch %1" }, caption: { "en-GB": "Tally Ho!", "en": "Let's go" } } }; expect( R.create( ) ).toMatchSnapshot(); }); it("should render TText as span by default", () => { expect(R.create(Hello).toJSON()).toMatchSnapshot(); const dict = { $$dict: { info: { "en-GB": "Spiffing! %1", "en": "Good %1" }, switch: { en: "switch %1" }, caption: { "en-GB": "Tally Ho!", "en": "Let's go" } } }; expect( R.create( Hello ) ).toMatchSnapshot(); }); //////////////////// // Negative cases // //////////////////// it("should fail for indexes out of range", () => { expect(() => R.create( ) ).toThrow(/out of range/); }); it("should fail for unused children", () => { expect(() => R.create( ) ).toThrow(/unused args/i); }); it("should fail for reused children", () => { expect(() => R.create( ) ).toThrow(/already/i); }); it("should fail if tag + text provided", () => { expect(() => R.create( ) ).toThrow(/both/); }); it("should fail if tag + content provided", () => { expect(() => R.create( ) ).toThrow(/don't mix/); }); it("should fail to pass refs to multiple children", () => { const ref = React.createRef(); expect(() => R.create( ) ).toThrow(/only forward/); }); it("should fail to pass refs to non-elements", () => { const ref = React.createRef(); expect(() => R.create( Hello! ) ).toThrow(/non-element/i); }); it("should fail to pass refs to content", () => { const ref = React.createRef(); expect(() => R.create( ) ).toThrow(/pass ref/i); }); it("should fail to pass refs to regular children", () => { const ref = React.createRef(); expect(() => R.create( Hello ) ).toThrow(/pass ref/i); }); });