c6d57059ff
The markup unit test currently fails with the following message: TypeError: class heritage MessageList.Message is not an object or null This is because MessageList imports other modules that end up importing MessageList themselves in order to inherit from one of its classes. But as the MessageList imports hasn't finished yet (it's still processing its own imports), that class hasn't been defined yet. Work around that by importing Main first, so that the importer can process imports in a proper order.
144 lines
5.5 KiB
JavaScript
144 lines
5.5 KiB
JavaScript
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
// Test cases for MessageList markup parsing
|
|
|
|
const JsUnit = imports.jsUnit;
|
|
const Pango = imports.gi.Pango;
|
|
|
|
const Environment = imports.ui.environment;
|
|
Environment.init();
|
|
|
|
const Main = imports.ui.main; // unused, but needed to break dependency loop
|
|
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
|
|
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.
|
|
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('<b>foo</b>');
|
|
assertEscapes('<b>foo</b>', '<b>foo</b>');
|
|
|
|
assertConverts('something <i>foo</i>');
|
|
assertEscapes('something <i>foo</i>', 'something <i>foo</i>');
|
|
|
|
assertConverts('<u>foo</u> something');
|
|
assertEscapes('<u>foo</u> something', '<u>foo</u> something');
|
|
|
|
assertConverts('<b>bold</b> <i>italic <u>and underlined</u></i>');
|
|
assertEscapes('<b>bold</b> <i>italic <u>and underlined</u></i>', '<b>bold</b> <i>italic <u>and underlined</u></i>');
|
|
|
|
assertConverts('this & that');
|
|
assertEscapes('this & that', 'this &amp; that');
|
|
|
|
assertConverts('this < that');
|
|
assertEscapes('this < that', 'this &lt; that');
|
|
|
|
assertConverts('this < that > the other');
|
|
assertEscapes('this < that > the other', 'this &lt; that &gt; the other');
|
|
|
|
assertConverts('this <<i>that</i>>');
|
|
assertEscapes('this <<i>that</i>>', 'this &lt;<i>that</i>&gt;');
|
|
|
|
assertConverts('<b>this</b> > <i>that</i>');
|
|
assertEscapes('<b>this</b> > <i>that</i>', '<b>this</b> > <i>that</i>');
|
|
|
|
|
|
|
|
// PARTIALLY CORRECT MARKUP
|
|
// correct bits are kept, incorrect bits are escaped
|
|
|
|
// unrecognized entity
|
|
assertConverts('<b>smile</b> ☺!', '<b>smile</b> &#9786;!');
|
|
assertEscapes('<b>smile</b> ☺!', '<b>smile</b> &#9786;!');
|
|
|
|
// stray '&'; this is really a bug, but it's easier to do it this way
|
|
assertConverts('<b>this</b> & <i>that</i>', '<b>this</b> & <i>that</i>');
|
|
assertEscapes('<b>this</b> & <i>that</i>', '<b>this</b> & <i>that</i>');
|
|
|
|
// likewise with stray '<'
|
|
assertConverts('this < that', 'this < that');
|
|
assertEscapes('this < that', 'this < that');
|
|
|
|
assertConverts('<b>this</b> < <i>that</i>', '<b>this</b> < <i>that</i>');
|
|
assertEscapes('<b>this</b> < <i>that</i>', '<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 <<i>that</i>>', 'this <<i>that</i>>');
|
|
assertEscapes('this <<i>that</i>>', 'this <<i>that</i>>');
|
|
|
|
// unknown tags
|
|
assertConverts('<unknown>tag</unknown>', '<unknown>tag</unknown>');
|
|
assertEscapes('<unknown>tag</unknown>', '<unknown>tag</unknown>');
|
|
|
|
// make sure we check beyond the first letter
|
|
assertConverts('<bunknown>tag</bunknown>', '<bunknown>tag</bunknown>');
|
|
assertEscapes('<bunknown>tag</bunknown>', '<bunknown>tag</bunknown>');
|
|
|
|
// with mix of good and bad, we keep the good and escape the bad
|
|
assertConverts('<i>known</i> and <unknown>tag</unknown>', '<i>known</i> and <unknown>tag</unknown>');
|
|
assertEscapes('<i>known</i> and <unknown>tag</unknown>', '<i>known</i> and <unknown>tag</unknown>');
|
|
|
|
|
|
|
|
// FULLY INCORRECT MARKUP
|
|
// (fall back to escaping the whole thing)
|
|
|
|
// tags not matched up
|
|
assertConverts('<b>in<i>com</i>plete', '<b>in<i>com</i>plete');
|
|
assertEscapes('<b>in<i>com</i>plete', '<b>in<i>com</i>plete');
|
|
|
|
assertConverts('in<i>com</i>plete</b>', 'in<i>com</i>plete</b>');
|
|
assertEscapes('in<i>com</i>plete</b>', '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('<b>good</b> and <b style=\'bad\'>bad</b>', '<b>good</b> and <b style='bad'>bad</b>');
|
|
assertEscapes('<b>good</b> and <b style=\'bad\'>bad</b>', '<b>good</b> and <b style='bad'>bad</b>');
|
|
|
|
// this is just syntactically invalid
|
|
assertConverts('<b>unrecognized</b stuff>', '<b>unrecognized</b stuff>');
|
|
assertEscapes('<b>unrecognized</b stuff>', '<b>unrecognized</b stuff>');
|
|
|
|
// mismatched tags
|
|
assertConverts('<b>mismatched</i>', '<b>mismatched</i>');
|
|
assertEscapes('<b>mismatched</i>', '<b>mismatched</i>');
|
|
|
|
assertConverts('<b>mismatched/unknown</bunknown>', '<b>mismatched/unknown</bunknown>');
|
|
assertEscapes('<b>mismatched/unknown</bunknown>', '<b>mismatched/unknown</bunknown>');
|