Home | History | Annotate | Download | only in Array
      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* ***** BEGIN LICENSE BLOCK *****
      3  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
      4  *
      5  * The contents of this file are subject to the Mozilla Public License Version
      6  * 1.1 (the "License"); you may not use this file except in compliance with
      7  * the License. You may obtain a copy of the License at
      8  * http://www.mozilla.org/MPL/
      9  *
     10  * Software distributed under the License is distributed on an "AS IS" basis,
     11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
     12  * for the specific language governing rights and limitations under the
     13  * License.
     14  *
     15  * The Original Code is JavaScript Engine testing utilities.
     16  *
     17  * The Initial Developer of the Original Code is
     18  * Mozilla Foundation.
     19  * Portions created by the Initial Developer are Copyright (C) 2005
     20  * the Initial Developer. All Rights Reserved.
     21  *
     22  * Contributor(s): Mike Shaver
     23  *                 Bob Clary
     24  *
     25  * Alternatively, the contents of this file may be used under the terms of
     26  * either the GNU General Public License Version 2 or later (the "GPL"), or
     27  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
     28  * in which case the provisions of the GPL or the LGPL are applicable instead
     29  * of those above. If you wish to allow use of your version of this file only
     30  * under the terms of either the GPL or the LGPL, and not to allow others to
     31  * use your version of this file under the terms of the MPL, indicate your
     32  * decision by deleting the provisions above and replace them with the notice
     33  * and other provisions required by the GPL or the LGPL. If you do not delete
     34  * the provisions above, a recipient may use your version of this file under
     35  * the terms of any one of the MPL, the GPL or the LGPL.
     36  *
     37  * ***** END LICENSE BLOCK ***** */
     38 //-----------------------------------------------------------------------------
     39 var bug = 290592;
     40 var summary = 'Array extras: forEach, indexOf, filter, map';
     41 var actual = '';
     42 var expect = '';
     43 
     44 printBugNumber (bug);
     45 printStatus (summary);
     46 
     47 // Utility functions
     48 
     49 function identity(v, index, array)
     50 {
     51   reportCompare(v, array[index], 'identity: check callback argument consistency');
     52   return v;
     53 }
     54 
     55 function mutate(v, index, array)
     56 {
     57   reportCompare(v, array[index], 'mutate: check callback argument consistency');
     58   if (index == 0)
     59   {
     60     array[1] = 'mutated';
     61     delete array[2];
     62     array.push('not visited');
     63   }
     64   return v;
     65 }
     66 
     67 function mutateForEach(v, index, array)
     68 {
     69   reportCompare(v, array[index], 'mutateForEach: check callback argument consistency');
     70   if (index == 0)
     71   {
     72     array[1] = 'mutated';
     73     delete array[2];
     74     array.push('not visited');
     75   }
     76   actual += v + ',';
     77 }
     78 
     79 function makeUpperCase(v, index, array)
     80 {
     81   reportCompare(v, array[index], 'makeUpperCase: check callback argument consistency');
     82   try
     83   {
     84     return v.toUpperCase();
     85   }
     86   catch(e)
     87   {
     88   }
     89   return v;
     90 }
     91 
     92 
     93 function concat(v, index, array)
     94 {
     95   reportCompare(v, array[index], 'concat: check callback argument consistency');
     96   actual += v + ',';
     97 }
     98 
     99 
    100 function isUpperCase(v, index, array)
    101 {
    102   reportCompare(v, array[index], 'isUpperCase: check callback argument consistency');
    103   try
    104   {
    105     return v == v.toUpperCase();
    106   }
    107   catch(e)
    108   {
    109   }
    110   return false;
    111 }
    112 
    113 function isString(v, index, array)
    114 {
    115   reportCompare(v, array[index], 'isString: check callback argument consistency');
    116   return typeof v == 'string';
    117 }
    118 
    119 
    120 // callback object.
    121 function ArrayCallback(state)
    122 {
    123   this.state = state;
    124 }
    125 
    126 ArrayCallback.prototype.makeUpperCase = function (v, index, array)
    127 {
    128   reportCompare(v, array[index], 'ArrayCallback.prototype.makeUpperCase: check callback argument consistency');
    129   try
    130   {
    131     return this.state ? v.toUpperCase() : v.toLowerCase();
    132   }
    133   catch(e)
    134   {
    135   }
    136   return v;
    137 };
    138 
    139 ArrayCallback.prototype.concat = function(v, index, array)
    140 {
    141   reportCompare(v, array[index], 'ArrayCallback.prototype.concat: check callback argument consistency');
    142   actual += v + ',';
    143 };
    144 
    145 ArrayCallback.prototype.isUpperCase = function(v, index, array)
    146 {
    147   reportCompare(v, array[index], 'ArrayCallback.prototype.isUpperCase: check callback argument consistency');
    148   try
    149   {
    150     return this.state ? true : (v == v.toUpperCase());
    151   }
    152   catch(e)
    153   {
    154   }
    155   return false;
    156 };
    157 
    158 ArrayCallback.prototype.isString = function(v, index, array)
    159 {
    160   reportCompare(v, array[index], 'ArrayCallback.prototype.isString: check callback argument consistency');
    161   return this.state ? true : (typeof v == 'string');
    162 };
    163 
    164 function dumpError(e)
    165 {
    166   var s = e.name + ': ' + e.message +
    167     ' File: ' + e.fileName +
    168     ', Line: ' + e.lineNumber +
    169     ', Stack: ' + e.stack;
    170   return s;
    171 }
    172 
    173 var obj;
    174 var strings = ['hello', 'Array', 'WORLD'];
    175 var mixed   = [0, '0', 0];
    176 var sparsestrings = new Array();
    177 sparsestrings[2] = 'sparse';
    178 
    179 if ('map' in Array.prototype)
    180 {
    181 // see http://developer-test.mozilla.org/docs/Core_JavaScript_1.5_Reference:Objects:Array:map
    182 
    183   // test Array.map
    184 
    185   // map has 1 required argument
    186   expect = 1;
    187   actual = Array.prototype.map.length;
    188   reportCompare(expect, actual, 'Array.prototype.map.length == 1');
    189 
    190   // throw TypeError if no callback function specified
    191   expect = 'TypeError';
    192   try
    193   {
    194     strings.map();
    195     actual = 'no error';
    196   }
    197   catch(e)
    198   {
    199     actual = e.name;
    200   }
    201   reportCompare(expect, actual, 'Array.map(undefined) throws TypeError');
    202 
    203   try
    204   {
    205     // identity map
    206     expect = 'hello,Array,WORLD';
    207     actual = strings.map(identity).toString();
    208   }
    209   catch(e)
    210   {
    211     actual = dumpError(e);
    212   }
    213   reportCompare(expect, actual, 'Array.map: identity');
    214 
    215 
    216   try
    217   {
    218     expect = 'hello,mutated,';
    219     actual = strings.map(mutate).toString();
    220   }
    221   catch(e)
    222   {
    223     actual = dumpError(e);
    224   }
    225   reportCompare(expect, actual, 'Array.map: mutate');
    226 
    227   strings = ['hello', 'Array', 'WORLD'];
    228 
    229   try
    230   {
    231     // general map
    232     expect = 'HELLO,ARRAY,WORLD';
    233     actual = strings.map(makeUpperCase).toString();
    234   }
    235   catch(e)
    236   {
    237     actual = dumpError(e);
    238   }
    239   reportCompare(expect, actual, 'Array.map: uppercase');
    240 
    241   try
    242   {
    243     // pass object method as map callback
    244     expect = 'HELLO,ARRAY,WORLD';
    245     var obj = new ArrayCallback(true);
    246     actual  = strings.map(obj.makeUpperCase, obj).toString();
    247   }
    248   catch(e)
    249   {
    250     actual = dumpError(e);
    251   }
    252   reportCompare(expect, actual, 'Array.map: uppercase with object callback');
    253 
    254   try
    255   {
    256     expect = 'hello,array,world';
    257     obj = new ArrayCallback(false);
    258     actual = strings.map(obj.makeUpperCase, obj).toString();
    259   }
    260   catch(e)
    261   {
    262     actual = dumpError(e);
    263   }
    264   reportCompare(expect, actual, 'Array.map: lowercase with object callback');
    265 
    266   try
    267   {
    268     // map on sparse arrays
    269     expect = ',,SPARSE';
    270     actual = sparsestrings.map(makeUpperCase).toString();
    271   }
    272   catch(e)
    273   {
    274     actual = dumpError(e);
    275   }
    276   reportCompare(expect, actual, 'Array.map: uppercase on sparse array');
    277 }
    278 
    279 if ('forEach' in Array.prototype)
    280 {
    281 // see http://developer-test.mozilla.org/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach
    282 
    283   // test Array.forEach
    284 
    285   // forEach has 1 required argument
    286   expect = 1;
    287   actual = Array.prototype.forEach.length;
    288   reportCompare(expect, actual, 'Array.prototype.forEach.length == 1');
    289 
    290   // throw TypeError if no callback function specified
    291   expect = 'TypeError';
    292   try
    293   {
    294     strings.forEach();
    295     actual = 'no error';
    296   }
    297   catch(e)
    298   {
    299     actual = e.name;
    300   }
    301   reportCompare(expect, actual, 'Array.forEach(undefined) throws TypeError');
    302 
    303   try
    304   {
    305     // general forEach
    306     expect = 'hello,Array,WORLD,';
    307     actual = '';
    308     strings.forEach(concat);
    309   }
    310   catch(e)
    311   {
    312     actual = dumpError(e);
    313   }
    314   reportCompare(expect, actual, 'Array.forEach');
    315 
    316   try
    317   {
    318     expect = 'hello,mutated,';
    319     actual = '';
    320     strings.forEach(mutateForEach);
    321   }
    322   catch(e)
    323   {
    324     actual = dumpError(e);
    325   }
    326   reportCompare(expect, actual, 'Array.forEach: mutate');
    327 
    328   strings = ['hello', 'Array', 'WORLD'];
    329 
    330 
    331 
    332   try
    333   {
    334     // pass object method as forEach callback
    335     expect = 'hello,Array,WORLD,';
    336     actual = '';
    337     obj = new ArrayCallback(true);
    338     strings.forEach(obj.concat, obj);
    339   }
    340   catch(e)
    341   {
    342     actual = dumpError(e);
    343   }
    344   reportCompare(expect, actual, 'Array.forEach with object callback 1');
    345 
    346   try
    347   {
    348     expect = 'hello,Array,WORLD,';
    349     actual = '';
    350     obj = new ArrayCallback(false);
    351     strings.forEach(obj.concat, obj);
    352   }
    353   catch(e)
    354   {
    355     actual = dumpError(e);
    356   }
    357   reportCompare(expect, actual, 'Array.forEach with object callback 2');
    358 
    359   try
    360   {
    361     // test forEach on sparse arrays
    362     // see https://bugzilla.mozilla.org/show_bug.cgi?id=311082
    363     expect = 'sparse,';
    364     actual = '';
    365     sparsestrings.forEach(concat);
    366   }
    367   catch(e)
    368   {
    369     actual = dumpError(e);
    370   }
    371   reportCompare(expect, actual, 'Array.forEach on sparse array');
    372 }
    373 
    374 if ('filter' in Array.prototype)
    375 {
    376 // see http://developer-test.mozilla.org/docs/Core_JavaScript_1.5_Reference:Objects:Array:filter
    377 
    378   // test Array.filter
    379 
    380   // filter has 1 required argument
    381   expect = 1;
    382   actual = Array.prototype.filter.length;
    383   reportCompare(expect, actual, 'Array.prototype.filter.length == 1');
    384 
    385   // throw TypeError if no callback function specified
    386   expect = 'TypeError';
    387   try
    388   {
    389     strings.filter();
    390     actual = 'no error';
    391   }
    392   catch(e)
    393   {
    394     actual = e.name;
    395   }
    396   reportCompare(expect, actual, 'Array.filter(undefined) throws TypeError');
    397 
    398   try
    399   {
    400     // test general filter
    401     expect = 'WORLD';
    402     actual = strings.filter(isUpperCase).toString();
    403   }
    404   catch(e)
    405   {
    406     actual = dumpError(e);
    407   }
    408   reportCompare(expect, actual, 'Array.filter');
    409 
    410   try
    411   {
    412     expect = 'WORLD';
    413     obj = new ArrayCallback(false);
    414     actual = strings.filter(obj.isUpperCase, obj).toString();
    415   }
    416   catch(e)
    417   {
    418     actual = dumpError(e);
    419   }
    420   reportCompare(expect, actual, 'Array.filter object callback 1');
    421 
    422   try
    423   {
    424     expect = 'hello,Array,WORLD';
    425     obj = new ArrayCallback(true);
    426     actual = strings.filter(obj.isUpperCase, obj).toString();
    427   }
    428   catch(e)
    429   {
    430     actual = dumpError(e);
    431   }
    432   reportCompare(expect, actual, 'Array.filter object callback 2');
    433 }
    434 
    435 if ('every' in Array.prototype)
    436 {
    437 // see http://developer-test.mozilla.org/docs/Core_JavaScript_1.5_Reference:Objects:Array:every
    438 
    439   // test Array.every
    440 
    441   // every has 1 required argument
    442 
    443   expect = 1;
    444   actual = Array.prototype.every.length;
    445   reportCompare(expect, actual, 'Array.prototype.every.length == 1');
    446 
    447   // throw TypeError if no every callback function specified
    448   expect = 'TypeError';
    449   try
    450   {
    451     strings.every();
    452     actual = 'no error';
    453   }
    454   catch(e)
    455   {
    456     actual = e.name;
    457   }
    458   reportCompare(expect, actual, 'Array.every(undefined) throws TypeError');
    459 
    460   // test general every
    461 
    462   try
    463   {
    464     expect = true;
    465     actual = strings.every(isString);
    466   }
    467   catch(e)
    468   {
    469     actual = dumpError(e);
    470   }
    471   reportCompare(expect, actual, 'strings: every element is a string');
    472 
    473   try
    474   {
    475     expect = false;
    476     actual = mixed.every(isString);
    477   }
    478   catch(e)
    479   {
    480     actual = dumpError(e);
    481   }
    482   reportCompare(expect, actual, 'mixed: every element is a string');
    483 
    484   try
    485   {
    486     // see https://bugzilla.mozilla.org/show_bug.cgi?id=311082
    487     expect = true;
    488     actual = sparsestrings.every(isString);
    489   }
    490   catch(e)
    491   {
    492     actual = dumpError(e);
    493   }
    494   reportCompare(expect, actual, 'sparsestrings: every element is a string');
    495 
    496   // pass object method as map callback
    497 
    498   obj = new ArrayCallback(false);
    499 
    500   try
    501   {
    502     expect = true;
    503     actual = strings.every(obj.isString, obj);
    504   }
    505   catch(e)
    506   {
    507     actual = dumpError(e);
    508   }
    509   reportCompare(expect, actual, 'strings: every element is a string, via object callback');
    510 
    511   try
    512   {
    513     expect = false;
    514     actual = mixed.every(obj.isString, obj);
    515   }
    516   catch(e)
    517   {
    518     actual = dumpError(e) ;
    519   }
    520   reportCompare(expect, actual, 'mixed: every element is a string, via object callback');
    521 
    522   try
    523   {
    524     // see https://bugzilla.mozilla.org/show_bug.cgi?id=311082
    525     expect = true;
    526     actual = sparsestrings.every(obj.isString, obj);
    527   }
    528   catch(e)
    529   {
    530     actual = dumpError(e);
    531   }
    532   reportCompare(expect, actual, 'sparsestrings: every element is a string, via object callback');
    533 
    534 }
    535 
    536 if ('some' in Array.prototype)
    537 {
    538 // see http://developer-test.mozilla.org/docs/Core_JavaScript_1.5_Reference:Objects:Array:some
    539 
    540   // test Array.some
    541 
    542   // some has 1 required argument
    543 
    544   expect = 1;
    545   actual = Array.prototype.some.length;
    546   reportCompare(expect, actual, 'Array.prototype.some.length == 1');
    547 
    548   // throw TypeError if no some callback function specified
    549   expect = 'TypeError';
    550   try
    551   {
    552     strings.some();
    553     actual = 'no error';
    554   }
    555   catch(e)
    556   {
    557     actual = e.name;
    558   }
    559   reportCompare(expect, actual, 'Array.some(undefined) throws TypeError');
    560 
    561   // test general some
    562 
    563   try
    564   {
    565     expect = true;
    566     actual = strings.some(isString);
    567   }
    568   catch(e)
    569   {
    570     actual = dumpError(e);
    571   }
    572   reportCompare(expect, actual, 'strings: some element is a string');
    573 
    574   try
    575   {
    576     expect = true;
    577     actual = mixed.some(isString);
    578   }
    579   catch(e)
    580   {
    581     actual = dumpError(e);
    582   }
    583   reportCompare(expect, actual, 'mixed: some element is a string');
    584 
    585   try
    586   {
    587     expect = true;
    588     actual = sparsestrings.some(isString);
    589   }
    590   catch(e)
    591   {
    592     actual = dumpError(e);
    593   }
    594   reportCompare(expect, actual, 'sparsestrings: some element is a string');
    595 
    596   // pass object method as map callback
    597 
    598   obj = new ArrayCallback(false);
    599 
    600   try
    601   {
    602     expect = true;
    603     actual = strings.some(obj.isString, obj);
    604   }
    605   catch(e)
    606   {
    607     actual = dumpError(e);
    608   }
    609   reportCompare(expect, actual, 'strings: some element is a string, via object callback');
    610 
    611   try
    612   {
    613     expect = true;
    614     actual = mixed.some(obj.isString, obj);
    615   }
    616   catch(e)
    617   {
    618     actual = dumpError(e);
    619   }
    620   reportCompare(expect, actual, 'mixed: some element is a string, via object callback');
    621 
    622   try
    623   {
    624     expect = true;
    625     actual = sparsestrings.some(obj.isString, obj);
    626   }
    627   catch(e)
    628   {
    629     actual = dumpError(e);
    630   }
    631   reportCompare(expect, actual, 'sparsestrings: some element is a string, via object callback');
    632 
    633 }
    634 
    635 if ('indexOf' in Array.prototype)
    636 {
    637 // see http://developer-test.mozilla.org/docs/Core_JavaScript_1.5_Reference:Objects:Array:indexOf
    638 
    639   // test Array.indexOf
    640 
    641   // indexOf has 1 required argument
    642 
    643   expect = 1;
    644   actual = Array.prototype.indexOf.length;
    645   reportCompare(expect, actual, 'Array.prototype.indexOf.length == 1');
    646 
    647   // test general indexOf
    648 
    649   try
    650   {
    651     expect = -1;
    652     actual = mixed.indexOf('not found');
    653   }
    654   catch(e)
    655   {
    656     actual = dumpError(e);
    657   }
    658   reportCompare(expect, actual, 'indexOf returns -1 if value not found');
    659 
    660   try
    661   {
    662     expect = 0;
    663     actual = mixed.indexOf(0);
    664   }
    665   catch(e)
    666   {
    667     actual = dumpError(e);
    668   }
    669   reportCompare(expect, actual, 'indexOf matches using strict equality');
    670 
    671   try
    672   {
    673     expect = 1;
    674     actual = mixed.indexOf('0');
    675   }
    676   catch(e)
    677   {
    678     actual = dumpError(e);
    679   }
    680   reportCompare(expect, actual, 'indexOf matches using strict equality');
    681 
    682   try
    683   {
    684     expect = 2;
    685     actual = mixed.indexOf(0, 1);
    686   }
    687   catch(e)
    688   {
    689     actual = dumpError(e);
    690   }
    691   reportCompare(expect, actual, 'indexOf begins searching at fromIndex');
    692 }
    693 
    694