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