import React from 'react';
import { render, RenderResult } from '@testing-library/react';
import { processToken, LineTableRow, treeToLines } from './renderingPlugin';
describe('processToken()', () => {
test('when passed `null`, it returns `null`', () => {
expect(processToken(null)).toBeNull();
expect(processToken(null, 0)).toBeNull();
expect(processToken(null, 1)).toBeNull();
});
test('when passed undefined, it returns `null`', () => {
expect(processToken(undefined)).toBeNull();
expect(processToken(undefined, 0)).toBeNull();
expect(processToken(undefined, 1)).toBeNull();
});
test('when passed an Array, it returns an Array', () => {
expect(processToken([])).toBeInstanceOf(Array);
expect(
processToken(
[
{ kind: 'hello', children: [] },
{ kind: 'world', children: [] },
],
0,
),
).toBeInstanceOf(Array);
expect(processToken(['hello', 'hello', 'hello'], 1)).toBeInstanceOf(Array);
});
test('when passed an object, it returns a React element', () => {
expect(
React.isValidElement(processToken({ kind: 'hello', children: [] })),
).toBeTruthy();
expect(
React.isValidElement(processToken({ kind: 'hello', children: [] }, 0)),
).toBeTruthy();
expect(
React.isValidElement(processToken({ kind: 'hello', children: [] }, 1)),
).toBeTruthy();
});
test('when passed a string, it returns a string', () => {
expect(processToken('hello')).toBe('hello');
expect(processToken('hello', 0)).toBe('hello');
expect(processToken('hello', 1)).toBe('hello');
});
test("when processToken is passed an argument that's not explicitly supported, it returns that value", () => {
// @ts-expect-error
expect(processToken(false)).toBe(false);
// @ts-expect-error
expect(processToken(false, 0)).toBe(false);
// @ts-expect-error
expect(processToken(false, 1)).toBe(false);
});
});
describe('LineTableRow', () => {
const content = 'hello';
const lineNumber = 1;
function renderLineTableRow(): RenderResult {
return render(
,
);
}
test('renders a single table row as the root node', () => {
const { getByTestId } = renderLineTableRow();
// The component must return a single as the root node.
// We render a table and tbody tag as parents of the element to avoid a console error,
// then get the children of that tbody tag to test that the tr element is the only child.
const rows = getByTestId('tbody').children;
expect(rows.length).toBe(1);
expect(rows[0]).toBeInTheDocument();
expect(rows[0].tagName).toBe('TR');
});
test('renders two table cells', () => {
const { getAllByRole } = renderLineTableRow();
const cells = getAllByRole('cell');
expect(cells.length).toBe(2);
cells.forEach(cell => expect(cell).toBeInTheDocument());
});
test(`renders the line number (${lineNumber}) in the first cell`, () => {
const { getAllByRole } = renderLineTableRow();
const cells = getAllByRole('cell');
expect(cells[0]).toHaveTextContent(lineNumber.toString());
});
test(`renders '${content}' in the second cell`, () => {
const { getAllByRole } = renderLineTableRow();
const cells = getAllByRole('cell');
expect(cells[1]).toHaveTextContent(content);
});
});
interface TokenObject {
kind: string;
children: Array;
}
const sampleChildren: Array = [
// Line break at the beginning should be stripped.
'\n',
{
kind: 'function',
children: [
{ kind: 'keyword', children: ['function'] },
' ',
{ kind: 'title', children: ['greeting'] },
'(',
{ kind: 'params', children: ['entity'] },
') ',
],
},
'{',
'\n ',
{ kind: 'keyword', children: ['return'] },
' ',
{
kind: 'string',
children: ['`Hello, ', { kind: 'subst', children: ['${entity}'] }, '!`'],
},
';\n',
'}',
'\n\n',
{ kind: 'built_in', children: ['console'] },
'.log',
'(',
'greeting',
'(',
{ kind: 'string', children: ["'World'"] },
'))',
// Line break at the end should be stripped.
';\n',
];
describe('treeToLines()', () => {
function validateLine(line: any) {
function isNonArrayObject(obj: any) {
if (obj instanceof Array) {
return false;
}
return typeof obj === 'object';
}
expect(line).toBeInstanceOf(Array);
line.forEach((el: any) => {
if (typeof el === 'string') {
expect(typeof el).toBe('string');
} else if (isNonArrayObject(el)) {
expect(el).toHaveProperty('kind');
expect(el).toHaveProperty('children');
el.children.forEach((child: any) => {
expect(
typeof child === 'string' || isNonArrayObject(child),
).toBeTruthy();
});
} else {
throw new TypeError(
"element in array was not of types: 'object' | 'string'",
);
}
});
}
// eslint-disable-next-line jest/expect-expect
test('when passed a valid set of children, returns a valid Array', () => {
treeToLines(sampleChildren).forEach(validateLine);
});
// eslint-disable-next-line jest/expect-expect
test('when passed an invalid set of children, returns a valid Array', () => {
// @ts-expect-error
treeToLines([...sampleChildren, null, 0]).forEach(validateLine);
});
});