<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[19968] trunk</title>
</head>
<body>
<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/19968">19968</a></dd>
<dt>Author</dt> <dd>ap</dd>
<dt>Date</dt> <dd>2007-03-05 12:39:41 -0800 (Mon, 05 Mar 2007)</dd>
</dl>
<h3>Log Message</h3>
<pre> Reviewed by Darin.
http://bugs.webkit.org/show_bug.cgi?id=12970
Fix and import 4XPath test_core_functions.html test
WebCore:
* xml/XPathExpression.cpp:
(WebCore::XPathExpression::evaluate): Fully initialize the evaluation context.
* xml/XPathFunctions.cpp:
(WebCore::XPath::FunSubstring::doEvaluate): Fixed handling of edge cases.
(WebCore::XPath::FunRound::round): Reimplemented to match the spec; exposed FunRound::round() to be used in
other functions.
LayoutTests:
* fast/xpath/4XPath/Core/test_core_functions-expected.txt: Added.
* fast/xpath/4XPath/Core/test_core_functions.html: Added.
The remaining failures with id() are caused by an XML DOM problem - ID attributes declared
in an internal subset are not treated as such.
* fast/xpath/4XPath/Core/test.js: Common data for XPath tests.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsfastxpath4XPathCoretest_core_functionsexpectedtxt">trunk/LayoutTests/fast/xpath/4XPath/Core/test_core_functions-expected.txt</a></li>
<li><a href="#trunkWebCoreChangeLog">trunk/WebCore/ChangeLog</a></li>
<li><a href="#trunkWebCorexmlXPathExpressioncpp">trunk/WebCore/xml/XPathExpression.cpp</a></li>
<li><a href="#trunkWebCorexmlXPathFunctionscpp">trunk/WebCore/xml/XPathFunctions.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastxpath4XPathCoretestjs">trunk/LayoutTests/fast/xpath/4XPath/Core/test.js</a></li>
<li><a href="#trunkLayoutTestsfastxpath4XPathCoretest_core_functionshtml">trunk/LayoutTests/fast/xpath/4XPath/Core/test_core_functions.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (19967 => 19968)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2007-03-05 20:29:11 UTC (rev 19967)
+++ trunk/LayoutTests/ChangeLog        2007-03-05 20:39:41 UTC (rev 19968)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2007-03-05 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin.
+
+ http://bugs.webkit.org/show_bug.cgi?id=12970
+ Fix and import 4XPath test_core_functions.html test
+
+ * fast/xpath/4XPath/Core/test_core_functions-expected.txt: Added.
+ * fast/xpath/4XPath/Core/test_core_functions.html: Added.
+ The remaining failures with id() are caused by an XML DOM problem - ID attributes declared
+ in an internal subset are not treated as such.
+
+ * fast/xpath/4XPath/Core/test.js: Common data for XPath tests.
+
</ins><span class="cx"> 2007-03-05 Anders Carlsson <acarlsson@apple.com>
</span><span class="cx">
</span><span class="cx"> * plugins/get-url-with-blank-target-expected.txt:
</span></span></pre></div>
<a id="trunkLayoutTestsfastxpath4XPathCoretestjsfromrev19963trunkLayoutTestsfastxpath4XPathCoretestjs"></a>
<div class="copfile"><h4>Copied: trunk/LayoutTests/fast/xpath/4XPath/Core/test.js (from rev 19963, trunk/LayoutTests/fast/xpath/4XPath/Core/test.js) (0 => 19968)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/xpath/4XPath/Core/test.js         (rev 0)
+++ trunk/LayoutTests/fast/xpath/4XPath/Core/test.js        2007-03-05 20:39:41 UTC (rev 19968)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+DOM = (new DOMParser).parseFromString(
+ '<?xml version="1.0" encoding="ISO-8859-1"?>' +
+ '<!DOCTYPE ROOT [' +
+ ' <!ELEMENT CHILD2 (#PCDATA|GCHILD)*>' +
+ ' <!ATTLIST CHILD2 attr1 CDATA #IMPLIED' +
+ ' CODE ID #REQUIRED>' +
+ ']>' +
+ '<?xml-stylesheet "Data" ?>' +
+ '<ROOT>' +
+ ' <!-- Test Comment -->' +
+ ' <CHILD1 attr1="val1" attr31="31">' +
+ ' <GCHILD name="GCHILD11"/>' +
+ ' <GCHILD name="GCHILD12"/>' +
+ ' Text1' +
+ ' </CHILD1>' +
+ ' <CHILD2 attr1="val2" CODE="1">' +
+ ' <GCHILD name="GCHILD21"/>' +
+ ' <GCHILD name="GCHILD22"/>' +
+ ' </CHILD2>' +
+ ' <foo:CHILD3 xmlns:foo="http://foo.com" foo:name="mike"/>' +
+ ' <lang xml:lang="en">' +
+ ' <foo xml:lang=""/>' +
+ ' <foo/>' +
+ ' <f\xf6\xf8/>' +
+ ' </lang>' +
+ '</ROOT>' +
+ '<?no-data ?>',
+ 'application/xml');
+
+DOM = DOM;
+ROOT = DOM.documentElement;
+
+PI = DOM.firstChild;
+while (PI.nodeType != Node.PROCESSING_INSTRUCTION_NODE)
+ PI = PI.nextSibling;
+PI2 = DOM.lastChild;
+COMMENT = ROOT.firstChild
+while (COMMENT.nodeType != Node.COMMENT_NODE)
+ COMMENT = COMMENT.nextSibling;
+
+CHILD1 = DOM.getElementsByTagName("CHILD1")[0];
+ATTR1 = CHILD1.getAttributeNode("attr1");
+ATTR31 = CHILD1.getAttributeNode("attr31");
+CHILD2 = DOM.getElementsByTagName("CHILD2")[0];
+ATTR2 = CHILD2.getAttributeNode("attr1");
+IDATTR2 = CHILD2.getAttributeNode('CODE')
+CHILD3 = DOM.getElementsByTagName("CHILD3")[0];
+text = CHILD1.lastChild;
+LANG = DOM.getElementsByTagName("lang")[0];
+NONASCIIQNAME = DOM.getElementsByTagName("f\xf6\xf8")[0];
+
+CHILDREN = [CHILD1, CHILD2, CHILD3, LANG];
+GCHILDREN1 = [CHILD1.getElementsByTagName("GCHILD")[0], CHILD1.getElementsByTagName("GCHILD")[1]];
+GCHILD11 = GCHILDREN1[0];
+GCHILD12 = GCHILDREN1[1];
+TEXT1 = CHILD1.lastChild;
+GCHILDREN2 = [CHILD2.getElementsByTagName("GCHILD")[0], CHILD2.getElementsByTagName("GCHILD")[1]];
+GCHILD21 = GCHILDREN2[0];
+GCHILD22 = GCHILDREN2[1];
+LCHILDREN = [LANG.getElementsByTagName("foo")[0], LANG.getElementsByTagName("foo")[1], LANG.getElementsByTagName("f\xf6\xf8")[0]];
+LCHILD1 = LCHILDREN[0];
+LCHILD2 = LCHILDREN[1];
+
+function checkSnapshot(comment, actual, expected) {
+ if (actual.snapshotLength != expected.length) {
+ testFailed(comment + " incorrect length (expected " + expected.length + ", actual " + actual.snapshotLength + ")");
+ return;
+ }
+
+ for (i = 0; i < actual.snapshotLength; ++i) {
+ if (actual.snapshotItem(i) != expected[i]) {
+ testFailed(comment + " item " + i + " incorrect (expected " + expected[i].nodeName + ", actual " + actual.snapshotItem(i).nodeName + ")");
+ return;
+ }
+ }
+
+ testPassed(comment);
+}
</ins></span></pre></div>
<a id="trunkLayoutTestsfastxpath4XPathCoretest_core_functionsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/xpath/4XPath/Core/test_core_functions-expected.txt (19967 => 19968)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/xpath/4XPath/Core/test_core_functions-expected.txt        2007-03-05 20:29:11 UTC (rev 19967)
+++ trunk/LayoutTests/fast/xpath/4XPath/Core/test_core_functions-expected.txt        2007-03-05 20:39:41 UTC (rev 19968)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-FAIL DOM.evaluate("last()", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue should be 1 (of type number). Was 0 (of type number).
</del><ins>+PASS DOM.evaluate("last()", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is 1
</ins><span class="cx"> PASS DOM.evaluate("position()", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is 1
</span><span class="cx"> PASS DOM.evaluate("count(/ROOT | /ROOT/CHILD1)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is 2
</span><span class="cx"> FAIL id(1) incorrect length (expected 1, actual 0)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> PASS DOM.evaluate("substring('12345', 1.5, 2.6)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue is "234"
</span><span class="cx"> PASS DOM.evaluate("substring('12345', 0, 3)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue is "12"
</span><span class="cx"> PASS DOM.evaluate("substring('12345', number('NaN'), 3)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue is ""
</span><del>-FAIL DOM.evaluate("substring('12345', 1, number('NaN'))", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue should be (of type string). Was 12345 (of type string).
</del><ins>+PASS DOM.evaluate("substring('12345', 1, number('NaN'))", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue is ""
</ins><span class="cx"> PASS DOM.evaluate("substring('12345', -42, 1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue is "12345"
</span><span class="cx"> PASS DOM.evaluate("substring('12345', -1 div 0, 1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue is ""
</span><span class="cx"> PASS DOM.evaluate("string-length('3.14Hi')", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is 6
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx"> PASS DOM.evaluate("ceiling(0.5)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is 1
</span><span class="cx"> PASS DOM.evaluate("ceiling(-0.5)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is 0
</span><span class="cx"> PASS DOM.evaluate("round(3.14)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is 3
</span><del>-FAIL DOM.evaluate("round(-4.5)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue should be -4 (of type number). Was -5 (of type number).
</del><ins>+PASS DOM.evaluate("round(-4.5)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is -4
</ins><span class="cx"> PASS DOM.evaluate("round(number('NaN'))", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is NaN
</span><span class="cx"> PASS DOM.evaluate("round(1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is Infinity
</span><span class="cx"> PASS DOM.evaluate("round(-1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue is -Infinity
</span></span></pre></div>
<a id="trunkLayoutTestsfastxpath4XPathCoretest_core_functionshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/xpath/4XPath/Core/test_core_functions.html (0 => 19968)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/xpath/4XPath/Core/test_core_functions.html         (rev 0)
+++ trunk/LayoutTests/fast/xpath/4XPath/Core/test_core_functions.html        2007-03-05 20:39:41 UTC (rev 19968)
</span><span class="lines">@@ -0,0 +1,115 @@
</span><ins>+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../../js/resources/js-test-style.css">
+<script src="../../../js/resources/js-test-pre.js"></script>
+<script src="test.js"></script>
+</head>
+<body>
+<div id="console"></div>
+
+<script>
+ function nsResolver(prefix) {
+ if (prefix == 'f')
+ return 'http://foo.com';
+ return null;
+ }
+
+ shouldBe('DOM.evaluate("last()", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '1');
+ shouldBe('DOM.evaluate("position()", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '1');
+ shouldBe('DOM.evaluate("count(/ROOT | /ROOT/CHILD1)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '2');
+
+ result = DOM.evaluate("id(1)", CHILD1, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ checkSnapshot("id(1)", result, [CHILD2]);
+
+ result = DOM.evaluate("id('1 1')", CHILD1, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ checkSnapshot("id('1 1')", result, [CHILD2]);
+
+ result = DOM.evaluate("id('0')", CHILD1, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ checkSnapshot("id('0')", result, []);
+
+ result = DOM.evaluate("id('0 1')", CHILD1, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ checkSnapshot("id('0 1')", result, [CHILD2]);
+
+ result = DOM.evaluate("id('0 1 1')", CHILD1, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ checkSnapshot("id('0 1 1')", result, [CHILD2]);
+
+ result = DOM.evaluate("id('0 0 1 1')", CHILD1, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ checkSnapshot("id('0 0 1 1')", result, [CHILD2]);
+
+ shouldBe('DOM.evaluate("local-name(/empty)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '""');
+ shouldBe('DOM.evaluate("local-name(//f:CHILD3)", CHILD1, nsResolver, XPathResult.ANY_TYPE, null).stringValue', '"CHILD3"');
+ shouldBe('DOM.evaluate("namespace-uri(/empty)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '""');
+ shouldBe('DOM.evaluate("namespace-uri(//f:CHILD3)", CHILD1, nsResolver, XPathResult.ANY_TYPE, null).stringValue', '"http://foo.com"');
+ shouldBe('DOM.evaluate("name(//f:CHILD3)", CHILD1, nsResolver, XPathResult.ANY_TYPE, null).stringValue', '"foo:CHILD3"');
+
+ strNodeset3 = " Text1 ";
+
+ shouldBe('DOM.evaluate("string(//CHILD1)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', 'strNodeset3');
+ shouldBe('DOM.evaluate("concat(//CHILD1, \'3.14\', \'Hi\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', 'strNodeset3 + "3.14Hi"');
+ shouldBe('DOM.evaluate("starts-with(//CHILD1, \'3.14\')", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'false');
+ shouldBe('DOM.evaluate("starts-with(//CHILD1, //CHILD1)", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'true');
+ shouldBe('DOM.evaluate("starts-with(//CHILD1, \'\')", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'true');
+ shouldBe('DOM.evaluate("contains(//CHILD1, \'3.14\')", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'false');
+ shouldBe('DOM.evaluate("contains(//CHILD1, //CHILD1)", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'true');
+ shouldBe('DOM.evaluate("contains(//CHILD1, \'\')", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'true');
+ shouldBe('DOM.evaluate("substring-before(\'3.14Hi\', \'Hi\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"3.14"');
+ shouldBe('DOM.evaluate("substring-before(\'3.14Hi\', \'\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '""');
+ shouldBe('DOM.evaluate("substring-after(\'3.14Hi\', \'3.14\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"Hi"');
+ shouldBe('DOM.evaluate("substring-after(\'3.14Hi\', \'\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '""');
+ shouldBe('DOM.evaluate("substring(\'3.14Hi\', \'3.14\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"14Hi"');
+ shouldBe('DOM.evaluate("substring(\'3.14Hi\', \'3.14\', 1)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"1"');
+ shouldBe('DOM.evaluate("substring(\'12345\', 2, 3)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"234"');
+ shouldBe('DOM.evaluate("substring(\'12345\', 2)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"2345"');
+ shouldBe('DOM.evaluate("substring(\'12345\', 1.5, 2.6)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"234"');
+ shouldBe('DOM.evaluate("substring(\'12345\', 0, 3)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"12"');
+ shouldBe('DOM.evaluate("substring(\'12345\', number(\'NaN\'), 3)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '""');
+ shouldBe('DOM.evaluate("substring(\'12345\', 1, number(\'NaN\'))", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '""');
+ shouldBe('DOM.evaluate("substring(\'12345\', -42, 1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"12345"');
+ shouldBe('DOM.evaluate("substring(\'12345\', -1 div 0, 1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '""');
+ shouldBe('DOM.evaluate("string-length(\'3.14Hi\')", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '6');
+ shouldBe('DOM.evaluate("normalize-space(\'Ht \t There\t Mike\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"Ht There Mike"');
+ shouldBe('DOM.evaluate("translate(\'Ht \t There\t Mike\', \'abcdefg\', \'ABCDEFG\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"Ht \t ThErE\t MikE"');
+ shouldBe('DOM.evaluate("translate(\'hello world\', \'e\', \'a\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"hallo world"');
+ shouldBe('DOM.evaluate("translate(\'hello world\', \'e\', \'abc\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"hallo world"');
+ shouldBe('DOM.evaluate("translate(\'hello world\', \'el\', \'a\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"hao word"');
+ shouldBe('DOM.evaluate("translate(\'hello world\', \'abcdefgabc\', \'ABCDEFG123\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"hEllo worlD"');
+ shouldBe('DOM.evaluate("translate(\'hello world\', \'abcdefghhe\', \'ABCDEFGH\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"HEllo worlD"');
+ shouldBe('DOM.evaluate("translate(\'hello world\', \'abcdefgh\', \'\')", CHILD1, null, XPathResult.ANY_TYPE, null).stringValue', '"llo worl"');
+
+ shouldBe('DOM.evaluate("boolean(\'3.14\')", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'true');
+ shouldBe('DOM.evaluate("not(\'3.14Hi\')", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'false');
+ shouldBe('DOM.evaluate("true()", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'true');
+ shouldBe('DOM.evaluate("false()", CHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'false');
+
+ shouldBe('DOM.evaluate("number(\'NaN\')", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', 'NaN');
+ shouldBe('DOM.evaluate("floor(3.14)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '3');
+ shouldBe('DOM.evaluate("floor(number())", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', 'NaN');
+ shouldBe('DOM.evaluate("floor(1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', 'Infinity');
+ shouldBe('DOM.evaluate("floor(-1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '-Infinity');
+ shouldBe('DOM.evaluate("floor(0.5)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '0');
+ shouldBe('DOM.evaluate("floor(-0.5)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '-1');
+ shouldBe('DOM.evaluate("ceiling(3.14)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '4');
+ shouldBe('DOM.evaluate("ceiling(number(\'NaN\'))", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', 'NaN');
+ shouldBe('DOM.evaluate("ceiling(1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', 'Infinity');
+ shouldBe('DOM.evaluate("ceiling(0.5)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '1');
+ shouldBe('DOM.evaluate("ceiling(-0.5)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '0'); // actually should be negative zero
+ shouldBe('DOM.evaluate("round(3.14)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '3');
+ shouldBe('DOM.evaluate("round(-4.5)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '-4');
+ shouldBe('DOM.evaluate("round(number(\'NaN\'))", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', 'NaN');
+ shouldBe('DOM.evaluate("round(1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', 'Infinity');
+ shouldBe('DOM.evaluate("round(-1 div 0)", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '-Infinity');
+ shouldBe('DOM.evaluate("round(\'12345\')", CHILD1, null, XPathResult.ANY_TYPE, null).numberValue', '12345');
+ shouldBe('DOM.evaluate("lang(\'en\')", LCHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'false');
+ shouldBe('DOM.evaluate("lang(\'en\')", LCHILD2, null, XPathResult.ANY_TYPE, null).booleanValue', 'true');
+ shouldBe('DOM.evaluate("lang(\'\')", LCHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'true');
+ shouldBe('DOM.evaluate("lang(\'\')", LCHILD2, null, XPathResult.ANY_TYPE, null).booleanValue', 'false');
+ shouldBe('DOM.evaluate("lang(\'foo\')", LCHILD1, null, XPathResult.ANY_TYPE, null).booleanValue', 'false');
+ shouldBe('DOM.evaluate("lang(\'foo\')", LCHILD2, null, XPathResult.ANY_TYPE, null).booleanValue', 'false');
+
+ var successfullyParsed = true;
+
+</script>
+<script src="../../../js/resources/js-test-post.js"></script>
+</body>
+</html>
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/xpath/4XPath/Core/test_core_functions.html
</span><span class="cx">___________________________________________________________________
</span><span class="cx">Name: svn:mime-type
</span><span class="cx"> + text/html
</span></span></pre></div>
<a id="trunkWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/ChangeLog (19967 => 19968)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/ChangeLog        2007-03-05 20:29:11 UTC (rev 19967)
+++ trunk/WebCore/ChangeLog        2007-03-05 20:39:41 UTC (rev 19968)
</span><span class="lines">@@ -2,6 +2,21 @@
</span><span class="cx">
</span><span class="cx"> Reviewed by Darin.
</span><span class="cx">
</span><ins>+ http://bugs.webkit.org/show_bug.cgi?id=12970
+ Fix and import 4XPath test_core_functions.html test
+
+ * xml/XPathExpression.cpp:
+ (WebCore::XPathExpression::evaluate): Fully initialize the evaluation context.
+
+ * xml/XPathFunctions.cpp:
+ (WebCore::XPath::FunSubstring::doEvaluate): Fixed handling of edge cases.
+ (WebCore::XPath::FunRound::round): Reimplemented to match the spec; exposed FunRound::round() to be used in
+ other functions.
+
+2007-03-05 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin.
+
</ins><span class="cx"> http://bugs.webkit.org/show_bug.cgi?id=12954
</span><span class="cx"> XPath relative operations are implemented incorrectly
</span><span class="cx">
</span></span></pre></div>
<a id="trunkWebCorexmlXPathExpressioncpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/xml/XPathExpression.cpp (19967 => 19968)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/xml/XPathExpression.cpp        2007-03-05 20:29:11 UTC (rev 19967)
+++ trunk/WebCore/xml/XPathExpression.cpp        2007-03-05 20:39:41 UTC (rev 19968)
</span><span class="lines">@@ -71,7 +71,9 @@
</span><span class="cx"> ? contextNode->ownerDocument()
</span><span class="cx"> : static_cast<EventTargetNode*>(contextNode);
</span><span class="cx">
</span><del>- Expression::evaluationContext().node = contextNode;
</del><ins>+ Expression::evaluationContext().node = contextNode;
+ Expression::evaluationContext().size = 1;
+ Expression::evaluationContext().position = 1;
</ins><span class="cx"> m_topExpression->optimize();
</span><span class="cx"> RefPtr<XPathResult> result = new XPathResult(eventTarget, m_topExpression->evaluate());
</span><span class="cx">
</span></span></pre></div>
<a id="trunkWebCorexmlXPathFunctionscpp"></a>
<div class="modfile"><h4>Modified: trunk/WebCore/xml/XPathFunctions.cpp (19967 => 19968)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebCore/xml/XPathFunctions.cpp        2007-03-05 20:29:11 UTC (rev 19967)
+++ trunk/WebCore/xml/XPathFunctions.cpp        2007-03-05 20:39:41 UTC (rev 19968)
</span><span class="lines">@@ -186,6 +186,8 @@
</span><span class="cx">
</span><span class="cx"> class FunRound : public Function {
</span><span class="cx"> virtual Value doEvaluate() const;
</span><ins>+public:
+ static double round(double);
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> DEFINE_FUNCTION_CREATOR(FunLast)
</span><span class="lines">@@ -511,11 +513,15 @@
</span><span class="cx"> Value FunSubstring::doEvaluate() const
</span><span class="cx"> {
</span><span class="cx"> String s = arg(0)->evaluate().toString();
</span><del>- long pos = lround(arg(1)->evaluate().toNumber());
</del><ins>+ long pos = static_cast<long>(FunRound::round(arg(1)->evaluate().toNumber()));
</ins><span class="cx"> bool haveLength = argCount() == 3;
</span><span class="cx"> long len = -1;
</span><del>- if (haveLength)
- len = lround(arg(2)->evaluate().toNumber());
</del><ins>+ if (haveLength) {
+ double doubleLen = arg(2)->evaluate().toNumber();
+ if (isnan(doubleLen))
+ return "";
+ len = static_cast<long>(FunRound::round(doubleLen));
+ }
</ins><span class="cx">
</span><span class="cx"> if (pos > long(s.length()))
</span><span class="cx"> return "";
</span><span class="lines">@@ -671,6 +677,17 @@
</span><span class="cx"> return ceil(arg(0)->evaluate().toNumber());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+double FunRound::round(double val)
+{
+ if (!isnan(val) && !isinf(val)) {
+ if (signbit(val) && val >= -0.5)
+ val *= 0; // negative zero
+ else
+ val = floor(val + 0.5);
+ }
+ return val;
+}
+
</ins><span class="cx"> Value FunRound::doEvaluate() const
</span><span class="cx"> {
</span><span class="cx"> return round(arg(0)->evaluate().toNumber());
</span></span></pre>
</div>
</div>
</body>
</html>