initial import
[vuplus_webkit] / Source / JavaScriptCore / tests / mozilla / ecma / String / 15.5.4.11-2.js
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 Mozilla Communicator client code, released
16  * March 31, 1998.
17  *
18  * The Initial Developer of the Original Code is
19  * Netscape Communications Corporation.
20  * Portions created by the Initial Developer are Copyright (C) 1998
21  * the Initial Developer. All Rights Reserved.
22  *
23  * Contributor(s):
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    File Name:          15.5.4.11-2.js
40    ECMA Section:       15.5.4.11 String.prototype.toLowerCase()
41    Description:
42
43    Returns a string equal in length to the length of the result of converting
44    this object to a string. The result is a string value, not a String object.
45
46    Every character of the result is equal to the corresponding character of the
47    string, unless that character has a Unicode 2.0 uppercase equivalent, in which
48    case the uppercase equivalent is used instead. (The canonical Unicode 2.0 case
49    mapping shall be used, which does not depend on implementation or locale.)
50
51    Note that the toLowerCase function is intentionally generic; it does not require
52    that its this value be a String object. Therefore it can be transferred to other
53    kinds of objects for use as a method.
54
55    Author:             christine@netscape.com
56    Date:               12 november 1997
57 */
58 /*
59     Safari Changes:  This test differs from the mozilla tests in two significant
60     ways.
61         First, the lower case range for Georgian letters in this file is the
62     correct range according to the Unicode 5.0 standard, as opposed to the 
63     Georgian caseless range that mozilla uses.
64         Secondly this test uses an array for expected results with two entries,
65     instead of a single expected result. This allows us to accept Unicode 4.0 or
66     Unicode 5.0 results as correct, as opposed to the mozilla test, which assumes
67     Unicode 5.0.  This allows Safari to pass this test on OS' with different
68     Unicode standards implemented (e.g. Tiger and XP)
69 */
70     var SECTION = "15.5.4.11-2";
71     var VERSION = "ECMA_1";
72     startTest();
73     var TITLE   = "String.prototype.toLowerCase()";
74
75     writeHeaderToLog( SECTION + " "+ TITLE);
76
77     var testcases = getTestCases();
78     test();
79
80 function getTestCases() {
81     var array = new Array();
82     var item = 0;
83
84     // Georgian
85     // Range: U+10A0 to U+10FF
86     for ( var i = 0x10A0; i <= 0x10FF; i++ ) {
87         var U = new Array(new Unicode( i, 4 ), new Unicode( i, 5 ));
88
89 /*
90         array[item++] = new TestCase(   SECTION,
91                                         "var s = new String( String.fromCharCode("+i+") ); s.toLowerCase()",
92                                         String.fromCharCode(U.lower),
93                                         eval("var s = new String( String.fromCharCode("+i+") ); s.toLowerCase()") );
94 */
95         array[item++] = new TestCaseDualExpected(   SECTION,
96                                         "var s = new String( String.fromCharCode("+i+") ); s.toLowerCase().charCodeAt(0)",
97                                         U,
98                                         eval("var s = new String( String.fromCharCode(i) ); s.toLowerCase().charCodeAt(0)") );
99     }
100
101     return array;
102 }
103
104 /*
105  * TestCase constructor
106  *
107  */
108
109 function TestCaseDualExpected( n, d, e, a ) {
110     this.name        = n;
111     this.description = d;
112     this.expect      = e;
113     this.actual      = a;
114     this.passed      = true;
115     this.reason      = "";
116     this.bugnumber   = BUGNUMBER;
117
118     this.passed = getTestCaseResultDualExpected( this.expect, this.actual );
119     if ( DEBUG ) {
120         writeLineToLog( "added " + this.description );
121     }
122 }
123
124 // Added so that either Unicode 4.0 or 5.0 results will be considered correct.
125 function writeTestCaseResultDualExpected( expect, actual, string ) {
126         var passed = getTestCaseResultDualExpected( expect, actual );
127         writeFormattedResult( expect[1].lower, actual, string, passed );
128         return passed;
129 }
130 /*
131  * Added so that either Unicode 4.0 or 5.0 results will be considered correct.
132  * Compare expected result to the actual result and figure out whether
133  * the test case passed.
134  */
135 function getTestCaseResultDualExpected( expect, actual ) {
136     expectedU4 = expect[0].lower;
137     expectedU5 = expect[1].lower;
138     //  because ( NaN == NaN ) always returns false, need to do
139     //  a special compare to see if we got the right result.
140         if ( actual != actual ) {
141             if ( typeof actual == "object" ) {
142                 actual = "NaN object";
143             } else {
144                 actual = "NaN number";
145             }
146         }
147
148         if ( expectedU4 != expectedU4 )   {
149             if ( typeof expectedU4 == "object" ) {
150                 expectedU4 = "NaN object";
151             } else {
152                 expectedU4 = "NaN number";
153             }
154         }
155         if ( expectedU5 != expectedU5 )   {
156             if ( typeof expectedU5 == "object" ) {
157                 expectedU5 = "NaN object";
158             } else {
159                 expectedU5 = "NaN number";
160             }
161         }
162
163         var passed = ( expectedU4 == actual || expectedU5 == actual ) ? true : false;
164         
165         //  if both objects are numbers
166         // need to replace w/ IEEE standard for rounding
167         if ( !passed &&
168              typeof(actual) == "number" &&
169             (typeof(expectedU4) == "number" ||
170              typeof(expectedU5) == "number")) {
171             if (( Math.abs(actual-expectedU4) < 0.0000001 ) || ( Math.abs(actual-expectedU5) < 0.0000001 )) {
172                 passed = true;
173             }
174         }
175
176         //  verify type is the same
177         if ( typeof(expectedU4) != typeof(actual) && typeof(expectedU5) != typeof(actual) )   {
178             passed = false;
179         }
180
181         return passed;
182 }
183
184 function test() {
185     for ( tc=0; tc < testcases.length; tc++ ) {
186         testcases[tc].passed = writeTestCaseResultDualExpected(
187                             testcases[tc].expect,
188                             testcases[tc].actual,
189                             testcases[tc].description +" = "+ testcases[tc].actual );
190
191         testcases[tc].reason += ( testcases[tc].passed ) ? "" : "wrong value ";
192     }
193     stopTest();
194     return ( testcases );
195 }
196
197 function MyObject( value ) {
198     this.value = value;
199     this.substring = String.prototype.substring;
200     this.toString = new Function ( "return this.value+''" );
201 }
202
203 function Unicode( c, version ) {
204     u = GetUnicodeValues( c, version );
205     this.upper = u[0];
206     this.lower = u[1]
207     return this;
208 }
209
210 function GetUnicodeValues( c, version ) {
211     u = new Array();
212
213     u[0] = c;
214     u[1] = c;
215
216     // upper case Basic Latin
217
218     if ( c >= 0x0041 && c <= 0x005A) {
219         u[0] = c;
220         u[1] = c + 32;
221         return u;
222     }
223
224     // lower case Basic Latin
225     if ( c >= 0x0061 && c <= 0x007a ) {
226         u[0] = c - 32;
227         u[1] = c;
228         return u;
229     }
230
231     // upper case Latin-1 Supplement
232     if ( c == 0x00B5 ) {
233         u[0] = c;
234         u[1] = 0x039C;
235         return u;
236     }
237     if ( (c >= 0x00C0 && c <= 0x00D6) || (c >= 0x00D8 && c<=0x00DE) ) {
238         u[0] = c;
239         u[1] = c + 32;
240         return u;
241     }
242
243     // lower case Latin-1 Supplement
244     if ( (c >= 0x00E0 && c <= 0x00F6) || (c >= 0x00F8 && c <= 0x00FE) ) {
245         u[0] = c - 32;
246         u[1] = c;
247         return u;
248     }
249     if ( c == 0x00FF ) {
250         u[0] = 0x0178;
251         u[1] = c;
252         return u;
253     }
254     // Latin Extended A
255     if ( (c >= 0x0100 && c < 0x0138) || (c > 0x0149 && c < 0x0178) ) {
256         // special case for capital I
257         if ( c == 0x0130 ) {
258             u[0] = c;
259             u[1] = 0x0069;
260             return u;
261         }
262         if ( c == 0x0131 ) {
263             u[0] = 0x0049;
264             u[1] = c;
265             return u;
266         }
267
268         if ( c % 2 == 0 ) {
269         // if it's even, it's a capital and the lower case is c +1
270             u[0] = c;
271             u[1] = c+1;
272         } else {
273         // if it's odd, it's a lower case and upper case is c-1
274             u[0] = c-1;
275             u[1] = c;
276         }
277         return u;
278     }
279     if ( c == 0x0178 ) {
280         u[0] = c;
281         u[1] = 0x00FF;
282         return u;
283     }
284
285     if ( (c >= 0x0139 && c < 0x0149) || (c > 0x0178 && c < 0x017F) ) {
286         if ( c % 2 == 1 ) {
287         // if it's odd, it's a capital and the lower case is c +1
288             u[0] = c;
289             u[1] = c+1;
290         } else {
291         // if it's even, it's a lower case and upper case is c-1
292             u[0] = c-1;
293             u[1] = c;
294         }
295         return u;
296     }
297     if ( c == 0x017F ) {
298         u[0] = 0x0053;
299         u[1] = c;
300     }
301
302     // Latin Extended B
303     // need to improve this set
304
305     if ( c >= 0x0200 && c <= 0x0217 ) {
306         if ( c % 2 == 0 ) {
307             u[0] = c;
308             u[1] = c+1;
309         } else {
310             u[0] = c-1;
311             u[1] = c;
312         }
313         return u;
314     }
315
316     // Latin Extended Additional
317     // Range: U+1E00 to U+1EFF
318     // http://www.unicode.org/Unicode.charts/glyphless/U1E00.html
319
320     // Spacing Modifier Leters
321     // Range: U+02B0 to U+02FF
322
323     // Combining Diacritical Marks
324     // Range: U+0300 to U+036F
325
326     // skip Greek for now
327     // Greek
328     // Range: U+0370 to U+03FF
329
330     // Cyrillic
331     // Range: U+0400 to U+04FF
332
333     if ( c >= 0x0400 && c <= 0x040F) {
334         u[0] = c;
335         u[1] = c + 80;
336         return u;
337     }
338
339
340     if ( c >= 0x0410  && c <= 0x042F ) {
341         u[0] = c;
342         u[1] = c + 32;
343         return u;
344     }
345
346     if ( c >= 0x0430 && c<= 0x044F ) {
347         u[0] = c - 32;
348         u[1] = c;
349         return u;
350
351     }
352     if ( c >= 0x0450 && c<= 0x045F ) {
353         u[0] = c -80;
354         u[1] = c;
355         return u;
356     }
357
358     if ( c >= 0x0460 && c <= 0x047F ) {
359         if ( c % 2 == 0 ) {
360             u[0] = c;
361             u[1] = c +1;
362         } else {
363             u[0] = c - 1;
364             u[1] = c;
365         }
366         return u;
367     }
368
369     // Armenian
370     // Range: U+0530 to U+058F
371     if ( c >= 0x0531 && c <= 0x0556 ) {
372         u[0] = c;
373         u[1] = c + 48;
374         return u;
375     }
376     if ( c >= 0x0561 && c < 0x0587 ) {
377         u[0] = c - 48;
378         u[1] = c;
379         return u;
380     }
381
382     // Hebrew
383     // Range: U+0590 to U+05FF
384
385
386     // Arabic
387     // Range: U+0600 to U+06FF
388
389     // Devanagari
390     // Range: U+0900 to U+097F
391
392
393     // Bengali
394     // Range: U+0980 to U+09FF
395
396
397     // Gurmukhi
398     // Range: U+0A00 to U+0A7F
399
400
401     // Gujarati
402     // Range: U+0A80 to U+0AFF
403
404
405     // Oriya
406     // Range: U+0B00 to U+0B7F
407     // no capital / lower case
408
409
410     // Tamil
411     // Range: U+0B80 to U+0BFF
412     // no capital / lower case
413
414
415     // Telugu
416     // Range: U+0C00 to U+0C7F
417     // no capital / lower case
418
419
420     // Kannada
421     // Range: U+0C80 to U+0CFF
422     // no capital / lower case
423
424
425     // Malayalam
426     // Range: U+0D00 to U+0D7F
427
428     // Thai
429     // Range: U+0E00 to U+0E7F
430
431
432     // Lao
433     // Range: U+0E80 to U+0EFF
434
435
436     // Tibetan
437     // Range: U+0F00 to U+0FBF
438
439     // Georgian
440     // Range: U+10A0 to U+10F0
441     if ( version == 5 ) {
442         if ( c >= 0x10A0 && c <= 0x10C5 ) {
443             u[0] = c;
444             u[1] = c + 7264; //48;
445             return u;
446         }
447         if ( c >= 0x2D00 && c <= 0x2D25 ) {
448             u[0] = c;
449             u[1] = c;
450             return u;
451         }
452     }
453
454     // Hangul Jamo
455     // Range: U+1100 to U+11FF
456
457     // Greek Extended
458     // Range: U+1F00 to U+1FFF
459     // skip for now
460
461
462     // General Punctuation
463     // Range: U+2000 to U+206F
464
465     // Superscripts and Subscripts
466     // Range: U+2070 to U+209F
467
468     // Currency Symbols
469     // Range: U+20A0 to U+20CF
470
471
472     // Combining Diacritical Marks for Symbols
473     // Range: U+20D0 to U+20FF
474     // skip for now
475
476
477     // Number Forms
478     // Range: U+2150 to U+218F
479     // skip for now
480
481
482     // Arrows
483     // Range: U+2190 to U+21FF
484
485     // Mathematical Operators
486     // Range: U+2200 to U+22FF
487
488     // Miscellaneous Technical
489     // Range: U+2300 to U+23FF
490
491     // Control Pictures
492     // Range: U+2400 to U+243F
493
494     // Optical Character Recognition
495     // Range: U+2440 to U+245F
496
497     // Enclosed Alphanumerics
498     // Range: U+2460 to U+24FF
499
500     // Box Drawing
501     // Range: U+2500 to U+257F
502
503     // Block Elements
504     // Range: U+2580 to U+259F
505
506     // Geometric Shapes
507     // Range: U+25A0 to U+25FF
508
509     // Miscellaneous Symbols
510     // Range: U+2600 to U+26FF
511
512     // Dingbats
513     // Range: U+2700 to U+27BF
514
515     // CJK Symbols and Punctuation
516     // Range: U+3000 to U+303F
517
518     // Hiragana
519     // Range: U+3040 to U+309F
520
521     // Katakana
522     // Range: U+30A0 to U+30FF
523
524     // Bopomofo
525     // Range: U+3100 to U+312F
526
527     // Hangul Compatibility Jamo
528     // Range: U+3130 to U+318F
529
530     // Kanbun
531     // Range: U+3190 to U+319F
532
533
534     // Enclosed CJK Letters and Months
535     // Range: U+3200 to U+32FF
536
537     // CJK Compatibility
538     // Range: U+3300 to U+33FF
539
540     // Hangul Syllables
541     // Range: U+AC00 to U+D7A3
542
543     // High Surrogates
544     // Range: U+D800 to U+DB7F
545
546     // Private Use High Surrogates
547     // Range: U+DB80 to U+DBFF
548
549     // Low Surrogates
550     // Range: U+DC00 to U+DFFF
551
552     // Private Use Area
553     // Range: U+E000 to U+F8FF
554
555     // CJK Compatibility Ideographs
556     // Range: U+F900 to U+FAFF
557
558     // Alphabetic Presentation Forms
559     // Range: U+FB00 to U+FB4F
560
561     // Arabic Presentation Forms-A
562     // Range: U+FB50 to U+FDFF
563
564     // Combining Half Marks
565     // Range: U+FE20 to U+FE2F
566
567     // CJK Compatibility Forms
568     // Range: U+FE30 to U+FE4F
569
570     // Small Form Variants
571     // Range: U+FE50 to U+FE6F
572
573     // Arabic Presentation Forms-B
574     // Range: U+FE70 to U+FEFF
575
576     // Halfwidth and Fullwidth Forms
577     // Range: U+FF00 to U+FFEF
578
579     if ( c >= 0xFF21 && c <= 0xFF3A ) {
580         u[0] = c;
581         u[1] = c + 32;
582         return u;
583     }
584
585     if ( c >= 0xFF41 && c <= 0xFF5A ) {
586         u[0] = c - 32;
587         u[1] = c;
588         return u;
589     }
590
591     // Specials
592     // Range: U+FFF0 to U+FFFF
593
594     return u;
595 }
596
597 function DecimalToHexString( n ) {
598     n = Number( n );
599     var h = "0x";
600
601     for ( var i = 3; i >= 0; i-- ) {
602         if ( n >= Math.pow(16, i) ){
603             var t = Math.floor( n  / Math.pow(16, i));
604             n -= t * Math.pow(16, i);
605             if ( t >= 10 ) {
606                 if ( t == 10 ) {
607                     h += "A";
608                 }
609                 if ( t == 11 ) {
610                     h += "B";
611                 }
612                 if ( t == 12 ) {
613                     h += "C";
614                 }
615                 if ( t == 13 ) {
616                     h += "D";
617                 }
618                 if ( t == 14 ) {
619                     h += "E";
620                 }
621                 if ( t == 15 ) {
622                     h += "F";
623                 }
624             } else {
625                 h += String( t );
626             }
627         } else {
628             h += "0";
629         }
630     }
631
632     return h;
633 }