diff options
Diffstat (limited to '')
-rw-r--r-- | tests/unit/markup.js | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/tests/unit/markup.js b/tests/unit/markup.js new file mode 100644 index 0000000..603ca81 --- /dev/null +++ b/tests/unit/markup.js @@ -0,0 +1,143 @@ +// -*- 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>'); |