Home | History | Annotate | Download | only in Exceptions
      1 /* ***** BEGIN LICENSE BLOCK *****
      2 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
      3 *
      4 * The contents of this file are subject to the Netscape Public License
      5 * Version 1.1 (the "License"); you may not use this file except in
      6 * compliance with the License. You may obtain a copy of the License at
      7 * http://www.mozilla.org/NPL/
      8 *
      9 * Software distributed under the License is distributed on an "AS IS" basis,
     10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
     11 * for the specific language governing rights and limitations under the
     12 * License.
     13 *
     14 * The Original Code is JavaScript Engine testing utilities.
     15 *
     16 * The Initial Developer of the Original Code is Netscape Communications Corp.
     17 * Portions created by the Initial Developer are Copyright (C) 2002
     18 * the Initial Developer. All Rights Reserved.
     19 *
     20 * Contributor(s): brendan (at) mozilla.org, pschwartau (at) netscape.com
     21 *
     22 * Alternatively, the contents of this file may be used under the terms of
     23 * either the GNU General Public License Version 2 or later (the "GPL"), or
     24 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
     25 * in which case the provisions of the GPL or the LGPL are applicable instead
     26 * of those above. If you wish to allow use of your version of this file only
     27 * under the terms of either the GPL or the LGPL, and not to allow others to
     28 * use your version of this file under the terms of the NPL, indicate your
     29 * decision by deleting the provisions above and replace them with the notice
     30 * and other provisions required by the GPL or the LGPL. If you do not delete
     31 * the provisions above, a recipient may use your version of this file under
     32 * the terms of any one of the NPL, the GPL or the LGPL.
     33 *
     34 * ***** END LICENSE BLOCK *****
     35 *
     36 *
     37 * Date:    28 Feb 2002
     38 * SUMMARY: Testing that Error.stack distinguishes between:
     39 *
     40 * A) top-level calls: myFunc();
     41 * B) no-name function calls: function() { myFunc();} ()
     42 *
     43 * The stack frame for A) should begin with '@'
     44 * The stack frame for B) should begin with '()'
     45 *
     46 * This behavior was coded by Brendan during his fix for bug 127136.
     47 * See http://bugzilla.mozilla.org/show_bug.cgi?id=127136#c13
     48 *
     49 * Note: our function getStackFrames(err) orders the array of stack frames
     50 * so that the 0th element will correspond to the highest frame, i.e. will
     51 * correspond to a line in top-level code. The 1st element will correspond
     52 * to the function that is called first, and so on...
     53 *
     54 * NOTE: At present Rhino does not have an Error.stack property. It is an
     55 * ECMA extension, see http://bugzilla.mozilla.org/show_bug.cgi?id=123177
     56 */
     57 //-----------------------------------------------------------------------------
     58 var UBound = 0;
     59 var bug = '(none)';
     60 var summary = 'Testing Error.stack';
     61 var status = '';
     62 var statusitems = [];
     63 var actual = '';
     64 var actualvalues = [];
     65 var expect= '';
     66 var expectedvalues = [];
     67 var myErr = '';
     68 var stackFrames = '';
     69 
     70 
     71 function A(x,y)
     72 {
     73   return B(x+1,y+1);
     74 }
     75 
     76 function B(x,z)
     77 {
     78   return C(x+1,z+1);
     79 }
     80 
     81 function C(x,y)
     82 {
     83   return D(x+1,y+1);
     84 }
     85 
     86 function D(x,z)
     87 {
     88   try
     89   {
     90     throw new Error('meep!');
     91   }
     92   catch (e)
     93   {
     94     return e;
     95   }
     96 }
     97 
     98 
     99 myErr = A(44,13);
    100 stackFrames = getStackFrames(myErr);
    101   status = inSection(1);
    102   actual = stackFrames[0].substring(0,1);
    103   expect = '@';
    104   addThis();
    105 
    106   status = inSection(2);
    107   actual = stackFrames[1].substring(0,9);
    108   expect = 'A(44,13)@';
    109   addThis();
    110 
    111   status = inSection(3);
    112   actual = stackFrames[2].substring(0,9);
    113   expect = 'B(45,14)@';
    114   addThis();
    115 
    116   status = inSection(4);
    117   actual = stackFrames[3].substring(0,9);
    118   expect = 'C(46,15)@';
    119   addThis();
    120 
    121   status = inSection(5);
    122   actual = stackFrames[4].substring(0,9);
    123   expect = 'D(47,16)@';
    124   addThis();
    125 
    126 
    127 
    128 myErr = A('44:foo','13:bar');
    129 stackFrames = getStackFrames(myErr);
    130   status = inSection(6);
    131   actual = stackFrames[0].substring(0,1);
    132   expect = '@';
    133   addThis();
    134 
    135   status = inSection(7);
    136   actual = stackFrames[1].substring(0,21);
    137   expect = 'A("44:foo","13:bar")@';
    138   addThis();
    139 
    140   status = inSection(8);
    141   actual = stackFrames[2].substring(0,23);
    142   expect = 'B("44:foo1","13:bar1")@';
    143   addThis();
    144 
    145   status = inSection(9);
    146   actual = stackFrames[3].substring(0,25);
    147   expect = 'C("44:foo11","13:bar11")@';
    148   addThis();
    149 
    150   status = inSection(10);
    151   actual = stackFrames[4].substring(0,27);
    152   expect = 'D("44:foo111","13:bar111")@';;
    153   addThis();
    154 
    155 
    156 
    157 /*
    158  * Make the first frame occur in a function with an empty name -
    159  */
    160 myErr = function() { return A(44,13); } ();
    161 stackFrames = getStackFrames(myErr);
    162   status = inSection(11);
    163   actual = stackFrames[0].substring(0,1);
    164   expect = '@';
    165   addThis();
    166 
    167   status = inSection(12);
    168   actual = stackFrames[1].substring(0,3);
    169   expect = '()@';
    170   addThis();
    171 
    172   status = inSection(13);
    173   actual = stackFrames[2].substring(0,9);
    174   expect = 'A(44,13)@';
    175   addThis();
    176 
    177 // etc. for the rest of the frames as above
    178 
    179 
    180 
    181 /*
    182  * Make the first frame occur in a function with name 'anonymous' -
    183  */
    184 var f = Function('return A(44,13);');
    185 myErr = f();
    186 stackFrames = getStackFrames(myErr);
    187   status = inSection(14);
    188   actual = stackFrames[0].substring(0,1);
    189   expect = '@';
    190   addThis();
    191 
    192   status = inSection(15);
    193   actual = stackFrames[1].substring(0,12);
    194   expect = 'anonymous()@';
    195   addThis();
    196 
    197   status = inSection(16);
    198   actual = stackFrames[2].substring(0,9);
    199   expect = 'A(44,13)@';
    200   addThis();
    201 
    202 // etc. for the rest of the frames as above
    203 
    204 
    205 
    206 /*
    207  * Make a user-defined error via the Error() function -
    208  */
    209 var message = 'Hi there!'; var fileName = 'file name'; var lineNumber = 0;
    210 myErr = Error(message, fileName, lineNumber);
    211 stackFrames = getStackFrames(myErr);
    212   status = inSection(17);
    213   actual = stackFrames[0].substring(0,1);
    214   expect = '@';
    215   addThis();
    216 
    217 
    218 /*
    219  * Now use the |new| keyword. Re-use the same params -
    220  */
    221 myErr = new Error(message, fileName, lineNumber);
    222 stackFrames = getStackFrames(myErr);
    223   status = inSection(18);
    224   actual = stackFrames[0].substring(0,1);
    225   expect = '@';
    226   addThis();
    227 
    228 
    229 
    230 
    231 //-----------------------------------------------------------------------------
    232 test();
    233 //-----------------------------------------------------------------------------
    234 
    235 
    236 
    237 /*
    238  * Split the string |err.stack| along its '\n' delimiter.
    239  * As of 2002-02-28 |err.stack| ends with the delimiter, so
    240  * the resulting array has an empty string as its last element.
    241  *
    242  * Pop that useless element off before doing anything.
    243  * Then reverse the array, for convenience of indexing -
    244  */
    245 function getStackFrames(err)
    246 {
    247   var arr = err.stack.split('\n');
    248   arr.pop();
    249   return arr.reverse();
    250 }
    251 
    252 
    253 function addThis()
    254 {
    255   statusitems[UBound] = status;
    256   actualvalues[UBound] = actual;
    257   expectedvalues[UBound] = expect;
    258   UBound++;
    259 }
    260 
    261 
    262 function test()
    263 {
    264   enterFunc('test');
    265   printBugNumber(bug);
    266   printStatus(summary);
    267 
    268   for (var i=0; i<UBound; i++)
    269   {
    270     reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
    271   }
    272 
    273   exitFunc ('test');
    274 }
    275