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: 11.6.1-2.js michael@0: ECMA Section: 11.6.1 The addition operator ( + ) michael@0: Description: michael@0: michael@0: The addition operator either performs string concatenation or numeric michael@0: addition. michael@0: michael@0: The production AdditiveExpression : AdditiveExpression + MultiplicativeExpression michael@0: is evaluated as follows: michael@0: michael@0: 1. Evaluate AdditiveExpression. michael@0: 2. Call GetValue(Result(1)). michael@0: 3. Evaluate MultiplicativeExpression. michael@0: 4. Call GetValue(Result(3)). michael@0: 5. Call ToPrimitive(Result(2)). michael@0: 6. Call ToPrimitive(Result(4)). michael@0: 7. If Type(Result(5)) is String or Type(Result(6)) is String, go to step 12. michael@0: (Note that this step differs from step 3 in the algorithm for comparison michael@0: for the relational operators in using or instead of and.) michael@0: 8. Call ToNumber(Result(5)). michael@0: 9. Call ToNumber(Result(6)). michael@0: 10. Apply the addition operation to Result(8) and Result(9). See the discussion below (11.6.3). michael@0: 11. Return Result(10). michael@0: 12. Call ToString(Result(5)). michael@0: 13. Call ToString(Result(6)). michael@0: 14. Concatenate Result(12) followed by Result(13). michael@0: 15. Return Result(14). michael@0: michael@0: Note that no hint is provided in the calls to ToPrimitive in steps 5 and 6. michael@0: All native ECMAScript objects except Date objects handle the absence of a michael@0: hint as if the hint Number were given; Date objects handle the absence of a michael@0: hint as if the hint String were given. Host objects may handle the absence michael@0: of a hint in some other manner. michael@0: michael@0: This test does only covers cases where the Additive or Mulplicative expression michael@0: ToPrimitive is a string. michael@0: michael@0: Author: christine@netscape.com michael@0: Date: 12 november 1997 michael@0: */ michael@0: var SECTION = "11.6.1-2"; michael@0: var VERSION = "ECMA_1"; michael@0: startTest(); michael@0: michael@0: writeHeaderToLog( SECTION + " The Addition operator ( + )"); michael@0: michael@0: // tests for boolean primitive, boolean object, Object object, a "MyObject" whose value is michael@0: // a boolean primitive and a boolean object. michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = 'string'; var EXP_2 = false; EXP_1 + EXP_2", michael@0: "stringfalse", michael@0: eval("var EXP_1 = 'string'; var EXP_2 = false; EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = true; var EXP_2 = 'string'; EXP_1 + EXP_2", michael@0: "truestring", michael@0: eval("var EXP_1 = true; var EXP_2 = 'string'; EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new Boolean(true); var EXP_2 = new String('string'); EXP_1 + EXP_2", michael@0: "truestring", michael@0: eval("var EXP_1 = new Boolean(true); var EXP_2 = new String('string'); EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new Object(true); var EXP_2 = new Object('string'); EXP_1 + EXP_2", michael@0: "truestring", michael@0: eval("var EXP_1 = new Object(true); var EXP_2 = new Object('string'); EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new Object(new String('string')); var EXP_2 = new Object(new Boolean(false)); EXP_1 + EXP_2", michael@0: "stringfalse", michael@0: eval("var EXP_1 = new Object(new String('string')); var EXP_2 = new Object(new Boolean(false)); EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new MyObject(true); var EXP_2 = new MyObject('string'); EXP_1 + EXP_2", michael@0: "truestring", michael@0: eval("var EXP_1 = new MyObject(true); var EXP_2 = new MyObject('string'); EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new MyObject(new String('string')); var EXP_2 = new MyObject(new Boolean(false)); EXP_1 + EXP_2", michael@0: "[object Object][object Object]", michael@0: eval("var EXP_1 = new MyObject(new String('string')); var EXP_2 = new MyObject(new Boolean(false)); EXP_1 + EXP_2") ); michael@0: michael@0: // tests for number primitive, number object, Object object, a "MyObject" whose value is michael@0: // a number primitive and a number object. michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = 100; var EXP_2 = 'string'; EXP_1 + EXP_2", michael@0: "100string", michael@0: eval("var EXP_1 = 100; var EXP_2 = 'string'; EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new String('string'); var EXP_2 = new Number(-1); EXP_1 + EXP_2", michael@0: "string-1", michael@0: eval("var EXP_1 = new String('string'); var EXP_2 = new Number(-1); EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new Object(100); var EXP_2 = new Object('string'); EXP_1 + EXP_2", michael@0: "100string", michael@0: eval("var EXP_1 = new Object(100); var EXP_2 = new Object('string'); EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new Object(new String('string')); var EXP_2 = new Object(new Number(-1)); EXP_1 + EXP_2", michael@0: "string-1", michael@0: eval("var EXP_1 = new Object(new String('string')); var EXP_2 = new Object(new Number(-1)); EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new MyObject(100); var EXP_2 = new MyObject('string'); EXP_1 + EXP_2", michael@0: "100string", michael@0: eval("var EXP_1 = new MyObject(100); var EXP_2 = new MyObject('string'); EXP_1 + EXP_2") ); michael@0: michael@0: new TestCase( SECTION, michael@0: "var EXP_1 = new MyObject(new String('string')); var EXP_2 = new MyObject(new Number(-1)); EXP_1 + EXP_2", michael@0: "[object Object][object Object]", michael@0: eval("var EXP_1 = new MyObject(new String('string')); var EXP_2 = new MyObject(new Number(-1)); EXP_1 + EXP_2") ); michael@0: michael@0: test(); michael@0: michael@0: function MyObject( value ) { michael@0: this.valueOf = new Function( "return this.value" ); michael@0: this.value = value; michael@0: }