michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: michael@0: /** michael@0: File Name: 15.1.2.5-1.js michael@0: ECMA Section: 15.1.2.5 Function properties of the global object michael@0: unescape( string ) michael@0: michael@0: Description: michael@0: The unescape function computes a new version of a string value in which michael@0: each escape sequences of the sort that might be introduced by the escape michael@0: function is replaced with the character that it represents. michael@0: michael@0: When the unescape function is called with one argument string, the michael@0: following steps are taken: michael@0: michael@0: 1. Call ToString(string). michael@0: 2. Compute the number of characters in Result(1). michael@0: 3. Let R be the empty string. michael@0: 4. Let k be 0. michael@0: 5. If k equals Result(2), return R. michael@0: 6. Let c be the character at position k within Result(1). michael@0: 7. If c is not %, go to step 18. michael@0: 8. If k is greater than Result(2)-6, go to step 14. michael@0: 9. If the character at position k+1 within result(1) is not u, go to step michael@0: 14. michael@0: 10. If the four characters at positions k+2, k+3, k+4, and k+5 within michael@0: Result(1) are not all hexadecimal digits, go to step 14. michael@0: 11. Let c be the character whose Unicode encoding is the integer represented michael@0: by the four hexadecimal digits at positions k+2, k+3, k+4, and k+5 michael@0: within Result(1). michael@0: 12. Increase k by 5. michael@0: 13. Go to step 18. michael@0: 14. If k is greater than Result(2)-3, go to step 18. michael@0: 15. If the two characters at positions k+1 and k+2 within Result(1) are not michael@0: both hexadecimal digits, go to step 18. michael@0: 16. Let c be the character whose Unicode encoding is the integer represented michael@0: by two zeroes plus the two hexadecimal digits at positions k+1 and k+2 michael@0: within Result(1). michael@0: 17. Increase k by 2. michael@0: 18. Let R be a new string value computed by concatenating the previous value michael@0: of R and c. michael@0: 19. Increase k by 1. michael@0: 20. Go to step 5. michael@0: Author: christine@netscape.com michael@0: Date: 28 october 1997 michael@0: */ michael@0: michael@0: var SECTION = "15.1.2.5-1"; michael@0: var VERSION = "ECMA_1"; michael@0: startTest(); michael@0: var TITLE = "unescape(string)"; michael@0: michael@0: writeHeaderToLog( SECTION + " "+ TITLE); michael@0: michael@0: new TestCase( SECTION, "unescape.length", 1, unescape.length ); michael@0: new TestCase( SECTION, "unescape.length = null; unescape.length", 1, eval("unescape.length=null; unescape.length") ); michael@0: new TestCase( SECTION, "delete unescape.length", false, delete unescape.length ); michael@0: new TestCase( SECTION, "delete unescape.length; unescape.length", 1, eval("delete unescape.length; unescape.length") ); michael@0: new TestCase( SECTION, "var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS", "", eval("var MYPROPS=''; for ( var p in unescape ) { MYPROPS+= p }; MYPROPS") ); michael@0: michael@0: new TestCase( SECTION, "unescape()", "undefined", unescape() ); michael@0: new TestCase( SECTION, "unescape('')", "", unescape('') ); michael@0: new TestCase( SECTION, "unescape( null )", "null", unescape(null) ); michael@0: new TestCase( SECTION, "unescape( void 0 )", "undefined", unescape(void 0) ); michael@0: new TestCase( SECTION, "unescape( true )", "true", unescape( true ) ); michael@0: new TestCase( SECTION, "unescape( false )", "false", unescape( false ) ); michael@0: michael@0: new TestCase( SECTION, "unescape( new Boolean(true) )", "true", unescape(new Boolean(true)) ); michael@0: new TestCase( SECTION, "unescape( new Boolean(false) )", "false", unescape(new Boolean(false)) ); michael@0: michael@0: new TestCase( SECTION, "unescape( Number.NaN )", "NaN", unescape(Number.NaN) ); michael@0: new TestCase( SECTION, "unescape( -0 )", "0", unescape( -0 ) ); michael@0: new TestCase( SECTION, "unescape( 'Infinity' )", "Infinity", unescape( "Infinity" ) ); michael@0: new TestCase( SECTION, "unescape( Number.POSITIVE_INFINITY )", "Infinity", unescape( Number.POSITIVE_INFINITY ) ); michael@0: new TestCase( SECTION, "unescape( Number.NEGATIVE_INFINITY )", "-Infinity", unescape( Number.NEGATIVE_INFINITY ) ); michael@0: michael@0: var ASCII_TEST_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./"; michael@0: michael@0: new TestCase( SECTION, "unescape( " +ASCII_TEST_STRING+" )", ASCII_TEST_STRING, unescape( ASCII_TEST_STRING ) ); michael@0: michael@0: // escaped chars with ascii values less than 256 michael@0: michael@0: for ( var CHARCODE = 0; CHARCODE < 256; CHARCODE++ ) { michael@0: new TestCase( SECTION, michael@0: "unescape( %"+ ToHexString(CHARCODE)+" )", michael@0: String.fromCharCode(CHARCODE), michael@0: unescape( "%" + ToHexString(CHARCODE) ) ); michael@0: } michael@0: michael@0: // unicode chars represented by two hex digits michael@0: for ( var CHARCODE = 0; CHARCODE < 256; CHARCODE++ ) { michael@0: new TestCase( SECTION, michael@0: "unescape( %u"+ ToHexString(CHARCODE)+" )", michael@0: "%u"+ToHexString(CHARCODE), michael@0: unescape( "%u" + ToHexString(CHARCODE) ) ); michael@0: } michael@0: /* michael@0: for ( var CHARCODE = 0; CHARCODE < 256; CHARCODE++ ) { michael@0: new TestCase( SECTION, michael@0: "unescape( %u"+ ToUnicodeString(CHARCODE)+" )", michael@0: String.fromCharCode(CHARCODE), michael@0: unescape( "%u" + ToUnicodeString(CHARCODE) ) ); michael@0: } michael@0: for ( var CHARCODE = 256; CHARCODE < 65536; CHARCODE+= 333 ) { michael@0: new TestCase( SECTION, michael@0: "unescape( %u"+ ToUnicodeString(CHARCODE)+" )", michael@0: String.fromCharCode(CHARCODE), michael@0: unescape( "%u" + ToUnicodeString(CHARCODE) ) ); michael@0: } michael@0: */ michael@0: michael@0: test(); michael@0: michael@0: function ToUnicodeString( n ) { michael@0: var string = ToHexString(n); michael@0: michael@0: for ( var PAD = (4 - string.length ); PAD > 0; PAD-- ) { michael@0: string = "0" + string; michael@0: } michael@0: michael@0: return string; michael@0: } michael@0: function ToHexString( n ) { michael@0: var hex = new Array(); michael@0: michael@0: for ( var mag = 1; Math.pow(16,mag) <= n ; mag++ ) { michael@0: ; michael@0: } michael@0: michael@0: for ( index = 0, mag -= 1; mag > 0; index++, mag-- ) { michael@0: hex[index] = Math.floor( n / Math.pow(16,mag) ); michael@0: n -= Math.pow(16,mag) * Math.floor( n/Math.pow(16,mag) ); michael@0: } michael@0: michael@0: hex[hex.length] = n % 16; michael@0: michael@0: var string =""; michael@0: michael@0: for ( var index = 0 ; index < hex.length ; index++ ) { michael@0: switch ( hex[index] ) { michael@0: case 10: michael@0: string += "A"; michael@0: break; michael@0: case 11: michael@0: string += "B"; michael@0: break; michael@0: case 12: michael@0: string += "C"; michael@0: break; michael@0: case 13: michael@0: string += "D"; michael@0: break; michael@0: case 14: michael@0: string += "E"; michael@0: break; michael@0: case 15: michael@0: string += "F"; michael@0: break; michael@0: default: michael@0: string += hex[index]; michael@0: } michael@0: } michael@0: michael@0: if ( string.length == 1 ) { michael@0: string = "0" + string; michael@0: } michael@0: return string; michael@0: }