import { errorToString } from 'assertion-error-diff';
import { strip } from 'typed-colors';
import { cross, tick } from 'typed-figures';
export function resultsToDom(results) {
    return withChildren(flexColumn(), results.map(x => resultToDom(x)));
}
export function resultToDom(result, nested = false) {
    if (result.type === 'pass') {
        return formatPassingResult(result, nested);
    }
    if (result.type === 'fail') {
        return formatFailingResult(result, nested);
    }
    if (result.type === 'skip') {
        return formatSkippedResult(result, nested);
    }
    return formatGroupResult(result);
}
function formatPassingResult({ name }, nested) {
    const element = withChildren(flexContainer(), [greenTick(), testName(name)]);
    return marginTopIfNotNested(element, nested);
}
function formatFailingResult({ name, error }, nested) {
    const testNameElement = withChildren(flexContainer(), [redCross(), testName(name)]);
    const errorElement = errorToDom(error);
    const element = marginTopIfNotNested(withChildren(flexColumn(), [testNameElement, errorElement]), nested);
    return nested ? withStyle(element, { marginBottom: '0.5rem' }) : element;
}
function errorToDom(error) {
    const message = errorMessage(error);
    return withStyle(message, { marginLeft: '1.25rem' });
}
function errorMessage(error) {
    const message = strip(errorToString(error)).replace('- expected + actual\n', '');
    const parts = message.split(/\n/g);
    return withChildren(flexColumn(), parts.map((x, i) => (i > 0 ? withStyle(text(x), { marginLeft: '1rem' }) : text(x))));
}
function formatSkippedResult({ name }, nested) {
    const element = withChildren(flexContainer(), [blueText('(Skipped) '), testName(name)]);
    return marginTopIfNotNested(element, nested);
}
function formatGroupResult(result) {
    const { results, name } = result;
    const container = flexColumn();
    return withChildren(withStyle(container, { marginTop: '1rem' }), [
        testName(name, true),
        withChildren(withStyle(flexColumn(), { paddingLeft: '1rem' }), results.map((x, i) => {
            const r = resultToDom(x, true);
            if (i > 0 && x.type !== 'group' && results[i - 1].type === 'group') {
                return withStyle(r, { marginTop: '1rem' });
            }
            return r;
        })),
    ]);
}
function testName(name, bold = false) {
    const itRegex = /^it\s/;
    const givenRegex = /^given\s/;
    if (itRegex.test(name)) {
        return withChildren(flexContainer(), [blueText('it '), text(name.replace(itRegex, '').trim())]);
    }
    if (givenRegex.test(name)) {
        const testNameParsed = name.replace(givenRegex, '').trim();
        return withChildren(flexContainer(), [
            blueText('given ', bold),
            bold ? boldText(testNameParsed) : text(testNameParsed),
        ]);
    }
    return text(name);
}
function withChildren(element, children) {
    children.forEach(child => element.appendChild(child));
    return element;
}
function boldText(txt) {
    return withStyle(text(txt), { fontWeight: '700' });
}
function blueText(txt, bold = false) {
    return withStyle(bold ? boldText(txt) : text(txt), { color: 'blue' });
}
function text(s) {
    const element = document.createElement('p');
    element.textContent = s;
    return withStyle(element, { margin: '0 0.25rem' });
}
function redCross() {
    return withStyle(text(cross), { color: 'red' });
}
function greenTick() {
    return withStyle(text(tick), { color: 'green' });
}
function flexColumn() {
    return withStyle(document.createElement('div'), {
        display: 'inline-flex',
        flexDirection: 'column',
    });
}
function flexContainer() {
    return withStyle(document.createElement('div'), {
        display: 'inline-flex',
        flexDirection: 'row',
    });
}
function marginTopIfNotNested(el, nested) {
    return nested ? el : withStyle(el, { marginTop: '1rem' });
}
function withStyle(el, styles) {
    const keys = Object.keys(styles);
    keys.forEach(key => (el.style[key] = styles[key]));
    return el;
}
//# sourceMappingURL=resultToDom.js.map