root/lang/javascript/javascript-xpath/trunk/test/functional/index.html @ 1530

Revision 1530, 18.0 kB (checked in by gyuque, 6 years ago)

lang/javascript/javascript-xpath/trunk/test/functional: refactored logger and counter

  • Property svn:mime-type set to text/html
Line 
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <head>
5  <title>XPath Functional Test</title>
6  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7  <meta http-equiv="Content-Style-Type" content="text/css" />
8  <meta http-equiv="Content-Script-Type" content="text/javascript" />
9
10  <script type="text/javascript" src="./logger.js"></script>
11
12  <script type="text/javascript" src="../../src/config.js"></script>
13  <script type="text/javascript" src="../../src/uai.js"></script>
14  <script type="text/javascript" src="../../src/lexer.js"></script>
15  <script type="text/javascript" src="../../src/ctx.js"></script>
16  <script type="text/javascript" src="../../src/baseExpr.js"></script>
17  <script type="text/javascript" src="../../src/binaryExpr.js"></script>
18  <script type="text/javascript" src="../../src/unaryExpr.js"></script>
19  <script type="text/javascript" src="../../src/unionExpr.js"></script>
20  <script type="text/javascript" src="../../src/pathExpr.js"></script>
21  <script type="text/javascript" src="../../src/filterExpr.js"></script>
22  <script type="text/javascript" src="../../src/stepExpr.js"></script>
23  <script type="text/javascript" src="../../src/nodeType.js"></script>
24  <script type="text/javascript" src="../../src/nameTest.js"></script>
25  <script type="text/javascript" src="../../src/variableReference.js"></script>
26  <script type="text/javascript" src="../../src/literal.js"></script>
27  <script type="text/javascript" src="../../src/number.js"></script>
28  <script type="text/javascript" src="../../src/functionCall.js"></script>
29  <script type="text/javascript" src="../../src/nodeSet.js"></script>
30  <script type="text/javascript" src="../../src/api.js"></script>
31  <style type="text/css">
32body {
33    font-family: monospace;
34}
35iframe {
36    width: 1px;
37    height: 1px;
38    visibility: hidden;
39}
40table {
41    border-collapse: collapse;
42    margin: 0;
43    padding: 0;
44    width: 100%;
45}
46td, th {
47    border: 3px solid white;
48    font-weight: bold;
49    margin: 0;
50    padding: 5px 8px;
51    color: #61666D;
52}
53td a {
54    color: #6166AA;
55}
56td {
57    font-size: 11px;
58    background: #C8CBD0;
59}
60th {
61    font-size: 12px;
62    background: #BBBBBB;
63}
64td a {
65   
66}
67
68td.error,
69td.ng{
70    background: #F36F6F;
71    color: #F3F1F1;
72}
73td.ok {
74    background: #AAF3AA;
75}
76
77td.heavy {
78    background: #F3E3AA;
79}
80
81span#counter {
82    font-size: 70%;
83}
84
85span#counter .counter-ok {
86    color: green;
87}
88
89span#counter .counter-ng {
90    color: red;
91}
92
93span.local-counter {
94    font-size: 80%;
95}
96
97span.local-counter .local-counter-ok {
98    color: green;
99}
100
101span.local-counter .local-counter-ng {
102    color: red;
103}
104
105h2 {
106    margin-top: 2em;
107    margin-bottom: 0.2em;
108}
109
110pre {
111    font-size: 80%;
112    padding: 1em;
113    line-height: 1.5;
114    color: #444;
115    border: 2px solid #AAA;
116}
117  </style>
118 </head>
119 <body>
120  <h1><a href="?">XPath Functional Test</a> <span id="counter"><span class="counter-ok">0</span> / <span>0</span></span></h1>
121  <div id="testLog"></div>
122  <iframe id="testFrame"></iframe>
123  <script type="text/javascript">
124// <![CDATA[
125
126var testFrame = document.getElementById('testFrame');
127var testLog = document.getElementById('testLog');
128
129
130{
131    var ct_elem = document.getElementById('counter');
132    Logger.globalCounter = new Counter(ct_elem.firstChild, ct_elem.lastChild, 'counter-ng');
133}
134
135function getTestData(id) {
136    var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest : new ActiveXObject('Msxml2.XMLHTTP');
137    var status, responseText;
138    try {
139        xhr.open('GET', 'data/' + id + '?' + Math.random(), false);
140        xhr.send(null);
141        status = xhr.status;
142        if (status == 0) {
143            status = 200;
144        }
145        responseText = xhr.responseText;
146        if (!responseText) {
147            status = 404;
148        }
149    }
150    catch(e) {
151        status = 404;
152    }
153    if (status == 200) {
154        return responseText;
155    }
156    else {
157        return undefined;
158    }
159}
160
161function loadFrame(html) {
162    var win = testFrame.contentWindow;
163    var doc = win.document;
164    doc.open();
165    doc.write(html);
166    doc.close();
167    install(win);
168    var html = doc.documentElement;
169    var attrs = html.attributes;
170    var t = '';
171    for (var i = 0, l = attrs.length; i < l; i ++) {
172        var attr = attrs[i];
173        t += (attr.prefix ? attr.prefix + ':' : '') + ' ' + attr.name + '=' + attr.value;
174    }
175//    return html.outerHTML || '<' + (html.prefix ? html.prefix + ':' : '') + html.nodeName + t + '>' + html.innerHTML + '</' + (html.prefix ? html.prefix + ':' : '') + html.nodeName + '>';
176}
177
178function applyXPath(context, expr) {
179    var doc = testFrame.contentWindow.document;
180    var expr = doc.createExpression(expr, null);
181    var start_t = new Date;
182    var result = expr.evaluate(context, 0, null);
183    var time = new Date - start_t;
184    if (result.resultType > 3) {
185        result = expr.evaluate(context, 7, null);
186        var array = [];
187        for (var i = 0, length = result.snapshotLength; i < length; i ++) {
188            array[i] = result.snapshotItem(i);
189        }
190        return [array, time];
191    }
192    else {
193        if (result.resultType == 1) {
194            return [result.numberValue, time];
195        }
196        if (result.resultType == 2) {
197            return [result.stringValue, time];
198        }
199        if (result.resultType == 3) {
200            return [result.booleanValue, time];
201        }
202    }
203}
204
205function parseTestData(data) {
206    if (data == undefined) {
207        return undefined;
208    }
209    var dataSplited = data.split(/\n--------\n/);
210
211    var comment = dataSplited[0];
212    var html = dataSplited[1];
213    var contextExpr = dataSplited[2];
214    var testData = dataSplited[3];
215
216    var testDataSplited = testData.split(/\n/);
217    var tests = [];
218    for (var i = 0, length = testDataSplited.length; i < length; i ++) {
219        if (testDataSplited[i].match(/^\s*#/)) continue; // comment
220        var m = testDataSplited[i].match(/^\s*(.*?)\s*=>\s*(.*?)?\s*$/);
221        if (m) {
222            tests.push({ expr: m[1], data: m[2] });
223        }
224    }
225    return {comment: comment, html: html, contextExpr: contextExpr, tests: tests};
226}
227
228function NodeTest(data) {
229    this.nodes = [];
230    data = data || '';
231    if (data.match(/^\s*\(none\)\s*$/)) return;
232    var tokens = data.match(/([\w-]+\(.*?\)|\w+(\.[\w-]+|#[\w-]+|\[[\w-]+=("[^"]*"|'[^']*')\])*)(:\w+)*/g);
233    tokens = tokens || [];
234    for (var i = 0, l = tokens.length; i < l; i ++) {
235        var token = tokens[i];
236        var m = token.match(/([\w-]+)\(((([\w-]+)=)?("[^"]*"|'[^']*'|-?\d+|NaN|-?Infinity|true|false)?)\)((:\w+)*)/);
237        var uas, nodeData, nodeType, nodeName, nodeValue;
238        uas = nodeData = nodeType = nodeName = nodeValue = null;
239        if (m) {
240            nodeType = this.typeMap[m[1]];
241            switch (nodeType) {
242                case 0:
243                    nodeName = '#value';
244                    nodeValue = m[2];
245                    break;
246                case 2: case 7:
247                    nodeName = m[4];
248                    nodeValue = m[5];
249                    break;
250                case 3:
251                    nodeName = '#text';
252                    nodeValue = m[2];
253                    break;
254                case 4:
255                    nodeName = '#cdata-section';
256                    nodeValue = m[2];
257                    break;
258                case 8:
259                    nodeName = '#comment';
260                    nodeValue = m[2];
261                    break;
262                case 9:
263                    nodeName = '#document';
264                    nodeValue = null;
265                    break;
266                default:
267                    nodeValue = m[2];
268                    break;
269            }
270            if (nodeValue && nodeType != 0) {
271                var first = nodeValue.charAt(0);
272                var last = nodeValue.charAt(nodeValue.length - 1);
273                if (last == first && (first == '"' || first == "'")) {
274                    nodeValue = eval(nodeValue);
275                }
276            }
277            uas = m[6].split(':');
278        }
279        else {
280            m = token.match(/((\w+)((\.[\w-]+|#[\w-]+|\[[\w-]+=("[^"]*"|'[^']*')\])*))((:\w+)*)/);
281
282            nodeType = 1;
283            nodeName = m[2]
284            var nodeDatas = m[3];
285            nodeDatas = nodeDatas.match(/\.[\w-]+|#[\w-]+|\[[\w-]+=("[^"]*"|'[^']*')\]/g);
286            if (nodeDatas) {
287                nodeData = [];
288                for (var j = 0; j < nodeDatas.length; j ++) {
289                    var data = nodeDatas[j];
290                    switch (data.charAt(0)) {
291                        case '.':
292                            data = {
293                                type: 'class',
294                                name: data.substring(1),
295                                match: function(node) {
296                                    var classes = node.className.split(/\s+/);
297                                    for (var i = 0; i < classes.length; i ++) {
298                                        if (classes[i] == this.name) {
299                                            return true;
300                                        }
301                                    }
302                                    return false;
303                                }
304                            };
305                            nodeData.push(data);
306                            break;
307                        case '#':
308                            data = {
309                                type: 'id',
310                                name: data.substring(1),
311                                match: function(node) {
312                                    return node.id == this.name;
313                                }
314                            };
315                            nodeData.push(data);
316                            break;
317                        case '[':
318                            data = data.substring(1, data.length - 1);
319                            data = data.split(/=/);
320                            data = {
321                                type: 'attr',
322                                name: data[0],
323                                value: eval(data[1]), // quot
324                                match: function(node) {
325                                    return node.getAttribute(this.name) == this.value;
326                                }
327                            };
328                            nodeData.push(data);
329                            break;
330                        default:
331                    }
332                }
333            }
334            else {
335            }
336            uas = m[6].split(':');
337        }
338        for (var j = 0, l0 = uas.length; j < l0; j++) {
339            if (!uas[j]) {
340                uas.splice(j, 1);
341            }
342        }
343
344        function createNodeInfo(nodeType, nodeName, nodeValue, nodeData) {
345            return {
346                nodeType: nodeType,
347                nodeName: nodeName,
348                nodeValue: nodeValue,
349                nodeData: nodeData,
350                match: function(node) {
351                    if (node.nodeType != this.nodeType) return false;
352                    if (node.nodeName.toLowerCase() != this.nodeName.toLowerCase()) return false;
353                    if (node.nodeValue != this.nodeValue) return false;
354                    if (node.nodeData) {
355                        for (var i = 0; i < this.nodeData.length; i ++) {
356                            if (!this.nodeData[i].match(node)) return false;
357                        }
358                    }
359                    return true;
360                }
361            }
362        }
363
364        if (uas.length) {
365            for (var j = 0, l0 = uas.length; j < l0; j++) {
366                if (uai[uas[j]]) {
367                    this.nodes.push(createNodeInfo(nodeType, nodeName, nodeValue, nodeData));
368                    break;
369                }
370            }
371        }
372        else {
373            this.nodes.push(createNodeInfo(nodeType, nodeName, nodeValue, nodeData));
374        }
375    }
376    if (this.nodes.length == 1 && this.nodes[0].nodeType == 0) {
377        this.primitive = true;
378        this.value = eval(this.nodes[0].nodeValue);
379    }
380}
381
382NodeTest.prototype.typeMap = {
383    value: 0,
384    element: 1,
385    attribute: 2,
386    text: 3,
387    'cdata-section': 4,
388    'entity-reference': 5,
389    entity: 6,
390    'processing-instruction': 7,
391    comment: 8,
392    document: 9,
393    'document-type': 10,
394    'document-fragment': 11,
395    notation: 12
396}
397
398NodeTest.prototype.test = function(nodes) {
399    if (nodes.length != this.nodes.length) {
400//        console.log(nodes.length, this.nodes.length)
401        return false;
402    }
403    for (var i = 0; i < nodes.length; i ++) {
404        if (!this.nodes[i].match(nodes[i])) {
405/*
406            alert(i);
407            alert(nodes[i].nodeValue == this.nodes[i].nodeValue);
408            if (nodes[i].nodeValue)
409                alert(nodes[i].nodeValue.replace(/ /g, 's').replace(/\n/g, 'n'));
410            if (this.nodes[i].nodeValue)
411                alert(this.nodes[i].nodeValue.replace(/ /g, 's').replace(/\n/g, 'n'));
412           
413            console.log(nodes[i], this.nodes[i]);
414*/
415            return false;
416        }
417    }
418    return true;
419}
420
421function testNodes(nodes, data) {
422    var tester = new NodeTest(data);
423    if (tester.primitive) {
424        if (tester.value == nodes) {
425            return { status: 'ok', detail: 'ok' };
426        }
427        else {
428            if (typeof tester.value != 'string') {
429                return { status: 'ng', detail: 'value(' + nodes + ')' }
430            }
431            else {
432                return { status: 'ng', detail: 'value("' + nodes.replace(/\\/, '\\\\').replace(/"/, '\\"') + '")' }
433            }
434        }
435    }
436    if (tester.test(nodes)) {
437        return { status: 'ok', detail: 'ok' };
438    }
439    var detail = [];
440    for (var i = 0; i < nodes.length; i ++) {
441        var t = '';
442        var node = nodes[i]
443        switch (node.nodeType) {
444            case 1:
445                t += node.nodeName.toLowerCase();
446                if (node.id) {
447                    t += '#' + node.id;
448                }
449                if (node.className) {
450                    var classes = node.className.split(/\s+/);
451                    t += '.' + classes.join('.');
452                }
453
454                /*
455                var attrs = node.attributes;
456                for (var j = 0; j < attrs.length; j ++) {
457                    if (attrs[j].nodeName == 'class' || attrs[j].nodeName == 'id') {
458                        continue;
459                    }
460                    if (attrs[j].nodeValue) {
461                        t += '[' + attrs[j].nodeName + '="' + attrs[j].nodeValue.replace(/\\/, '\\\\').replace(/"/, '\\"') + '"]';
462                    }
463                }
464                */
465                break;
466            case 3:
467                t += 'text("' + node.nodeValue.replace(/\\/, '\\\\').replace(/"/, '\\"') + '")';
468                break;
469            case 7:
470                t += 'processing-instruction(' + node.nodeName + '="' + node.nodeValue.replace(/\\/, '\\\\').replace(/"/, '\\"') + '")';
471                break;
472            case 8:
473                t += 'comment("' + node.nodeValue.replace(/\\/, '\\\\').replace(/"/, '\\"') + '")';
474                break;
475            case 9:
476                t += 'document()';
477                break;
478            default:
479                t += 'unknown';
480                break;
481        }
482        detail.push(t);
483    }
484    return { status: 'ng', detail: detail.join(' ') };
485}
486
487var search = document.location.search;
488if (search) {
489    var splited = search.replace(/^\?/, '').split(/-/);
490    if (splited[0]) {
491        var reservedTestIndex = parseInt(splited[0].replace(/^0*/, '') || 0);
492    }
493    if (splited[1]) {
494        var reservedCaseIndex = parseInt(splited[1].replace(/^0*/, ''));
495    }
496}
497
498window._setTimeout = window.setTimeout;
499
500window.setTimeout = function() {
501    var f = arguments[0];
502    var t = arguments[1];
503    var args = [];
504    for (var i = 2, l = arguments.length; i < l; i ++) args.push(arguments[i]);
505    _setTimeout(function() { return f.apply(this, args) }, t);
506};
507
508var testIndex = (reservedTestIndex || 0);
509var prevLogger = null;
510
511var prevId = null;
512function f () {
513    var doc = testFrame.contentWindow.document;
514    var id = testIndex ++;
515    id = (10000 + id + '').substring(1)
516    var data = parseTestData(getTestData(id));
517    if (!data) return;
518
519    loadFrame(data.html);
520    var context = doc.evaluate(data.contextExpr, doc, null, 7, null).snapshotItem(0);
521    var tests = data.tests;
522    var logger = new Logger(data.comment, data.html, id, prevId);
523    prevId = id;
524    if (prevLogger) prevLogger.next(id);
525    prevLogger = logger;
526    var i = (reservedCaseIndex || 0), length = tests.length;;
527
528    function g(fin) {
529        if (!(i < length)) return fin();
530        var test = tests[i];
531        var expr = test.expr;
532        try {
533            var nodesAndTime = applyXPath(context, expr);
534            var result = testNodes(nodesAndTime[0], test.data);
535            var t = nodesAndTime[1];
536            var ok = result.detail == 'ok';
537
538            var anchor = document.createElement('a');
539            anchor.href = '?' + id + '-' + (10000 + logger.localCounter.countAll + '').substring(1);
540            anchor.appendChild(document.createTextNode('only this case'));
541
542            logger.log([
543                expr,
544                test.data,
545                {
546                    label: result.detail,
547                    className: result.status
548                },
549                {
550                    label: t,
551                    className: (t>50) ? 'heavy': null
552                },
553                                {
554                                        richLabel: anchor
555                                }
556            ]);
557                        logger.localCounter.inc(ok);
558                        Logger.globalCounter.inc(ok);
559        }
560        catch (e) {
561            logger.log([expr, test.data, e.message, 'error']);
562                        logger.localCounter.inc(false);
563                        Logger.globalCounter.inc(false);
564//          alert(e);
565        }
566        i ++;
567        if (reservedCaseIndex == undefined) {
568            setTimeout(g, 10, fin);
569        }
570    }
571
572    setTimeout(g , 10, function() {
573        if (reservedTestIndex == undefined) {
574            setTimeout(f, 10);
575        }
576    });
577}
578
579setTimeout(f, 10);
580
581// ]]>
582  </script>
583 </body>
584</html>
585
Note: See TracBrowser for help on using the browser.