Add abstract property tests and rebaseline.

1. Positive tests.
2. Negative tests.
3. Update error messages.
4. Remove errors from conformance test.
This commit is contained in:
Nathan Shively-Sanders
2016-02-22 10:31:31 -08:00
parent 48f728e96f
commit 02fc8b1b2d
11 changed files with 501 additions and 21 deletions

View File

@@ -0,0 +1,56 @@
//// [abstractProperty.ts]
interface A {
prop: string;
raw: string;
m(): void;
}
abstract class B implements A {
abstract prop: string;
abstract raw: string;
abstract readonly ro: string;
abstract get readonlyProp(): string;
abstract set readonlyProp(val: string);
abstract m(): void;
}
class C extends B {
get prop() { return "foo"; }
set prop(v) { }
raw = "edge";
readonly ro = "readonly please";
readonlyProp: string; // don't have to give a value, in fact
m() { }
}
//// [abstractProperty.js]
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var B = (function () {
function B() {
}
Object.defineProperty(B.prototype, "readonlyProp", {
get: function () { },
set: function (val) { },
enumerable: true,
configurable: true
});
return B;
}());
var C = (function (_super) {
__extends(C, _super);
function C() {
_super.apply(this, arguments);
this.raw = "edge";
this.ro = "readonly please";
}
Object.defineProperty(C.prototype, "prop", {
get: function () { return "foo"; },
set: function (v) { },
enumerable: true,
configurable: true
});
C.prototype.m = function () { };
return C;
}(B));

View File

@@ -0,0 +1,59 @@
=== tests/cases/compiler/abstractProperty.ts ===
interface A {
>A : Symbol(A, Decl(abstractProperty.ts, 0, 0))
prop: string;
>prop : Symbol(prop, Decl(abstractProperty.ts, 0, 13))
raw: string;
>raw : Symbol(raw, Decl(abstractProperty.ts, 1, 17))
m(): void;
>m : Symbol(m, Decl(abstractProperty.ts, 2, 16))
}
abstract class B implements A {
>B : Symbol(B, Decl(abstractProperty.ts, 4, 1))
>A : Symbol(A, Decl(abstractProperty.ts, 0, 0))
abstract prop: string;
>prop : Symbol(prop, Decl(abstractProperty.ts, 5, 31))
abstract raw: string;
>raw : Symbol(raw, Decl(abstractProperty.ts, 6, 26))
abstract readonly ro: string;
>ro : Symbol(ro, Decl(abstractProperty.ts, 7, 25))
abstract get readonlyProp(): string;
>readonlyProp : Symbol(readonlyProp, Decl(abstractProperty.ts, 8, 33), Decl(abstractProperty.ts, 9, 40))
abstract set readonlyProp(val: string);
>readonlyProp : Symbol(readonlyProp, Decl(abstractProperty.ts, 8, 33), Decl(abstractProperty.ts, 9, 40))
>val : Symbol(val, Decl(abstractProperty.ts, 10, 30))
abstract m(): void;
>m : Symbol(m, Decl(abstractProperty.ts, 10, 43))
}
class C extends B {
>C : Symbol(C, Decl(abstractProperty.ts, 12, 1))
>B : Symbol(B, Decl(abstractProperty.ts, 4, 1))
get prop() { return "foo"; }
>prop : Symbol(prop, Decl(abstractProperty.ts, 13, 19), Decl(abstractProperty.ts, 14, 32))
set prop(v) { }
>prop : Symbol(prop, Decl(abstractProperty.ts, 13, 19), Decl(abstractProperty.ts, 14, 32))
>v : Symbol(v, Decl(abstractProperty.ts, 15, 13))
raw = "edge";
>raw : Symbol(raw, Decl(abstractProperty.ts, 15, 19))
readonly ro = "readonly please";
>ro : Symbol(ro, Decl(abstractProperty.ts, 16, 17))
readonlyProp: string; // don't have to give a value, in fact
>readonlyProp : Symbol(readonlyProp, Decl(abstractProperty.ts, 17, 36))
m() { }
>m : Symbol(m, Decl(abstractProperty.ts, 18, 25))
}

View File

@@ -0,0 +1,62 @@
=== tests/cases/compiler/abstractProperty.ts ===
interface A {
>A : A
prop: string;
>prop : string
raw: string;
>raw : string
m(): void;
>m : () => void
}
abstract class B implements A {
>B : B
>A : A
abstract prop: string;
>prop : string
abstract raw: string;
>raw : string
abstract readonly ro: string;
>ro : string
abstract get readonlyProp(): string;
>readonlyProp : string
abstract set readonlyProp(val: string);
>readonlyProp : string
>val : string
abstract m(): void;
>m : () => void
}
class C extends B {
>C : C
>B : B
get prop() { return "foo"; }
>prop : string
>"foo" : string
set prop(v) { }
>prop : string
>v : string
raw = "edge";
>raw : string
>"edge" : string
readonly ro = "readonly please";
>ro : string
>"readonly please" : string
readonlyProp: string; // don't have to give a value, in fact
>readonlyProp : string
m() { }
>m : () => void
}

View File

@@ -0,0 +1,106 @@
tests/cases/compiler/abstractPropertyNegative.ts(10,18): error TS2380: 'get' and 'set' accessor must have the same type.
tests/cases/compiler/abstractPropertyNegative.ts(11,18): error TS2380: 'get' and 'set' accessor must have the same type.
tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'm' from class 'B'.
tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'mismatch' from class 'B'.
tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'prop' from class 'B'.
tests/cases/compiler/abstractPropertyNegative.ts(13,7): error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'readonlyProp' from class 'B'.
tests/cases/compiler/abstractPropertyNegative.ts(15,5): error TS1244: Abstract methods can only appear within an abstract class.
tests/cases/compiler/abstractPropertyNegative.ts(16,37): error TS1005: '{' expected.
tests/cases/compiler/abstractPropertyNegative.ts(19,1): error TS2450: Left-hand side of assignment expression cannot be a constant or a read-only property.
tests/cases/compiler/abstractPropertyNegative.ts(24,7): error TS2415: Class 'WrongTypePropertyImpl' incorrectly extends base class 'WrongTypeProperty'.
Types of property 'num' are incompatible.
Type 'string' is not assignable to type 'number'.
tests/cases/compiler/abstractPropertyNegative.ts(30,7): error TS2415: Class 'WrongTypeAccessorImpl' incorrectly extends base class 'WrongTypeAccessor'.
Types of property 'num' are incompatible.
Type 'string' is not assignable to type 'number'.
tests/cases/compiler/abstractPropertyNegative.ts(33,7): error TS2415: Class 'WrongTypeAccessorImpl2' incorrectly extends base class 'WrongTypeAccessor'.
Types of property 'num' are incompatible.
Type 'string' is not assignable to type 'number'.
tests/cases/compiler/abstractPropertyNegative.ts(38,18): error TS2676: Accessors must both be abstract or not abstract.
tests/cases/compiler/abstractPropertyNegative.ts(39,9): error TS2676: Accessors must both be abstract or not abstract.
tests/cases/compiler/abstractPropertyNegative.ts(40,9): error TS2676: Accessors must both be abstract or not abstract.
tests/cases/compiler/abstractPropertyNegative.ts(41,18): error TS2676: Accessors must both be abstract or not abstract.
==== tests/cases/compiler/abstractPropertyNegative.ts (16 errors) ====
interface A {
prop: string;
m(): string;
}
abstract class B implements A {
abstract prop: string;
public abstract readonly ro: string;
abstract get readonlyProp(): string;
abstract m(): string;
abstract get mismatch(): string;
~~~~~~~~
!!! error TS2380: 'get' and 'set' accessor must have the same type.
abstract set mismatch(val: number); // error, not same type
~~~~~~~~
!!! error TS2380: 'get' and 'set' accessor must have the same type.
}
class C extends B {
~
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'm' from class 'B'.
~
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'mismatch' from class 'B'.
~
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'prop' from class 'B'.
~
!!! error TS2515: Non-abstract class 'C' does not implement inherited abstract member 'readonlyProp' from class 'B'.
readonly ro = "readonly please";
abstract notAllowed: string;
~~~~~~~~
!!! error TS1244: Abstract methods can only appear within an abstract class.
get concreteWithNoBody(): string;
~
!!! error TS1005: '{' expected.
}
let c = new C();
c.ro = "error: lhs of assignment can't be readonly";
~~~~
!!! error TS2450: Left-hand side of assignment expression cannot be a constant or a read-only property.
abstract class WrongTypeProperty {
abstract num: number;
}
class WrongTypePropertyImpl extends WrongTypeProperty {
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2415: Class 'WrongTypePropertyImpl' incorrectly extends base class 'WrongTypeProperty'.
!!! error TS2415: Types of property 'num' are incompatible.
!!! error TS2415: Type 'string' is not assignable to type 'number'.
num = "nope, wrong";
}
abstract class WrongTypeAccessor {
abstract get num(): number;
}
class WrongTypeAccessorImpl extends WrongTypeAccessor {
~~~~~~~~~~~~~~~~~~~~~
!!! error TS2415: Class 'WrongTypeAccessorImpl' incorrectly extends base class 'WrongTypeAccessor'.
!!! error TS2415: Types of property 'num' are incompatible.
!!! error TS2415: Type 'string' is not assignable to type 'number'.
get num() { return "nope, wrong"; }
}
class WrongTypeAccessorImpl2 extends WrongTypeAccessor {
~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2415: Class 'WrongTypeAccessorImpl2' incorrectly extends base class 'WrongTypeAccessor'.
!!! error TS2415: Types of property 'num' are incompatible.
!!! error TS2415: Type 'string' is not assignable to type 'number'.
num = "nope, wrong";
}
abstract class AbstractAccessorMismatch {
abstract get p1(): string;
~~
!!! error TS2676: Accessors must both be abstract or not abstract.
set p1(val: string) { };
~~
!!! error TS2676: Accessors must both be abstract or not abstract.
get p2(): string { return "should work"; }
~~
!!! error TS2676: Accessors must both be abstract or not abstract.
abstract set p2(val: string);
~~
!!! error TS2676: Accessors must both be abstract or not abstract.
}

View File

@@ -0,0 +1,144 @@
//// [abstractPropertyNegative.ts]
interface A {
prop: string;
m(): string;
}
abstract class B implements A {
abstract prop: string;
public abstract readonly ro: string;
abstract get readonlyProp(): string;
abstract m(): string;
abstract get mismatch(): string;
abstract set mismatch(val: number); // error, not same type
}
class C extends B {
readonly ro = "readonly please";
abstract notAllowed: string;
get concreteWithNoBody(): string;
}
let c = new C();
c.ro = "error: lhs of assignment can't be readonly";
abstract class WrongTypeProperty {
abstract num: number;
}
class WrongTypePropertyImpl extends WrongTypeProperty {
num = "nope, wrong";
}
abstract class WrongTypeAccessor {
abstract get num(): number;
}
class WrongTypeAccessorImpl extends WrongTypeAccessor {
get num() { return "nope, wrong"; }
}
class WrongTypeAccessorImpl2 extends WrongTypeAccessor {
num = "nope, wrong";
}
abstract class AbstractAccessorMismatch {
abstract get p1(): string;
set p1(val: string) { };
get p2(): string { return "should work"; }
abstract set p2(val: string);
}
//// [abstractPropertyNegative.js]
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var B = (function () {
function B() {
}
Object.defineProperty(B.prototype, "readonlyProp", {
get: function () { },
enumerable: true,
configurable: true
});
Object.defineProperty(B.prototype, "mismatch", {
get: function () { },
set: function (val) { } // error, not same type
,
enumerable: true,
configurable: true
});
return B;
}());
var C = (function (_super) {
__extends(C, _super);
function C() {
_super.apply(this, arguments);
this.ro = "readonly please";
}
Object.defineProperty(C.prototype, "concreteWithNoBody", {
get: function () { },
enumerable: true,
configurable: true
});
return C;
}(B));
var c = new C();
c.ro = "error: lhs of assignment can't be readonly";
var WrongTypeProperty = (function () {
function WrongTypeProperty() {
}
return WrongTypeProperty;
}());
var WrongTypePropertyImpl = (function (_super) {
__extends(WrongTypePropertyImpl, _super);
function WrongTypePropertyImpl() {
_super.apply(this, arguments);
this.num = "nope, wrong";
}
return WrongTypePropertyImpl;
}(WrongTypeProperty));
var WrongTypeAccessor = (function () {
function WrongTypeAccessor() {
}
Object.defineProperty(WrongTypeAccessor.prototype, "num", {
get: function () { },
enumerable: true,
configurable: true
});
return WrongTypeAccessor;
}());
var WrongTypeAccessorImpl = (function (_super) {
__extends(WrongTypeAccessorImpl, _super);
function WrongTypeAccessorImpl() {
_super.apply(this, arguments);
}
Object.defineProperty(WrongTypeAccessorImpl.prototype, "num", {
get: function () { return "nope, wrong"; },
enumerable: true,
configurable: true
});
return WrongTypeAccessorImpl;
}(WrongTypeAccessor));
var WrongTypeAccessorImpl2 = (function (_super) {
__extends(WrongTypeAccessorImpl2, _super);
function WrongTypeAccessorImpl2() {
_super.apply(this, arguments);
this.num = "nope, wrong";
}
return WrongTypeAccessorImpl2;
}(WrongTypeAccessor));
var AbstractAccessorMismatch = (function () {
function AbstractAccessorMismatch() {
}
Object.defineProperty(AbstractAccessorMismatch.prototype, "p1", {
get: function () { },
set: function (val) { },
enumerable: true,
configurable: true
});
;
Object.defineProperty(AbstractAccessorMismatch.prototype, "p2", {
get: function () { return "should work"; },
set: function (val) { },
enumerable: true,
configurable: true
});
return AbstractAccessorMismatch;
}());

View File

@@ -1,9 +1,9 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructor.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructor.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class, method, or property declaration.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractConstructor.ts (1 errors) ====
abstract class A {
abstract constructor() {}
~~~~~~~~
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
!!! error TS1242: 'abstract' modifier can only appear on a class, method, or property declaration.
}

View File

@@ -1,4 +1,4 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class, method, or property declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,28): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(11,15): error TS2515: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(13,15): error TS2515: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.
@@ -9,7 +9,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
declare abstract class A {
abstract constructor() {}
~~~~~~~~
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
!!! error TS1242: 'abstract' modifier can only appear on a class, method, or property declaration.
~
!!! error TS1183: An implementation cannot be declared in ambient contexts.
}

View File

@@ -1,29 +1,17 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts(3,12): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts(4,15): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts(5,13): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts(7,5): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts(5,13): error TS1243: 'private' modifier cannot be used with 'abstract' modifier.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts(12,13): error TS1243: 'private' modifier cannot be used with 'abstract' modifier.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts (6 errors) ====
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractProperties.ts (2 errors) ====
abstract class A {
abstract x : number;
~~~~~~~~
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
public abstract y : number;
~~~~~~~~
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
protected abstract z : number;
~~~~~~~~
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
private abstract w : number;
~~~~~~~~
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
!!! error TS1243: 'private' modifier cannot be used with 'abstract' modifier.
abstract m: () => void;
~~~~~~~~
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
abstract foo_x() : number;
public abstract foo_y() : number;

View File

@@ -1,7 +1,7 @@
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractWithInterface.ts(1,1): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractWithInterface.ts(1,1): error TS1242: 'abstract' modifier can only appear on a class, method, or property declaration.
==== tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractWithInterface.ts (1 errors) ====
abstract interface I {}
~~~~~~~~
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
!!! error TS1242: 'abstract' modifier can only appear on a class, method, or property declaration.

View File

@@ -0,0 +1,22 @@
//@target: ES5
interface A {
prop: string;
raw: string;
m(): void;
}
abstract class B implements A {
abstract prop: string;
abstract raw: string;
abstract readonly ro: string;
abstract get readonlyProp(): string;
abstract set readonlyProp(val: string);
abstract m(): void;
}
class C extends B {
get prop() { return "foo"; }
set prop(v) { }
raw = "edge";
readonly ro = "readonly please";
readonlyProp: string; // don't have to give a value, in fact
m() { }
}

View File

@@ -0,0 +1,43 @@
//@target: ES5
interface A {
prop: string;
m(): string;
}
abstract class B implements A {
abstract prop: string;
public abstract readonly ro: string;
abstract get readonlyProp(): string;
abstract m(): string;
abstract get mismatch(): string;
abstract set mismatch(val: number); // error, not same type
}
class C extends B {
readonly ro = "readonly please";
abstract notAllowed: string;
get concreteWithNoBody(): string;
}
let c = new C();
c.ro = "error: lhs of assignment can't be readonly";
abstract class WrongTypeProperty {
abstract num: number;
}
class WrongTypePropertyImpl extends WrongTypeProperty {
num = "nope, wrong";
}
abstract class WrongTypeAccessor {
abstract get num(): number;
}
class WrongTypeAccessorImpl extends WrongTypeAccessor {
get num() { return "nope, wrong"; }
}
class WrongTypeAccessorImpl2 extends WrongTypeAccessor {
num = "nope, wrong";
}
abstract class AbstractAccessorMismatch {
abstract get p1(): string;
set p1(val: string) { };
get p2(): string { return "should work"; }
abstract set p2(val: string);
}