browser/devtools/shared/test/browser_templater_basic.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 // Tests that the DOM Template engine works properly
     6 /*
     7  * These tests run both in Mozilla/Mochitest and plain browsers (as does
     8  * domtemplate)
     9  * We should endevour to keep the source in sync.
    10  */
    12 var promise = Cu.import("resource://gre/modules/devtools/deprecated-sync-thenables.js", {}).Promise;
    13 var template = Cu.import("resource://gre/modules/devtools/Templater.jsm", {}).template;
    15 const TEST_URI = "http://example.com/browser/browser/devtools/shared/test/browser_templater_basic.html";
    17 function test() {
    18   addTab(TEST_URI, function() {
    19     info("Starting DOM Templater Tests");
    20     runTest(0);
    21   });
    22 }
    24 function runTest(index) {
    25   var options = tests[index] = tests[index]();
    26   var holder = content.document.createElement('div');
    27   holder.id = options.name;
    28   var body = content.document.body;
    29   body.appendChild(holder);
    30   holder.innerHTML = options.template;
    32   info('Running ' + options.name);
    33   template(holder, options.data, options.options);
    35   if (typeof options.result == 'string') {
    36     is(holder.innerHTML, options.result, options.name);
    37   }
    38   else {
    39     ok(holder.innerHTML.match(options.result) != null,
    40        options.name + ' result=\'' + holder.innerHTML + '\'');
    41   }
    43   if (options.also) {
    44     options.also(options);
    45   }
    47   function runNextTest() {
    48     index++;
    49     if (index < tests.length) {
    50       runTest(index);
    51     }
    52     else {
    53       finished();
    54     }
    55   }
    57   if (options.later) {
    58     var ais = is.bind(this);
    60     function createTester(holder, options) {
    61       return function() {
    62         ais(holder.innerHTML, options.later, options.name + ' later');
    63         runNextTest();
    64       }.bind(this);
    65     }
    67     executeSoon(createTester(holder, options));
    68   }
    69   else {
    70     runNextTest();
    71   }
    72 }
    74 function finished() {
    75   gBrowser.removeCurrentTab();
    76   info("Finishing DOM Templater Tests");
    77   tests = null;
    78   finish();
    79 }
    81 /**
    82  * Why have an array of functions that return data rather than just an array
    83  * of the data itself? Some of these tests contain calls to delayReply() which
    84  * sets up async processing using executeSoon(). Since the execution of these
    85  * tests is asynchronous, the delayed reply will probably arrive before the
    86  * test is executed, making the test be synchronous. So we wrap the data in a
    87  * function so we only set it up just before we use it.
    88  */
    89 var tests = [
    90   function() { return {
    91     name: 'simpleNesting',
    92     template: '<div id="ex1">${nested.value}</div>',
    93     data: { nested:{ value:'pass 1' } },
    94     result: '<div id="ex1">pass 1</div>'
    95   };},
    97   function() { return {
    98     name: 'returnDom',
    99     template: '<div id="ex2">${__element.ownerDocument.createTextNode(\'pass 2\')}</div>',
   100     options: { allowEval: true },
   101     data: {},
   102     result: '<div id="ex2">pass 2</div>'
   103   };},
   105   function() { return {
   106     name: 'srcChange',
   107     template: '<img _src="${fred}" id="ex3">',
   108     data: { fred:'green.png' },
   109     result: /<img( id="ex3")? src="green.png"( id="ex3")?>/
   110   };},
   112   function() { return {
   113     name: 'ifTrue',
   114     template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
   115     options: { allowEval: true },
   116     data: { name: 'fred' },
   117     result: '<p>hello fred</p>'
   118   };},
   120   function() { return {
   121     name: 'ifFalse',
   122     template: '<p if="${name !== \'jim\'}">hello ${name}</p>',
   123     options: { allowEval: true },
   124     data: { name: 'jim' },
   125     result: ''
   126   };},
   128   function() { return {
   129     name: 'simpleLoop',
   130     template: '<p foreach="index in ${[ 1, 2, 3 ]}">${index}</p>',
   131     options: { allowEval: true },
   132     data: {},
   133     result: '<p>1</p><p>2</p><p>3</p>'
   134   };},
   136   function() { return {
   137     name: 'loopElement',
   138     template: '<loop foreach="i in ${array}">${i}</loop>',
   139     data: { array: [ 1, 2, 3 ] },
   140     result: '123'
   141   };},
   143   // Bug 692028: DOMTemplate memory leak with asynchronous arrays
   144   // Bug 692031: DOMTemplate async loops do not drop the loop element
   145   function() { return {
   146     name: 'asyncLoopElement',
   147     template: '<loop foreach="i in ${array}">${i}</loop>',
   148     data: { array: delayReply([1, 2, 3]) },
   149     result: '<span></span>',
   150     later: '123'
   151   };},
   153   function() { return {
   154     name: 'saveElement',
   155     template: '<p save="${element}">${name}</p>',
   156     data: { name: 'pass 8' },
   157     result: '<p>pass 8</p>',
   158     also: function(options) {
   159       ok(options.data.element.innerHTML, 'pass 9', 'saveElement saved');
   160       delete options.data.element;
   161     }
   162   };},
   164   function() { return {
   165     name: 'useElement',
   166     template: '<p id="pass9">${adjust(__element)}</p>',
   167     options: { allowEval: true },
   168     data: {
   169       adjust: function(element) {
   170         is('pass9', element.id, 'useElement adjust');
   171         return 'pass 9b'
   172       }
   173     },
   174     result: '<p id="pass9">pass 9b</p>'
   175   };},
   177   function() { return {
   178     name: 'asyncInline',
   179     template: '${delayed}',
   180     data: { delayed: delayReply('inline') },
   181     result: '<span></span>',
   182     later: 'inline'
   183   };},
   185   // Bug 692028: DOMTemplate memory leak with asynchronous arrays
   186   function() { return {
   187     name: 'asyncArray',
   188     template: '<p foreach="i in ${delayed}">${i}</p>',
   189     data: { delayed: delayReply([1, 2, 3]) },
   190     result: '<span></span>',
   191     later: '<p>1</p><p>2</p><p>3</p>'
   192   };},
   194   function() { return {
   195     name: 'asyncMember',
   196     template: '<p foreach="i in ${delayed}">${i}</p>',
   197     data: { delayed: [delayReply(4), delayReply(5), delayReply(6)] },
   198     result: '<span></span><span></span><span></span>',
   199     later: '<p>4</p><p>5</p><p>6</p>'
   200   };},
   202   // Bug 692028: DOMTemplate memory leak with asynchronous arrays
   203   function() { return {
   204     name: 'asyncBoth',
   205     template: '<p foreach="i in ${delayed}">${i}</p>',
   206     data: {
   207       delayed: delayReply([
   208         delayReply(4),
   209         delayReply(5),
   210         delayReply(6)
   211       ])
   212     },
   213     result: '<span></span>',
   214     later: '<p>4</p><p>5</p><p>6</p>'
   215   };},
   217   // Bug 701762: DOMTemplate fails when ${foo()} returns undefined
   218   function() { return {
   219     name: 'functionReturningUndefiend',
   220     template: '<p>${foo()}</p>',
   221     options: { allowEval: true },
   222     data: {
   223       foo: function() {}
   224     },
   225     result: '<p>undefined</p>'
   226   };},
   228   // Bug 702642: DOMTemplate is relatively slow when evaluating JS ${}
   229   function() { return {
   230     name: 'propertySimple',
   231     template: '<p>${a.b.c}</p>',
   232     data: { a: { b: { c: 'hello' } } },
   233     result: '<p>hello</p>'
   234   };},
   236   function() { return {
   237     name: 'propertyPass',
   238     template: '<p>${Math.max(1, 2)}</p>',
   239     options: { allowEval: true },
   240     result: '<p>2</p>'
   241   };},
   243   function() { return {
   244     name: 'propertyFail',
   245     template: '<p>${Math.max(1, 2)}</p>',
   246     result: '<p>${Math.max(1, 2)}</p>'
   247   };},
   249   // Bug 723431: DOMTemplate should allow customisation of display of
   250   // null/undefined values
   251   function() { return {
   252     name: 'propertyUndefAttrFull',
   253     template: '<p>${nullvar}|${undefinedvar1}|${undefinedvar2}</p>',
   254     data: { nullvar: null, undefinedvar1: undefined },
   255     result: '<p>null|undefined|undefined</p>'
   256   };},
   258   function() { return {
   259     name: 'propertyUndefAttrBlank',
   260     template: '<p>${nullvar}|${undefinedvar1}|${undefinedvar2}</p>',
   261     data: { nullvar: null, undefinedvar1: undefined },
   262     options: { blankNullUndefined: true },
   263     result: '<p>||</p>'
   264   };},
   266   function() { return {
   267     name: 'propertyUndefAttrFull',
   268     template: '<div><p value="${nullvar}"></p><p value="${undefinedvar1}"></p><p value="${undefinedvar2}"></p></div>',
   269     data: { nullvar: null, undefinedvar1: undefined },
   270     result: '<div><p value="null"></p><p value="undefined"></p><p value="undefined"></p></div>'
   271   };},
   273   function() { return {
   274     name: 'propertyUndefAttrBlank',
   275     template: '<div><p value="${nullvar}"></p><p value="${undefinedvar1}"></p><p value="${undefinedvar2}"></p></div>',
   276     data: { nullvar: null, undefinedvar1: undefined },
   277     options: { blankNullUndefined: true },
   278     result: '<div><p value=""></p><p value=""></p><p value=""></p></div>'
   279   };}
   280 ];
   282 function delayReply(data) {
   283   var d = promise.defer();
   284   executeSoon(function() {
   285     d.resolve(data);
   286   });
   287   return d.promise;
   288 }

mercurial