diff --git a/test/tests/utilities_internalTest.js b/test/tests/utilities_internalTest.js
index e4b4b0bc0a..6885a71e57 100644
--- a/test/tests/utilities_internalTest.js
+++ b/test/tests/utilities_internalTest.js
@@ -776,4 +776,132 @@ describe("Zotero.Utilities.Internal", function () {
});
});
});
+
+ describe("#renderItemTitle()", function () {
+ function renderToElement(title) {
+ let elem = new DOMParser().parseFromString('
', 'text/html')
+ .querySelector('div');
+ Zotero.Utilities.Internal.renderItemTitle(title, elem);
+ return elem;
+ }
+
+ function renderToHTML(title) {
+ return renderToElement(title).innerHTML;
+ }
+
+ function renderToTextViaHTML(title) {
+ return renderToElement(title).textContent;
+ }
+
+ function renderToText(title) {
+ return Zotero.Utilities.Internal.renderItemTitle(title);
+ }
+
+ it("should render a title without tags unchanged", function () {
+ assert.equal(renderToHTML('My Title'), 'My Title');
+ assert.equal(renderToHTML('1 < 2'), '1 < 2');
+ assert.equal(renderToHTML('<> READ THIS'), '<<ATTENTION>> READ THIS');
+ });
+
+ it("should render single-level tags", function () {
+ let examples = [
+ 'My Title XYZ',
+ 'My Title XYZ',
+ 'My Title XYZ',
+ 'My Title XYZ',
+ ];
+ for (let example of examples) {
+ assert.equal(renderToHTML(example), example);
+ }
+
+ assert.equal(renderToHTML('My Title XYZ'), 'My Title XYZ');
+ // Citeproc wants no space, DOM output includes space. Confusing!
+ assert.equal(
+ renderToHTML('My Title XYZ'),
+ 'My Title XYZ'
+ );
+ });
+
+ it("should render a tag nested inside a different tag", function () {
+ let examples = [
+ 'My Title XYZ',
+ 'My Title XYZ',
+ 'My Title XYZ',
+ ];
+ for (let example of examples) {
+ assert.equal(renderToHTML(example), example);
+ }
+ });
+
+ it("should preserve mismatched opening and closing tags", function () {
+ assert.equal(
+ renderToHTML('My Title XYZ'),
+ 'My <b>Title XYZ'
+ );
+ assert.equal(
+ renderToHTML('My Title XYZ'),
+ 'My Title</i> XYZ'
+ );
+ assert.equal(
+ renderToHTML('My Title XYZ'),
+ 'My <span class="font-variant:small-caps;">Title XYZ'
+ );
+ assert.equal(
+ renderToHTML('My Title XYZ'),
+ 'My <span class="font-variant:small-caps;">Title</span> XYZ'
+ );
+ });
+
+ it("should preserve matched but unsupported tags", function () {
+ assert.equal(
+ renderToHTML('My Title XYZ'),
+ 'My <em>Title</em> XYZ'
+ );
+ assert.equal(
+ renderToHTML('My Title XYZ'),
+ 'My <strong>Title</strong> XYZ'
+ );
+ assert.equal(
+ renderToHTML('My Title XYZ'), // Extra space
+ 'My <span class="font-variant: small-caps;">Title</span> XYZ'
+ );
+ assert.equal(
+ renderToHTML('My Title XYZ'), // Extra space
+ 'My <span>Title</span> XYZ'
+ );
+ });
+
+ it("should invert a tag nested inside itself", function () {
+ assert.equal(
+ renderToHTML('A Title in Italics'),
+ 'A Title in Italics'
+ );
+ assert.equal(
+ renderToHTML('A Title in Bold'),
+ 'A Title in Bold'
+ );
+ });
+
+ it("should invert a tag nested inside itself, with a different tag in between", function () {
+ assert.equal(
+ renderToHTML('A Title in Italics'),
+ 'A Title in Italics'
+ );
+ });
+
+ it("should render the same text directly and via DOM", function () {
+ let examples = [
+ 'Basic Title',
+ 'Complicated Title',
+ 'Complicated Title With More Text',
+ 'Nested Title With More Text',
+ 'Self-Nested Title With More Text',
+ 'Fe1−xO',
+ 'Title with like this',
+ ];
+ for (let example of examples) {
+ assert.equal(renderToTextViaHTML(example), renderToText(example));
+ }
+ });
+ });
});