diff --git a/webodf/lib/core/UnitTester.js b/webodf/lib/core/UnitTester.js index 8bbf394c4..ee0be4b57 100644 --- a/webodf/lib/core/UnitTester.js +++ b/webodf/lib/core/UnitTester.js @@ -568,8 +568,13 @@ core.UnitTester = function UnitTester() { * @return {!string} **/ function link(text, code) { + // NASTY HACK, DO NOT RE-USE. String concatenation with uncontrolled user input is a bad idea for building DOM + // fragments everyone. If you feel tempted to extract the HTML escape thing from here, please force yourself to + // visit http://shebang.brandonmintern.com/foolproof-html-escaping-in-javascript/ first, and learn a better + // approach to take. + return "" - + text + ""; + + text.replace(/"; } /** * @type {function(!{description:string,suite:!Array.,success:boolean,log:!Array.<{category:string,message:string}>,time:number})} @@ -634,7 +639,7 @@ core.UnitTester = function UnitTester() { + link(testName, "runSuite(\"" + testName + "\");") + ": " + test.description() + ""); } else { - runtime.log("Running " + testName + ": " + test.description); + runtime.log("Running " + testName + ": " + test.description()); } tests = test.tests(); for (i = 0; i < tests.length; i += 1) { diff --git a/webodf/tests/ops/OdtDocumentTests.js b/webodf/tests/ops/OdtDocumentTests.js index 99cab2728..4f6f4a37d 100644 --- a/webodf/tests/ops/OdtDocumentTests.js +++ b/webodf/tests/ops/OdtDocumentTests.js @@ -158,11 +158,12 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) { documentRoot; serializer.filter = new OdfOrCursorNodeFilter(); - runtime.log("Scenario: " + documentString); t.segmentCount = segments.length; + t.expectedCursorPositionsCount = segments.length - 1; // e.g., | has two segments, but only one cursor position r.shouldBe(t, "t.segmentCount > 1", "true"); documentRoot = createOdtDocument(segments.join("")); t.documentLength = t.odtDocument.convertDomPointToCursorStep(documentRoot, documentRoot.childNodes.length, PREVIOUS); + r.shouldBe(t, "t.expectedCursorPositionsCount", "(t.documentLength+1)"); // Test iteration forward for (position = 1; position < segments.length; position += 1) { @@ -186,6 +187,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) { // Test iteration backward for (position = segments.length - 1; position > 0; position -= 1) { setCursorPosition(step); + t.currentDocLength = t.odtDocument.convertDomPointToCursorStep(documentRoot, documentRoot.childNodes.length, PREVIOUS); r.shouldBe(t, "t.currentDocLength", "t.documentLength"); t.expected = "" + segments.slice(0, position).join("") + "|" + segments.slice(position, segments.length).join("") + @@ -363,76 +365,6 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) { r.shouldBe(t, "t.rootToFocus", "1"); } - function testAvailablePositions_EmptyParagraph() { - // Examples from README_cursorpositions.txt - testCursorPositions("|"); - // TODO behaviour is different from README_cursorpositions - // cursorPositionsTest("|"); - // TODO behaviour is different from README_cursorpositions - // cursorPositionsTest("|"); - // TODO behaviour is different from README_cursorpositions - // cursorPositionsTest("|"); - testCursorPositions("| "); - // TODO behaviour is different from README_cursorpositions - // cursorPositionsTest(" | "); - // TODO behaviour is different from README_cursorpositions - // cursorPositionsTest(" | "); - } - function testAvailablePositions_SimpleTextNodes() { - // Examples from README_cursorpositions.txt - testCursorPositions("|A|B|C|"); - } - function testAvailablePositions_MixedSpans() { - // Examples from README_cursorpositions.txt - testCursorPositions("|A|B|C|"); - testCursorPositions("|A|B|C|"); - testCursorPositions("|A|B|C|"); - testCursorPositions("|A|B|C|"); - testCursorPositions("|A|B|C|"); - } - function testAvailablePositions_Whitespace() { - // Examples from README_cursorpositions.txt - testCursorPositions("|A| |B|C|"); - testCursorPositions(" |A| "); - testCursorPositions("|A| |B|"); - testCursorPositions(" |A| | B| "); - testCursorPositions(" |a| "); - testCursorPositions(" |a| | b| "); - // TODO behaviour is different from README_cursorpositions - // cursorPositionsTest(" |a| "); - testCursorPositions(" |a| "); - testCursorPositions(" |a|"); - } - function testAvailablePositions_SpaceElements() { - // Examples from README_cursorpositions.txt - testCursorPositions("|A| |B|C|"); - // Unexpanded spaces - Not really supported, but interesting to test - testCursorPositions("|A||B|C|"); - // Slight span nesting and positioning - testCursorPositions("| |"); - // TODO behaviour is different from README_cursorpositions - // cursorPositionsTest(" |A| | | |B| "); - testCursorPositions("| | | |"); - testCursorPositions("| | | |"); - testCursorPositions("|a| | | "); - testCursorPositions("|a| | |"); - } - function testAvailablePositions_DrawElements() { - testCursorPositions("|data|"); - testCursorPositions("|data|"); - } - function testAvailablePositions_Annotations() { - testCursorPositions('|a|b|||c|d|1|2|'); - testCursorPositions('|a||b||c|1|2|'); - testCursorPositions('|a||b||1|2|'); - } - function testAvailablePositions_BetweenAnnotationAndSpan() { - testCursorPositions('|a|b|||c|d|1|2|'); - testCursorPositions('|a||b||c|1|2|'); - testCursorPositions('|a||b||1|2|'); - } - - function getTextNodeAtStep_BeginningOfTextNode() { var doc = createOdtDocument("ABCD"); t.paragraph = doc.getElementsByTagNameNS(odf.Namespaces.textns, "p")[0]; @@ -624,6 +556,89 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) { r.shouldBe(t, "t.domPosition.textNode.previousSibling.localName", "'cursor'"); } + function cursorPositionTests() { + // Examples from README_cursorpositions.txt + + return [ + // *************** Empty Paragraph *************** // + // Examples from README_cursorpositions.txt + "|", + // TODO behaviour is different from README_cursorpositions + // "|", + // TODO behaviour is different from README_cursorpositions + // "|", + // TODO behaviour is different from README_cursorpositions + // "|", + "| ", + // TODO behaviour is different from README_cursorpositions + // " | ", + // TODO behaviour is different from README_cursorpositions + // " | ", + + + // *************** Simple Text Nodes *************** // + "|A|B|C|", + + + // *************** Mixed spans *************** // + "|A|B|C|", + "|A|B|C|", + "|A|B|C|", + "|A|B|C|", + "|A|B|C|", + + + // *************** Whitespace *************** // + "|A| |B|C|", + " |A| ", + "|A| |B|", + " |A| | B| ", + " |a| ", + " |a| | b| ", + // TODO behaviour is different from README_cursorpositions + // cursorPositionsTest(" |a| ", + " |a| ", + " |a|", + + + // *************** Space elements *************** // + "|A| |B|C|", + // Unexpanded spaces - Not really supported, but interesting to test + "|A||B|C|", + // Slight span nesting and positioning + "| |", + // TODO behaviour is different from README_cursorpositions + // cursorPositionsTest(" |A| | | |B| ", + "| | | |", + "| | | |", + "|a| | | ", + "|a| | |", + + + // *************** Draw elements *************** // + "|data|", + "|data|", + + + // *************** Annotations *************** // + '|a|b|||c|d|1|2|', + '|a||b||c|1|2|', + '|a||b||1|2|', + + + // *************** Annotations with highlighting *************** // + '|a|b|||c|d|1|2|', + '|a||b||c|1|2|', + '|a||b||1|2|' + + ].map(function(testInput) { + return { + name: "cursorPositions " + testInput, + f: testCursorPositions.bind(undefined, testInput) + }; + }); + } + this.setUp = function () { var doc, stylesElement; testarea = core.UnitTest.provideTestAreaDiv(); @@ -656,15 +671,6 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) { testFixCursorPositions_CursorNearParagraphStart_ForwardSelection, testFixCursorPositions_CursorNearParagraphStart_ReverseSelection, - testAvailablePositions_EmptyParagraph, - testAvailablePositions_SimpleTextNodes, - testAvailablePositions_MixedSpans, - testAvailablePositions_Whitespace, - testAvailablePositions_SpaceElements, - testAvailablePositions_DrawElements, - testAvailablePositions_Annotations, - testAvailablePositions_BetweenAnnotationAndSpan, - getTextNodeAtStep_BeginningOfTextNode, getTextNodeAtStep_EndOfTextNode, getTextNodeAtStep_PositionWithNoTextNode_AddsNewNode_Front, @@ -680,7 +686,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) { getTextNodeAtStep_At4_PutsTargetMemberCursor_BeforeTextNode, getTextNodeAtStep_AfterNonText_PutsTargetMemberCursor_BeforeTextNode, getTextNodeAtStep_EmptyP_MovesAllCursors_BeforeTextNode - ]); + ]).concat(cursorPositionTests()); }; this.asyncTests = function () { return [ diff --git a/webodf/tests/tests.js b/webodf/tests/tests.js index e4033ff3c..94d680b04 100644 --- a/webodf/tests/tests.js +++ b/webodf/tests/tests.js @@ -188,7 +188,7 @@ function runSuite(name) { } function runTest(suite, name) { "use strict"; - runtime.getWindow().location.search = "?suite=" + suite + "&test=" + name; + runtime.getWindow().location.search = "?suite=" + suite + "&test=" + encodeURIComponent(name); } function runSelectedTests(selectedTests) { @@ -211,7 +211,7 @@ function getTestNameFromUrl(selectedTests) { return; } if (options.test) { - selectedTests.testNames = options.test.split(","); + selectedTests.testNames = options.test.split(",").map(decodeURIComponent); } }