OLD | NEW |
(Empty) | |
| 1 // 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 AN
Y |
| 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 AN
Y |
| 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 O
N |
| 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 |
| 24 // Flags: --harmony-sloppy |
| 25 |
| 26 description('Tests for ES6 class name semantics in class statements and expressi
ons'); |
| 27 |
| 28 function runTestShouldBe(statement, result) { |
| 29 shouldBe(statement, result); |
| 30 shouldBe("'use strict'; " + statement, result); |
| 31 } |
| 32 |
| 33 function runTestShouldBeTrue(statement) { |
| 34 shouldBeTrue(statement); |
| 35 shouldBeTrue("'use strict'; " + statement); |
| 36 } |
| 37 |
| 38 function runTestShouldThrow(statement) { |
| 39 shouldThrow(statement); |
| 40 shouldThrow("'use strict'; " + statement); |
| 41 } |
| 42 |
| 43 function runTestShouldNotThrow(statement) { |
| 44 shouldNotThrow(statement); |
| 45 shouldNotThrow("'use strict'; " + statement); |
| 46 } |
| 47 |
| 48 // Class statement. Class name added to global scope. Class name is available in
side class scope and in global scope. |
| 49 debug('Class statement'); |
| 50 runTestShouldThrow("A"); |
| 51 runTestShouldThrow("class {}"); |
| 52 runTestShouldThrow("class { constructor() {} }"); |
| 53 runTestShouldNotThrow("class A { constructor() {} }"); |
| 54 runTestShouldBe("class A { constructor() {} }; A.toString()", "'class A { constr
uctor() {} }'"); |
| 55 runTestShouldBeTrue("class A { constructor() {} }; (new A) instanceof A"); |
| 56 runTestShouldBe("class A { constructor() { this.base = A; } }; (new A).base.toSt
ring()", "'class A { constructor() { this.base = A; } }'"); |
| 57 runTestShouldNotThrow("class A { constructor() {} }; class B extends A {};"); |
| 58 runTestShouldBe("class A { constructor() {} }; class B extends A { constructor()
{} }; B.toString()", "'class B extends A { constructor() {} }'"); |
| 59 runTestShouldBeTrue("class A { constructor() {} }; class B extends A {}; (new B)
instanceof A"); |
| 60 runTestShouldBeTrue("class A { constructor() {} }; class B extends A {}; (new B)
instanceof B"); |
| 61 runTestShouldBe("class A { constructor() {} }; class B extends A { constructor()
{ super(); this.base = A; this.derived = B; } }; (new B).base.toString()", "'cl
ass A { constructor() {} }'"); |
| 62 runTestShouldBe("class A { constructor() {} }; class B extends A { constructor()
{ super(); this.base = A; this.derived = B; } }; (new B).derived.toString()", "
'class B extends A { constructor() { super(); this.base = A; this.derived = B; }
}'"); |
| 63 |
| 64 // Class expression. Class name not added to scope. Class name is available insi
de class scope. |
| 65 debug(''); debug('Class expression'); |
| 66 runTestShouldThrow("A"); |
| 67 runTestShouldNotThrow("(class {})"); |
| 68 runTestShouldNotThrow("(class { constructor(){} })"); |
| 69 runTestShouldBe("typeof (class {})", '"function"'); |
| 70 runTestShouldNotThrow("(class A {})"); |
| 71 runTestShouldBe("typeof (class A {})", '"function"'); |
| 72 runTestShouldThrow("(class A {}); A"); |
| 73 runTestShouldNotThrow("new (class A {})"); |
| 74 runTestShouldBe("typeof (new (class A {}))", '"object"'); |
| 75 runTestShouldNotThrow("(new (class A { constructor() { this.base = A; } })).base
"); |
| 76 runTestShouldBe("(new (class A { constructor() { this.base = A; } })).base.toStr
ing()", '"class A { constructor() { this.base = A; } }"'); |
| 77 runTestShouldNotThrow("class A {}; (class B extends A {})"); |
| 78 runTestShouldThrow("class A {}; (class B extends A {}); B"); |
| 79 runTestShouldNotThrow("class A {}; new (class B extends A {})"); |
| 80 runTestShouldNotThrow("class A {}; new (class B extends A { constructor() { supe
r(); this.base = A; this.derived = B; } })"); |
| 81 runTestShouldBeTrue("class A {}; (new (class B extends A { constructor() { super
(); this.base = A; this.derived = B; } })) instanceof A"); |
| 82 runTestShouldBe("class A { constructor() {} }; (new (class B extends A { constru
ctor() { super(); this.base = A; this.derived = B; } })).base.toString()", "'cla
ss A { constructor() {} }'"); |
| 83 runTestShouldBe("class A { constructor() {} }; (new (class B extends A { constru
ctor() { super(); this.base = A; this.derived = B; } })).derived.toString()", "'
class B extends A { constructor() { super(); this.base = A; this.derived = B; }
}'"); |
| 84 |
| 85 // Assignment of a class expression to a variable. Variable name available in sc
ope, class name is not. Class name is available inside class scope. |
| 86 debug(''); debug('Class expression assignment to variable'); |
| 87 runTestShouldThrow("A"); |
| 88 runTestShouldNotThrow("var VarA = class {}"); |
| 89 runTestShouldBe("var VarA = class { constructor() {} }; VarA.toString()", "'clas
s { constructor() {} }'"); |
| 90 runTestShouldThrow("VarA"); |
| 91 runTestShouldNotThrow("var VarA = class A { constructor() {} }"); |
| 92 runTestShouldBe("var VarA = class A { constructor() {} }; VarA.toString()", "'cl
ass A { constructor() {} }'"); |
| 93 runTestShouldThrow("var VarA = class A { constructor() {} }; A.toString()"); |
| 94 runTestShouldBeTrue("var VarA = class A { constructor() {} }; (new VarA) instanc
eof VarA"); |
| 95 runTestShouldBe("var VarA = class A { constructor() { this.base = A; } }; (new V
arA).base.toString()", "'class A { constructor() { this.base = A; } }'"); |
| 96 runTestShouldNotThrow("var VarA = class A { constructor() {} }; var VarB = class
B extends VarA { constructor() {} };"); |
| 97 runTestShouldThrow("var VarA = class A { constructor() {} }; var VarB = class B
extends VarA { constructor() {} }; B"); |
| 98 runTestShouldBe("var VarA = class A { constructor() {} }; var VarB = class B ext
ends VarA { constructor() {} }; VarB.toString()", "'class B extends VarA { const
ructor() {} }'"); |
| 99 runTestShouldBeTrue("var VarA = class A { constructor() {} }; var VarB = class B
extends VarA { }; (new VarB) instanceof VarA"); |
| 100 runTestShouldBeTrue("var VarA = class A { constructor() {} }; var VarB = class B
extends VarA { }; (new VarB) instanceof VarB"); |
| 101 runTestShouldBeTrue("var VarA = class A { constructor() {} }; var VarB = class B
extends VarA { constructor() { super(); this.base = VarA; this.derived = B; thi
s.derivedVar = VarB; } }; (new VarB).base === VarA"); |
| 102 runTestShouldBeTrue("var VarA = class A { constructor() {} }; var VarB = class B
extends VarA { constructor() { super(); this.base = VarA; this.derived = B; thi
s.derivedVar = VarB; } }; (new VarB).derived === VarB"); |
| 103 runTestShouldBeTrue("var VarA = class A { constructor() {} }; var VarB = class B
extends VarA { constructor() { super(); this.base = VarA; this.derived = B; thi
s.derivedVar = VarB; } }; (new VarB).derivedVar === VarB"); |
| 104 |
| 105 // FIXME: Class statement binding should be like `let`, not `var`. |
| 106 debug(''); debug('Class statement binding in other circumstances'); |
| 107 runTestShouldThrow("var result = A; result"); |
| 108 runTestShouldThrow("var result = A; class A {}; result"); |
| 109 runTestShouldThrow("class A { constructor() { A = 1; } }; new A"); |
| 110 runTestShouldBe("class A { constructor() { } }; A = 1; A", "1"); |
| 111 runTestShouldNotThrow("class A {}; var result = A; result"); |
| 112 shouldBe("eval('var Foo = 10'); Foo", "10"); |
| 113 shouldThrow("'use strict'; eval('var Foo = 10'); Foo"); |
| 114 shouldBe("eval('class Bar { constructor() {} }'); Bar.toString()", "'class Bar {
constructor() {} }'"); |
| 115 shouldThrow("'use strict'; eval('class Bar { constructor() {} }'); Bar.toString(
)"); |
OLD | NEW |