diff --git a/tests/meson.build b/tests/meson.build
index c0431631f..50fb601e9 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -10,7 +10,17 @@ run_test = configure_file(
testenv = environment()
testenv.set('GSETTINGS_SCHEMA_DIR', join_paths(meson.build_root(), 'data'))
-foreach test : ['insertSorted', 'jsParse', 'markup', 'params', 'url', 'versionCompare']
+tests = [
+ 'highlighter',
+ 'insertSorted',
+ 'jsParse',
+ 'markup',
+ 'params',
+ 'url',
+ 'versionCompare',
+]
+
+foreach test : tests
test(test, run_test,
args: 'unit/@0@.js'.format(test),
env: testenv,
diff --git a/tests/unit/highlighter.js b/tests/unit/highlighter.js
new file mode 100644
index 000000000..d582d38e3
--- /dev/null
+++ b/tests/unit/highlighter.js
@@ -0,0 +1,106 @@
+// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
+
+// Test cases for SearchResult description match highlighter
+
+const JsUnit = imports.jsUnit;
+const Pango = imports.gi.Pango;
+
+const Environment = imports.ui.environment;
+Environment.init();
+
+const Util = imports.misc.util;
+
+const tests = [
+ { input: 'abc cba',
+ terms: null,
+ output: 'abc cba' },
+ { input: 'abc cba',
+ terms: [],
+ output: 'abc cba' },
+ { input: 'abc cba',
+ terms: [''],
+ output: 'abc cba' },
+ { input: 'abc cba',
+ terms: ['a'],
+ output: 'abc cba' },
+ { input: 'abc cba',
+ terms: ['a', 'a'],
+ output: 'abc cba' },
+ { input: 'CaSe InSenSiTiVe',
+ terms: ['cas', 'sens'],
+ output: 'CaSe InSenSiTiVe' },
+ { input: 'This contains the < character',
+ terms: null,
+ output: 'This contains the < character' },
+ { input: 'Don\'t',
+ terms: ['t'],
+ output: 'Don't' },
+ { input: 'Don\'t',
+ terms: ['n\'t'],
+ output: 'Don't' },
+ { input: 'Don\'t',
+ terms: ['o', 't'],
+ output: 'Don't' },
+ { input: 'salt&pepper',
+ terms: ['salt'],
+ output: 'salt&pepper' },
+ { input: 'salt&pepper',
+ terms: ['salt', 'alt'],
+ output: 'salt&pepper' },
+ { input: 'salt&pepper',
+ terms: ['pepper'],
+ output: 'salt&pepper' },
+ { input: 'salt&pepper',
+ terms: ['salt', 'pepper'],
+ output: 'salt&pepper' },
+ { input: 'salt&pepper',
+ terms: ['t', 'p'],
+ output: 'salt&pepper' },
+ { input: 'salt&pepper',
+ terms: ['t', '&', 'p'],
+ output: 'salt&pepper' },
+ { input: 'salt&pepper',
+ terms: ['e'],
+ output: 'salt&pepper' },
+ { input: 'salt&pepper',
+ terms: ['&a', '&am', '&', '&'],
+ output: 'salt&pepper' },
+ { input: '&&&&&',
+ terms: ['a'],
+ output: '&&&&&' },
+ { input: '&;&;&;&;&;',
+ terms: ['a'],
+ output: '&;&;&;&;&;' },
+ { input: '&;&;&;&;&;',
+ terms: [';'],
+ output: '&;&;&;&;&;' },
+ { input: '&',
+ terms: ['a'],
+ output: '&' }
+];
+
+try {
+ for (let i = 0; i < tests.length; i++) {
+ let highlighter = new Util.Highlighter(tests[i].terms);
+ let output = highlighter.highlight(tests[i].input);
+
+ JsUnit.assertEquals(`Test ${i + 1} highlight ` +
+ `"${tests[i].terms}" in "${tests[i].input}"`,
+ output, tests[i].output);
+
+ let parsed = false;
+ try {
+ Pango.parse_markup(output, -1, '');
+ parsed = true;
+ } catch (e) {}
+ JsUnit.assertEquals(`Test ${i + 1} is valid markup`, true, parsed);
+ }
+} catch (e) {
+ if (typeof(e.isJsUnitException) != 'undefined'
+ && e.isJsUnitException)
+ {
+ if (e.comment)
+ log(`Error in: ${e.comment}`);
+ }
+ throw e;
+}