// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
// Test cases for MessageList markup parsing
const JsUnit = imports.jsUnit;
import Pango from 'gi://Pango';
import '../../js/ui/environment.js';
imports.ui.main; // eslint-disable-line no-unused-expressions
const MessageList = imports.ui.messageList;
/**
* Assert that `input`, assumed to be markup, gets "fixed" to `output`,
* which is valid markup. If `output` is null, `input` is expected to
* convert to itself
*
* @param {string} input the input
* @param {string} output the output
*/
function assertConverts(input, output) {
if (!output)
output = input;
let fixed = MessageList._fixMarkup(input, true);
JsUnit.assertEquals(output, fixed);
let parsed = false;
try {
Pango.parse_markup(fixed, -1, '');
parsed = true;
} catch (e) {}
JsUnit.assertEquals(true, parsed);
}
/**
* Assert that `input`, assumed to be plain text, gets escaped to `output`,
* which is valid markup.
*
* @param {string} input the input
* @param {string} output the output
*/
function assertEscapes(input, output) {
let fixed = MessageList._fixMarkup(input, false);
JsUnit.assertEquals(output, fixed);
let parsed = false;
try {
Pango.parse_markup(fixed, -1, '');
parsed = true;
} catch (e) {}
JsUnit.assertEquals(true, parsed);
}
// CORRECT MARKUP
assertConverts('foo');
assertEscapes('foo', 'foo');
assertConverts('foo');
assertEscapes('foo', '<b>foo</b>');
assertConverts('something foo');
assertEscapes('something foo', 'something <i>foo</i>');
assertConverts('foo something');
assertEscapes('foo something', '<u>foo</u> something');
assertConverts('bold italic and underlined');
assertEscapes('bold italic and underlined', '<b>bold</b> <i>italic <u>and underlined</u></i>');
assertConverts('this & that');
assertEscapes('this & that', 'this & that');
assertConverts('this < that');
assertEscapes('this < that', 'this < that');
assertConverts('this < that > the other');
assertEscapes('this < that > the other', 'this < that > the other');
assertConverts('this <that>');
assertEscapes('this <that>', 'this <<i>that</i>>');
assertConverts('this > that');
assertEscapes('this > that', '<b>this</b> > <i>that</i>');
// PARTIALLY CORRECT MARKUP
// correct bits are kept, incorrect bits are escaped
// unrecognized entity
assertConverts('smile ☺!', 'smile ☺!');
assertEscapes('smile ☺!', '<b>smile</b> ☺!');
// stray '&'; this is really a bug, but it's easier to do it this way
assertConverts('this & that', 'this & that');
assertEscapes('this & that', '<b>this</b> & <i>that</i>');
// likewise with stray '<'
assertConverts('this < that', 'this < that');
assertEscapes('this < that', 'this < that');
assertConverts('this < that', 'this < that');
assertEscapes('this < that', '<b>this</b> < <i>that</i>');
assertConverts('this < that > the other', 'this < that > the other');
assertEscapes('this < that > the other', 'this < that > the other');
assertConverts('this <that>', 'this <that>');
assertEscapes('this <that>', 'this <<i>that</i>>');
// unknown tags
assertConverts('tag', '<unknown>tag</unknown>');
assertEscapes('tag', '<unknown>tag</unknown>');
// make sure we check beyond the first letter
assertConverts('tag', '<bunknown>tag</bunknown>');
assertEscapes('tag', '<bunknown>tag</bunknown>');
// with mix of good and bad, we keep the good and escape the bad
assertConverts('known and tag', 'known and <unknown>tag</unknown>');
assertEscapes('known and tag', '<i>known</i> and <unknown>tag</unknown>');
// FULLY INCORRECT MARKUP
// (fall back to escaping the whole thing)
// tags not matched up
assertConverts('incomplete', '<b>in<i>com</i>plete');
assertEscapes('incomplete', '<b>in<i>com</i>plete');
assertConverts('incomplete', 'in<i>com</i>plete</b>');
assertEscapes('incomplete', 'in<i>com</i>plete</b>');
// we don't support attributes, and it's too complicated to try
// to escape both start and end tags, so we just treat it as bad
assertConverts('good and bad', '<b>good</b> and <b style='bad'>bad</b>');
assertEscapes('good and bad', '<b>good</b> and <b style='bad'>bad</b>');
// this is just syntactically invalid
assertConverts('unrecognized', '<b>unrecognized</b stuff>');
assertEscapes('unrecognized', '<b>unrecognized</b stuff>');
// mismatched tags
assertConverts('mismatched', '<b>mismatched</i>');
assertEscapes('mismatched', '<b>mismatched</i>');
assertConverts('mismatched/unknown', '<b>mismatched/unknown</bunknown>');
assertEscapes('mismatched/unknown', '<b>mismatched/unknown</bunknown>');