import '@testing-library/jest-dom';
import renderer from 'react-test-renderer';
import {render, screen} from '@testing-library/react';
import {TypographyComponent as Typography} from './typography.component';
import {AppProviderComponent} from '../../../providers';
import {THEME_LIGHT} from '../../../../themes';
import React from 'react';

describe('Typography Component', () => {
    describe('Render without crash and correctly', () => {
        it('Check', () => {
            const role = 'typography';
            const theme = THEME_LIGHT;

            render(
                <AppProviderComponent>
                    <Typography role={role} />
                </AppProviderComponent>,
            );

            const typography = screen.getByRole(role);

            expect(typography).toHaveStyle(`padding: 0`);
            expect(typography).toHaveStyle(`margin: 0`);
            expect(typography).toHaveStyle(`font-size: 1rem`);
            expect(typography).toHaveStyle(`font-weight: 400`);
            expect(typography).toHaveStyle(`letter-spacing: normal`);
            expect(typography).toHaveStyle(`line-height: 1.5rem`);
            expect(typography).toHaveStyle(`color: ${theme.palette.gray[900]}`);
        });

        it('Snapshot', () => {
            const tree = renderer.create(
                <AppProviderComponent>
                    <Typography />
                </AppProviderComponent>,
            );

            expect(tree).toMatchSnapshot();
        });
    });

    describe('Prop `children` works correctly', () => {
        it('Check', () => {
            const children = 'Typography';
            const role = 'typography';
            const theme = THEME_LIGHT;

            render(
                <AppProviderComponent>
                    <Typography role={role}>{children}</Typography>
                </AppProviderComponent>,
            );

            const typography = screen.getByRole(role);

            expect(typography).toHaveTextContent(children);

            expect(typography).toHaveStyle(`padding: 0`);
            expect(typography).toHaveStyle(`margin: 0`);
            expect(typography).toHaveStyle(`font-size: 1rem`);
            expect(typography).toHaveStyle(`font-weight: 400`);
            expect(typography).toHaveStyle(`letter-spacing: normal`);
            expect(typography).toHaveStyle(`line-height: 1.5rem`);
            expect(typography).toHaveStyle(`color: ${theme.palette.gray[900]}`);
        });

        it('Snapshot', () => {
            const children = 'Typography';

            const tree = renderer.create(
                <AppProviderComponent>
                    <Typography>{children}</Typography>
                </AppProviderComponent>,
            );

            expect(tree).toMatchSnapshot();
        });
    });

    describe('Prop `size` works correctly', () => {
        describe('textXS', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'textXS';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 0.75rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'textXS';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('textSM', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'textSM';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 0.875rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'textSM';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('textMD', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'textMD';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 1rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'textMD';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('textLG', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'textLG';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 1.125rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'textLG';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('textXL', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'textXL';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 1.25rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'textXL';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('displayXS', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'displayXS';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 1.5rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'displayXS';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('displaySM', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'displaySM';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 1.875rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'displaySM';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('displayMD', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'displayMD';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 2.25rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'displayMD';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('displayLG', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'displayLG';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 3rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'displayLG';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('displayXL', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'displayXL';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 3.75rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'displayXL';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('display2XL', () => {
            it('Check', () => {
                const children = 'Typography';
                const size = 'display2XL';
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} size={size}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-size: 4.5rem`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const size = 'display2XL';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography size={size}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });
    });

    describe('Prop `weight` works correctly', () => {
        describe('100', () => {
            it('Check', () => {
                const children = 'Typography';
                const weight = 100;
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} weight={weight}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-weight: 100`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const weight = 100;

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography weight={weight}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('200', () => {
            it('Check', () => {
                const children = 'Typography';
                const weight = 200;
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} weight={weight}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-weight: 200`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const weight = 200;

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography weight={weight}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('300', () => {
            it('Check', () => {
                const children = 'Typography';
                const weight = 300;
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} weight={weight}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-weight: 300`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const weight = 300;

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography weight={weight}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('400', () => {
            it('Check', () => {
                const children = 'Typography';
                const weight = 400;
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} weight={weight}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-weight: 400`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const weight = 400;

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography weight={weight}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('500', () => {
            it('Check', () => {
                const children = 'Typography';
                const weight = 500;
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} weight={weight}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-weight: 500`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const weight = 500;

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography weight={weight}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('600', () => {
            it('Check', () => {
                const children = 'Typography';
                const weight = 600;
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} weight={weight}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-weight: 600`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const weight = 600;

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography weight={weight}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('700', () => {
            it('Check', () => {
                const children = 'Typography';
                const weight = 700;
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} weight={weight}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-weight: 700`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const weight = 700;

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography weight={weight}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('800', () => {
            it('Check', () => {
                const children = 'Typography';
                const weight = 800;
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} weight={weight}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-weight: 800`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const weight = 800;

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography weight={weight}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('900', () => {
            it('Check', () => {
                const children = 'Typography';
                const weight = 900;
                const role = 'typography';

                render(
                    <AppProviderComponent>
                        <Typography role={role} weight={weight}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(`font-weight: 900`);
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const weight = 900;

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography weight={weight}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });
    });

    describe('Prop `tag` works correctly', () => {
        describe('h1', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'h1';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'h1';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('h2', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'h2';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'h2';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('h3', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'h3';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'h3';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('h4', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'h4';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'h4';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('h5', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'h5';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'h5';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('h6', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'h6';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'h6';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('p', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'p';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'p';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('small', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'small';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'small';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('span', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'span';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'span';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('strong', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'strong';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'strong';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });

        describe('b', () => {
            it('Check', () => {
                const children = 'Typography';
                const tag = 'b';
                const role = 'typography';

                const {container} = render(
                    <AppProviderComponent>
                        <Typography role={role} tag={tag}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = container.querySelector(tag);
                expect(typography).toBeInTheDocument();
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const tag = 'b';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography tag={tag}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });
    });

    describe('Prop `color` works correctly', () => {
        describe('primary', () => {
            it('Check', () => {
                const children = 'Typography';
                const color = 'primary';
                const role = 'typography';
                const theme = THEME_LIGHT;

                render(
                    <AppProviderComponent>
                        <Typography role={role} color={color}>
                            {children}
                        </Typography>
                    </AppProviderComponent>,
                );

                const typography = screen.getByRole(role);
                expect(typography).toHaveStyle(
                    `color: ${theme.palette[color][900]}`,
                );
            });

            it('Snapshot', () => {
                const children = 'Typography';
                const color = 'primary';

                const tree = renderer.create(
                    <AppProviderComponent>
                        <Typography color={color}>{children}</Typography>
                    </AppProviderComponent>,
                );

                expect(tree).toMatchSnapshot();
            });
        });
    });
});
