functions.html revision 5f90462bbf4efb0ac7bb65a852d5559d0ab30f0b
1<html> 2<head> 3<link rel="stylesheet" href="/js/resources/js-test-style.css"> 4<script src="/js/resources/js-test-pre.js"></script> 5<script src="/xpath-test-pre.js"></script> 6</head> 7<body> 8<div id="console"></div> 9 10<script> 11var doc = (new DOMParser).parseFromString( 12 '<!DOCTYPE doc [<!ATTLIST item identifier ID #IMPLIED>]>' + 13 '<doc>' + 14 '<item id="1" identifier="a" />' + 15 '<item id="2" identifier="b" />' + 16 '<item id="3" identifier="c" />' + 17 '<item id="4" identifier="d" />' + 18 '<item id="5" identifier="e" />' + 19 '<reference>a</reference>' + 20 '<reference>c</reference>' + 21 '<reference>e</reference>' + 22 '<namespace xmlns="http://www.example.com/a" xmlns:b="http://www.example.com/b">' + 23 '<item id="6" />' + 24 '<b:item id="7" b:value="42" />' + 25 '</namespace>' + 26 '</doc>', 27 'application/xml'); 28 29var ROOT = doc.documentElement; 30var ITEM1 = ROOT.firstChild; 31var ITEM2 = ITEM1.nextSibling; 32var ITEM3 = ITEM2.nextSibling; 33var ITEM4 = ITEM3.nextSibling; 34var ITEM5 = ITEM4.nextSibling; 35var REFA = ITEM5.nextSibling; 36var REFC = REFA.nextSibling; 37var REFE = REFC.nextSibling; 38var NAMESPACE = REFE.nextSibling; 39var ITEM6 = NAMESPACE.firstChild; 40var ITEM7 = ITEM6.nextSibling; 41 42test(doc, ROOT, '//item[@id=last()]', [ITEM5]); 43test(doc, ROOT, '//item[position()=3]', [ITEM3]); 44test(doc, ROOT, 'count(//item)', 5); 45test(doc, ROOT, 'id("c")', [ITEM3]); 46test(doc, ROOT, 'id(//reference)', [ITEM1, ITEM3, ITEM5]); 47// The below test is wrong, it has an invalid expression. 48//test(doc, ROOT, '//reference/id("a")', [ITEM1]); 49// Several tests below originally used predicates with an abbreviated step, which is formally invalid, see <https://bugs.webkit.org/show_bug.cgi?id=12632>. 50test(doc, ROOT, 'local-name(//self::node()[@id=7])', 'item'); 51test(doc, ROOT, 'number(//self::node()[@id=7]/attribute::*[local-name()="value"])', 42); 52test(doc, ROOT, 'local-name(/absent)', ''); 53test(doc, ROOT, 'namespace-uri(//self::node()[@id>5])', 'http://www.example.com/a'); 54test(doc, ROOT, '//self::node()[@id and namespace-uri()="http://www.example.com/b"]', [ITEM7]); 55test(doc, ROOT, 'namespace-uri(/absent)', ''); 56test(doc, ROOT, 'name(//self::node()[@id=7])', 'b:item'); 57test(doc, ROOT, '//self::node()[name()="b:item"]', [ITEM7]); 58test(doc, ROOT, 'name(/absent)', ''); 59 60 61doc = (new DOMParser).parseFromString( 62 '<doc>' + 63 '<para id="1">One</para>' + 64 '<para id="2">Two</para>' + 65 '<para id="3">Three</para>' + 66 '<para id="4">' + 67 'Four' + 68 '</para>' + 69 '</doc>', 70 'application/xml'); 71 72var ROOT = doc.documentElement; 73var PARA1 = ROOT.firstChild; 74var PARA2 = PARA1.nextSibling; 75var PARA3 = PARA2.nextSibling; 76var PARA4 = PARA3.nextSibling; 77 78test(doc, doc, 'string(//para)', 'One'); 79test(doc, doc, 'string(//inconceivable)', ''); 80test(doc, doc, 'string(0 div 0)', 'NaN'); 81test(doc, doc, 'string(1 div 0)', 'Infinity'); 82test(doc, doc, 'string(-1 div 0)', '-Infinity'); 83test(doc, doc, 'string(2.5 * 2)', '5'); 84test(doc, doc, 'string(1 div -2)', '-0.5'); 85test(doc, doc, 'string(1 = 2)', 'false'); 86test(doc, doc, 'string("string")', 'string'); 87test(doc, doc, '//para[string()="Two"]', [PARA2]); 88test(doc, doc, 'concat(//para, ":", //para[2])', 'One:Two'); 89test(doc, doc, 'starts-with("foo-bar", "foo")', true); 90test(doc, doc, 'starts-with("foo-bar", "bar")', false); 91test(doc, doc, 'contains("foo-bar", "o-b")', true); 92test(doc, doc, 'contains("foo-bar", "b-o")', false); 93test(doc, doc, 'substring-before("foo::bar", "::")', 'foo'); 94test(doc, doc, 'substring-before("foo::bar", "--")', ''); 95test(doc, doc, 'substring-after("foo::bar", "::")', 'bar'); 96test(doc, doc, 'substring-after("foo::bar", "--")', ''); 97test(doc, doc, 'substring("12345", 2)', '2345'); 98test(doc, doc, 'substring("12345", 2, 3)', '234'); 99test(doc, doc, 'substring("12345", 1.5, 2.6)', '234'); 100test(doc, doc, 'substring("12345", 0, 3)', '12'); 101test(doc, doc, 'substring("12345", 0 div 0, 3)', ''); 102test(doc, doc, 'substring("12345", 1, 0 div 0)', ''); 103test(doc, doc, 'substring("12345", -42, 1 div 0)', '12345'); 104test(doc, doc, 'substring("12345", -1 div 0, 1 div 0)', ''); 105test(doc, doc, 'substring("12345", 6, 1)', ''); 106test(doc, doc, 'substring("12345", 1, 0)', ''); 107test(doc, doc, 'string-length("12345")', 5); 108test(doc, doc, '//para[string-length()=5]', [PARA3]); 109test(doc, doc, 'normalize-space(" one two ")', 'one two'); 110test(doc, doc, '//para[normalize-space() = "Four"]', [PARA4]); 111test(doc, doc, 'translate("abcdef", "abcde", "xyz")', 'xyzf'); 112 113doc = (new DOMParser).parseFromString( 114 '<doc id="0">' + 115 '<para id="1" />' + 116 '<para id="2" xml:lang="en">' + 117 '<item id="3" />' + 118 'English' + 119 '<section id="4" xml:lang="jp">' + 120 '<item id="5" />' + 121 'Nihongo' + 122 '</section>' + 123 '</para>' + 124 '<para id="6" xml:lang="EN">' + 125 'ENGLISH' + 126 '</para>' + 127 '<para id="7" xml:lang="en-us">' + 128 'US English' + 129 '</para>' + 130 '<para id="8" xml:lang="EN-UK">' + 131 'UK English' + 132 '</para>' + 133 '</doc>', 134 'application/xml'); 135 136var ROOT = doc.documentElement; 137var PARA1 = ROOT.firstChild; 138var PARA2 = PARA1.nextSibling; 139var ITEM3 = PARA2.firstChild; 140var SECTION4 = ITEM3.nextSibling.nextSibling; 141var ITEM5 = SECTION4.firstChild; 142var PARA6 = PARA2.nextSibling; 143var PARA7 = PARA6.nextSibling; 144var PARA8 = PARA7.nextSibling; 145 146test(doc, doc, 'boolean(1)', true); 147test(doc, doc, 'boolean(0)', false); 148test(doc, doc, 'boolean(0 div 0)', false); 149test(doc, doc, 'boolean(cod)', false); 150test(doc, doc, 'boolean(doc)', true); 151test(doc, doc, 'boolean("")', false); 152test(doc, doc, 'boolean("foo")', true); 153test(doc, doc, 'not(1 = 1)', false); 154test(doc, doc, 'true()', true); 155test(doc, doc, 'false()', false); 156test(doc, doc, '//*[lang("en")]', [PARA2, ITEM3, PARA6, PARA7, PARA8]); 157test(doc, doc, '//*[lang("EN-US")]', [PARA7]); 158test(doc, doc, 'normalize-space((//text()[lang("jp")])[normalize-space()])', 'Nihongo'); 159 160doc = (new DOMParser).parseFromString( 161 '<doc>' + 162 '<item>1</item>' + 163 '<item>2</item>' + 164 '<item>3</item>' + 165 '</doc>', 166 'application/xml'); 167 168test(doc, doc, 'string(number("-1e5"))', 'NaN'); // This test originally checked for successful parsing, but -1e5 is not a valid XPath number. 169test(doc, doc, 'number(true())', 1); 170test(doc, doc, 'number(false())', 0); 171test(doc, doc, 'number(//item)', 1); 172test(doc, doc, 'string(//item[number()=4 div 2])', '2'); 173test(doc, doc, 'sum(//item)', 6); 174test(doc, doc, 'floor(1.99)', 1); 175test(doc, doc, 'floor(-1.99)', -2); 176test(doc, doc, 'ceiling(1.99)', 2); 177test(doc, doc, 'ceiling(-1.99)', -1); 178test(doc, doc, 'round(1.5)', 2); 179test(doc, doc, 'round(-1.5)', -1); 180test(doc, doc, 'string(round(0 div 0))', 'NaN'); 181test(doc, doc, 'round(1 div 0)', 1 / 0); 182test(doc, doc, 'round(-1 div 0)', -1 / 0); 183 184// The below tests are added for WebKit to complement the -1e5 test above. 185test(doc, doc, 'number(".1")', 0.1); 186test(doc, doc, 'number("1.")', 1); 187test(doc, doc, 'string(number(".1."))', 'NaN'); 188test(doc, doc, 'string(number("..1"))', 'NaN'); 189test(doc, doc, 'string(number("1.."))', 'NaN'); 190test(doc, doc, 'string(number(".-1"))', 'NaN'); 191 192 193var successfullyParsed = true; 194 195</script> 196<script src="/js/resources/js-test-post.js"></script> 197</body> 198</html> 199