blob: a458a61ef75c52dc3c4ecf7d3935f52fd44be8b0 [file] [log] [blame]
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import '../../../test/common-test-setup';
import './gr-diff-text';
import {GrDiffText} from './gr-diff-text';
import {fixture, html, assert} from '@open-wc/testing';
const LINE_BREAK = '<span class="br"></span>';
const LINE_BREAK_WBR = '<wbr></wbr>';
const TAB = '<span class="" style=""></span>';
const TAB_IGNORE = ['class', 'style'];
suite('gr-diff-text test', () => {
let element: GrDiffText;
setup(async () => {
element = await fixture<GrDiffText>(
html`<gr-diff-text tabsize="4" linelimit="10"></gr-diff-text>`
);
});
const check = async (
text: string,
html: string,
ignoreAttributes: string[] = []
) => {
element.text = text;
await element.updateComplete;
assert.lightDom.equal(element, html, {ignoreAttributes});
};
suite('lit rendering', () => {
test('renderText newlines 1', async () => {
await check('abcdef', 'abcdef');
await check('a'.repeat(20), `aaaaaaaaaa${LINE_BREAK}aaaaaaaaaa`);
});
test('renderText newlines 1 responsive', async () => {
element.isResponsive = true;
await check('abcdef', 'abcdef');
await check('a'.repeat(20), `aaaaaaaaaa${LINE_BREAK_WBR}aaaaaaaaaa`);
});
test('renderText newlines 2', async () => {
await check(
'<span class="thumbsup">👍</span>',
'&lt;span clas' +
LINE_BREAK +
's="thumbsu' +
LINE_BREAK +
'p"&gt;👍&lt;/span' +
LINE_BREAK +
'&gt;'
);
});
test('renderText newlines 3', async () => {
await check(
'01234\t56789',
'01234' + TAB + '56' + LINE_BREAK + '789',
TAB_IGNORE
);
});
test('renderText newlines 4', async () => {
element.lineLimit = 20;
await element.updateComplete;
await check(
'👍'.repeat(58),
'👍'.repeat(20) +
LINE_BREAK +
'👍'.repeat(20) +
LINE_BREAK +
'👍'.repeat(18)
);
});
test('tab wrapper style', async () => {
element.lineLimit = 100;
element.tabSize = 4;
await check(
'\t',
/* HTML */ '<span class="tab" style="tab-size:4;"></span>'
);
await check(
'abc\t',
/* HTML */ 'abc<span class="tab" style="tab-size:1;"></span>'
);
element.tabSize = 8;
await check(
'\t',
/* HTML */ '<span class="tab" style="tab-size:8;"></span>'
);
await check(
'abc\t',
/* HTML */ 'abc<span class="tab" style="tab-size:5;"></span>'
);
});
test('tab wrapper insertion', async () => {
await check('abc\tdef', 'abc' + TAB + 'def', TAB_IGNORE);
});
test('escaping HTML', async () => {
element.lineLimit = 100;
await element.updateComplete;
await check(
'<script>alert("XSS");<' + '/script>',
'&lt;script&gt;alert("XSS");&lt;/script&gt;'
);
await check('& < > " \' / `', '&amp; &lt; &gt; " \' / `');
});
test('text length with tabs and unicode', async () => {
async function expectTextLength(
text: string,
tabSize: number,
expected: number
) {
element.text = text;
element.tabSize = tabSize;
element.lineLimit = expected;
await element.updateComplete;
const result = element.innerHTML;
// Must not contain a line break.
assert.isNotOk(element.querySelector('span.br'));
// Increasing the line limit by 1 should not change anything.
element.lineLimit = expected + 1;
await element.updateComplete;
const resultPlusOne = element.innerHTML;
assert.equal(resultPlusOne, result);
// Increasing the line limit to infinity should not change anything.
element.lineLimit = Infinity;
await element.updateComplete;
const resultInf = element.innerHTML;
assert.equal(resultInf, result);
// Decreasing the line limit by 1 should introduce a line break.
element.lineLimit = expected + 1;
await element.updateComplete;
assert.isNotOk(element.querySelector('span.br'));
}
expectTextLength('12345', 4, 5);
expectTextLength('\t\t12', 4, 10);
expectTextLength('abc💢123', 4, 7);
expectTextLength('abc\t', 8, 8);
expectTextLength('abc\t\t', 10, 20);
expectTextLength('', 10, 0);
// 17 Thai combining chars.
expectTextLength('ก้้้้้้้้้้้้้้้้', 4, 17);
expectTextLength('abc\tde', 10, 12);
expectTextLength('abc\tde\t', 10, 20);
expectTextLength('\t\t\t\t\t', 20, 100);
});
});
});