blob: 3691928dd421b714472b02a4c4ae262313160ab5 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
2// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions
6// are met:
7// 1. Redistributions of source code must retain the above copyright
8// notice, this list of conditions and the following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright
10// notice, this list of conditions and the following disclaimer in the
11// documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000024description('Tests for ES6 class constructor return values');
25
26// ES6
27// - 9.2.2 [[Construct]] (ECMAScript Function Objects)
28// - 12.3.5.1 Runtime Semantics: Evaluation (The super Keyword)
29// - 14.5.14 Runtime Semantics: ClassDefinitionEvaluation (Default Constructor)
30
31var globalVariable = {name:"globalVariable"};
32var globalSymbol = Symbol();
33
34debug('Base class');
35class BaseNoReturn { constructor() { } };
36class BaseReturnImplicit { constructor() { return; } };
37class BaseReturnUndefined { constructor() { return undefined; } };
38class BaseReturnThis { constructor() { return this; } };
39class BaseReturnObject { constructor() { return {a:1}; } };
40class BaseReturnObject2 { constructor() { return globalVariable; } };
41class BaseReturnString { constructor() { return "test"; } };
42class BaseReturnNumber { constructor() { return 1; } };
43class BaseReturnNull { constructor() { return null; } };
44class BaseReturnSymbol { constructor() { return Symbol(); } };
45class BaseThrow { constructor() { throw "Thrown Exception String"; } };
46
47// Base - Implicit => return this.
48shouldBeTrue('(new BaseNoReturn) instanceof BaseNoReturn');
49
50// Base - Early return => return this.
51shouldBeTrue('(new BaseReturnImplicit) instanceof BaseReturnImplicit');
52shouldBeTrue('(new BaseReturnImplicit) !== undefined');
53shouldBeTrue('(new BaseReturnUndefined) instanceof BaseReturnUndefined');
54shouldBeTrue('(new BaseReturnUndefined) !== undefined');
55
56// Base - return this => return this.
57shouldBeTrue('(new BaseReturnThis) instanceof BaseReturnThis');
58
59// Base - return Object => return object, not instance.
60shouldBeFalse('(new BaseReturnObject) instanceof BaseReturnObject');
61shouldBeTrue('typeof (new BaseReturnObject) === "object"');
62shouldBeFalse('(new BaseReturnObject2) instanceof BaseReturnObject');
63shouldBeTrue('(new BaseReturnObject2) === globalVariable');
64
65// Base - return non-Object => return this.
66shouldBeTrue('(new BaseReturnString) instanceof BaseReturnString');
67shouldBeTrue('typeof (new BaseReturnString) !== "string"');
68shouldBeTrue('(new BaseReturnNumber) instanceof BaseReturnNumber');
69shouldBeTrue('typeof (new BaseReturnNumber) !== "number"');
70shouldBeTrue('(new BaseReturnNull) instanceof BaseReturnNull');
71shouldBeTrue('(new BaseReturnNull) !== null');
72shouldBeTrue('(new BaseReturnSymbol) instanceof BaseReturnSymbol');
73shouldBeTrue('(new BaseReturnSymbol) !== globalSymbol');
74
75// Base - throw => throw
76shouldThrow('(new BaseThrow)');
77
78// Same behavior for Functions.
79debug(''); debug('Function constructor (non-class)');
80function FunctionNoReturn() { };
81function FunctionReturnImplicit() { return; };
82function FunctionReturnUndefined() { return undefined; };
83function FunctionReturnThis() { return this; };
84function FunctionReturnObject() { return {a:1}; };
85function FunctionReturnObject2() { return globalVariable; };
86function FunctionReturnString() { return "test"; };
87function FunctionReturnNumber() { return 1; };
88function FunctionReturnNull() { return null; };
89function FunctionReturnSymbol() { return Symbol(); };
90function FunctionThrow() { throw "Thrown Exception String"; };
91
92shouldBeTrue('(new FunctionNoReturn) instanceof FunctionNoReturn');
93shouldBeTrue('(new FunctionReturnImplicit) instanceof FunctionReturnImplicit');
94shouldBeTrue('(new FunctionReturnImplicit) !== undefined');
95shouldBeTrue('(new FunctionReturnUndefined) instanceof FunctionReturnUndefined');
96shouldBeTrue('(new FunctionReturnUndefined) !== undefined');
97shouldBeTrue('(new FunctionReturnThis) instanceof FunctionReturnThis');
98shouldBeFalse('(new FunctionReturnObject) instanceof FunctionReturnObject');
99shouldBeTrue('typeof (new FunctionReturnObject) === "object"');
100shouldBeFalse('(new FunctionReturnObject2) instanceof FunctionReturnObject');
101shouldBeTrue('(new FunctionReturnObject2) === globalVariable');
102shouldBeTrue('(new FunctionReturnString) instanceof FunctionReturnString');
103shouldBeTrue('typeof (new FunctionReturnString) !== "string"');
104shouldBeTrue('(new FunctionReturnNumber) instanceof FunctionReturnNumber');
105shouldBeTrue('typeof (new FunctionReturnNumber) !== "number"');
106shouldBeTrue('(new FunctionReturnNull) instanceof FunctionReturnNull');
107shouldBeTrue('(new FunctionReturnNull) !== null');
108shouldBeTrue('(new FunctionReturnSymbol) instanceof FunctionReturnSymbol');
109shouldBeTrue('(new FunctionReturnSymbol) !== globalSymbol');
110shouldThrow('(new FunctionThrow)');
111
112
113debug(''); debug('Derived class calling super()');
114class DerivedNoReturn extends BaseNoReturn { constructor() { super(); } };
115class DerivedReturnImplicit extends BaseNoReturn { constructor() { super(); return; } };
116class DerivedReturnUndefined extends BaseNoReturn { constructor() { super(); return undefined; } };
117class DerivedReturnThis extends BaseNoReturn { constructor() { super(); return this; } };
118class DerivedReturnObject extends BaseNoReturn { constructor() { super(); return {a:1}; } };
119class DerivedReturnObject2 extends BaseNoReturn { constructor() { super(); return globalVariable; } };
120class DerivedReturnString extends BaseNoReturn { constructor() { super(); return "test"; } };
121class DerivedReturnNumber extends BaseNoReturn { constructor() { super(); return 1; } };
122class DerivedReturnNull extends BaseNoReturn { constructor() { super(); return null; } };
123class DerivedReturnSymbol extends BaseNoReturn { constructor() { super(); return globalSymbol; } };
124class DerivedThrow extends BaseNoReturn { constructor() { super(); throw "Thrown Exception String"; } };
125
126// Derived - Implicit => return this.
127shouldBeTrue('(new DerivedNoReturn) instanceof DerivedNoReturn');
128
129// Derived - Early return => return this.
130shouldBeTrue('(new DerivedReturnImplicit) instanceof DerivedReturnImplicit');
131shouldBeTrue('(new DerivedReturnImplicit) !== undefined');
132shouldBeTrue('(new DerivedReturnUndefined) instanceof DerivedReturnUndefined');
133shouldBeTrue('(new DerivedReturnUndefined) !== undefined');
134
135// Derived - return this => return this.
136shouldBeTrue('(new DerivedReturnThis) instanceof DerivedReturnThis');
137
138// Derived - return Object => return object, not instance.
139shouldBeFalse('(new DerivedReturnObject) instanceof DerivedReturnObject');
140shouldBeTrue('typeof (new DerivedReturnObject) === "object"');
141shouldBeFalse('(new DerivedReturnObject2) instanceof DerivedReturnObject2');
142shouldBeTrue('(new DerivedReturnObject2) === globalVariable');
143
144// Derived - return non-Object => exception.
145shouldThrow('(new DerivedReturnString)');
146shouldThrow('(new DerivedReturnNumber)');
147shouldThrow('(new DerivedReturnNull)');
148shouldThrow('(new DerivedReturnSymbol)');
149shouldThrow('(new DerivedThrow)');
150
151
152debug(''); debug('Derived class not calling super()');
153class DerivedNoSuperNoReturn extends BaseNoReturn { constructor() { } };
154class DerivedNoSuperReturn extends BaseNoReturn { constructor() { return; } };
155class DerivedNoSuperReturnUndefined extends BaseNoReturn { constructor() { return undefined; } };
156class DerivedNoSuperReturnObject extends BaseNoReturn { constructor() { return {a:1}; } };
157class DerivedNoSuperReturnObject2 extends BaseNoReturn { constructor() { return globalVariable; } };
158class DerivedNoSuperReturnThis extends BaseNoReturn { constructor() { return this; } };
159class DerivedNoSuperReturnString extends BaseNoReturn { constructor() { return "test"; } };
160class DerivedNoSuperReturnNumber extends BaseNoReturn { constructor() { return 1; } };
161class DerivedNoSuperReturnNull extends BaseNoReturn { constructor() { return null; } };
162class DerivedNoSuperReturnSymbol extends BaseNoReturn { constructor() { return globalSymbol; } };
163class DerivedNoSuperThrow extends BaseNoReturn { constructor() { throw "Thrown Exception String"; } };
164
165// Derived without super() - Implicit => return this => TDZ.
166shouldThrow('(new DerivedNoSuperNoReturn)');
167
168// Derived without super() - Early return => return this => TDZ.
169shouldThrow('(new DerivedNoSuperReturnImplicit)');
170shouldThrow('(new DerivedNoSuperReturnUndefined)');
171
172// Derived without super() - return this => return this => TDZ
173shouldThrow('(new DerivedNoSuperReturnThis)');
174
175// Derived without super() - return Object => no this access => return object, not instance
176shouldNotThrow('(new DerivedNoSuperReturnObject)');
177shouldNotThrow('(new DerivedNoSuperReturnObject2)');
178
179// Derived without super() - return non-Object => exception
180shouldThrow('(new DerivedNoSuperReturnString)'); // TypeError
181shouldThrow('(new DerivedNoSuperReturnNumber)'); // TypeError
182shouldThrow('(new DerivedNoSuperReturnNull)'); // TypeError
183shouldThrow('(new DerivedNoSuperReturnSymbol)'); // TypeError
184shouldThrow('(new DerivedNoSuperThrow)'); // Thrown exception
185
186
187debug(''); debug('Derived class with default constructor and base class returning different values');
188class DerivedDefaultConstructorWithBaseNoReturn extends BaseNoReturn { };
189class DerivedDefaultConstructorWithBaseReturnImplicit extends BaseReturnImplicit { };
190class DerivedDefaultConstructorWithBaseReturnUndefined extends BaseReturnUndefined { };
191class DerivedDefaultConstructorWithBaseReturnThis extends BaseReturnThis { };
192class DerivedDefaultConstructorWithBaseReturnObject extends BaseReturnObject { };
193class DerivedDefaultConstructorWithBaseReturnObject2 extends BaseReturnObject2 { };
194class DerivedDefaultConstructorWithBaseReturnString extends BaseReturnString { };
195class DerivedDefaultConstructorWithBaseReturnNumber extends BaseReturnNumber { };
196class DerivedDefaultConstructorWithBaseReturnNull extends BaseReturnNull { };
197class DerivedDefaultConstructorWithBaseReturnSymbol extends BaseReturnSymbol { };
198class DerivedDefaultConstructorWithBaseThrow extends BaseThrow { };
199
200// Derived default constructor - implicit "super(...arguments)" return the result of the base (Object or this).
201shouldBeTrue('(new DerivedDefaultConstructorWithBaseNoReturn) instanceof DerivedDefaultConstructorWithBaseNoReturn');
202shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnImplicit) instanceof DerivedDefaultConstructorWithBaseReturnImplicit');
203shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnUndefined) instanceof DerivedDefaultConstructorWithBaseReturnUndefined');
204shouldBeFalse('(new DerivedDefaultConstructorWithBaseReturnObject) instanceof DerivedDefaultConstructorWithBaseReturnObject');
205shouldBeTrue('typeof (new DerivedDefaultConstructorWithBaseReturnObject) === "object"');
206shouldBeFalse('(new DerivedDefaultConstructorWithBaseReturnObject2) instanceof DerivedDefaultConstructorWithBaseReturnObject2');
207shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnObject2) === globalVariable');
208shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnThis) instanceof DerivedDefaultConstructorWithBaseReturnThis');
209shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnString) instanceof DerivedDefaultConstructorWithBaseReturnString');
210shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnNumber) instanceof DerivedDefaultConstructorWithBaseReturnNumber');
211shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnNull) instanceof DerivedDefaultConstructorWithBaseReturnNull');
212shouldBeTrue('(new DerivedDefaultConstructorWithBaseReturnSymbol) instanceof DerivedDefaultConstructorWithBaseReturnSymbol');
213shouldThrow('(new DerivedDefaultConstructorWithBaseThrow)');
214
215var successfullyParsed = true;