import React from 'react';
import { render } from '@testing-library/react';
import { renderMessage } from '../render';
import { transformMessage } from '../transform';

describe('transformMessage', () => {
    test('replaces {arg}...{/arg} in message with a new argument', () => {
        const message = 'This {arg}is to{/arg} be translated';
        const transformed = transformMessage(message, {
            arg: ({ children }: { children?: React.ReactNode }) => <i>{children}</i>,
        });

        expect(transformed.message).toEqual('This {arg:5} be translated');
    });

    test('start/stop arguments are stored back as a normal JSX argument', () => {
        const message = 'This is{wrapper}to be translated{/wrapper}';
        const { args } = transformMessage(message, {
            wrapper: ({ children }: { children?: React.ReactNode }) => <i>{children}</i>,
        });

        const element = args['wrapper:7'] as JSX.Element;
        const { container } = render(element);
        expect(container.innerHTML).toEqual('<i>to be translated</i>');
    });

    test('nested arguments are supported', () => {
        const message = 'This {outer}is {inner}cool{/inner}{/outer}';
        const transformed = transformMessage(message, {
            outer: ({ children }: { children?: React.ReactNode }) => <i>{children}</i>,
            inner: ({ children }: { children?: React.ReactNode }) => <b>{children}</b>,
        });

        expect(transformed.message).toEqual('This {outer:5}');

        const { container } = render(renderMessage(transformed));
        expect(container.innerHTML).toEqual('This <i>is <b>cool</b></i>');
    });

    test('built-in support for <b> and <i>', () => {
        const message = 'This <b>is <i>cool</i></b>';
        const transformed = transformMessage(message);

        const { container } = render(renderMessage(transformed));
        expect(container.innerHTML).toEqual('This <b>is <i>cool</i></b>');
    });

    test('JSX and string arguments are passed through', () => {
        const message = 'This {is} super {cool}';
        const transformed = transformMessage(message, {
            is: <i>is</i>,
            cool: 'COOL',
        });

        const { container } = render(renderMessage(transformed));
        expect(container.innerHTML).toEqual('This <i>is</i> super COOL');
    });

    test('empty strings are passed through', () => {
        const message = '';
        const transformed = transformMessage(message);

        expect(transformed.message).toEqual('');
    });
});
