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);
}
}