Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add decorators tests #4103

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
82 changes: 82 additions & 0 deletions src/decorator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Decorator Test Notes

## Terminology

Some terms are simplified in these tests to make it easier to communicate
meaning and intent.

- **static** is used to refer to all class elements that are used with the
`static` keyword, including fields and methods. This should be thought of as
"elements that belong to the class definition".

- **instance** is used to refer to all class elements that are used _without_
the static keyword, including fields and methods. This should be thought as
"elements that belong to the class instance". Some of these elements are
assigned to the class prototype rather than the instance, but from a typical
usage perspective, a user will only call these methods when dealing with an
instance of the class. Most users do not ever deal directly with the class
prototype.

- **methods** refers to all public/private _methods_, _getters_, and _setters_.
These are elements that do _not_ have a per-instance initializer, and for this
reason they are grouped together for things like initialization and decorator
application.

- **fields** refers to all public/private _fields_ and _accessors_. Accessors
here refers to auto-accessors created with the `accessor` keyword, _NOT_
getters and setters created with the `get` and `set` keywords. These are
elements that _have_ an initialization step per-instance, and grouped
together for initialization and decorator application for that reason.

- **Extra-initializers** refers to all initializers added via
`context.addInitializer`. This distinguishes them from standard initializers
for fields and accessors, which run in a different order and with different
timing.

## Structure

- Element decorator templates all follow the same basic structure in order to
share as much code as possible for repeated tests.

- The class element being tested is named `element` for public elements and
`#element` for private elements.

- If the element is gettable, there is a `getElement` public method that
directly gets the element. If the element is a field, accessor, or getter,
this will call any getters and return the value. If it is a method, it will
return the method itself. Setters are not gettable.

- These is a `setElement` public method that directly sets the element. If the
element is a field, accessor, or setter, this will call any setters and set
the value. Getters and methods are not settable.

- Each element template folder is broken down into the following directory
structure:

```
.
└── [element type]/
└── [test case type]/
├── private/
│ ├── instance/
│ │ ├── cls-decl.template
│ │ └── cls-expr.template
│ └── static/
│ ├── cls-decl.template
│ └── cls-expr.template
└── public/
├── instance/
│ ├── cls-decl.template
│ └── cls-expr.template
└── static/
└── cls-decl.template/
└── cls-expr.template
```

This structure allows each test to easily select the types of values it
applies to and test them across both class declarations and expressions.
Private and public are split out because there are some common differences
between them (e.g. `context.private`, `context.name`) and the same is true for
static vs instance (e.g. `context.static`).


22 changes: 22 additions & 0 deletions src/decorator/accessor-deco-invalid-return-get.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator cannot return invalid getter
template: accessors/error/**/*
features: [decorators]
---*/

//- decorators
function dec() {
return {
get: 123
};
}

//- application
@dec

//- error
TypeError
22 changes: 22 additions & 0 deletions src/decorator/accessor-deco-invalid-return-init.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator cannot return invalid init
template: accessors/error/**/*
features: [decorators]
---*/

//- decorators
function dec() {
return {
init: 123
};
}

//- application
@dec

//- error
TypeError
22 changes: 22 additions & 0 deletions src/decorator/accessor-deco-invalid-return-set.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator cannot return invalid setter
template: accessors/error/**/*
features: [decorators]
---*/

//- decorators
function dec() {
return {
set: 123
};
}

//- application
@dec

//- error
TypeError
20 changes: 20 additions & 0 deletions src/decorator/accessor-deco-invalid-return.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator cannot return invalid init
template: accessors/error/**/*
features: [decorators]
---*/

//- decorators
function dec() {
return 123;
}

//- application
@dec

//- error
TypeError
25 changes: 25 additions & 0 deletions src/decorator/accessor-deco-returns-get.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator can return a new getter
template: accessors/standard/**/*
features: [decorators]
---*/

//- decorators
function dec({ get }) {
return {
get() {
assert.sameValue(get.call(this), undefined);
return 123;
}
};
}

//- application
@dec

//- assertions
assert.sameValue(classOrInstance.getElement(), 123);
27 changes: 27 additions & 0 deletions src/decorator/accessor-deco-returns-init.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator can return a new init
template: accessors/standard/**/*
features: [decorators]
---*/

//- decorators
function dec() {
return {
init(value) {
assert.sameValue(value, undefined);
return 123;
}
};
}

//- application
@dec

//- assertions
assert.sameValue(classOrInstance.getElement(), 123);
classOrInstance.setElement(456);
assert.sameValue(classOrInstance.getElement(), 456);
27 changes: 27 additions & 0 deletions src/decorator/accessor-deco-returns-set.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator can return a new getter
template: accessors/standard/**/*
features: [decorators]
---*/

//- decorators
function dec({ set }) {
return {
set(value) {
assert.sameValue(value, 123);
set.call(this, 456);
}
};
}

//- application
@dec

//- assertions
assert.sameValue(classOrInstance.getElement(), undefined);
classOrInstance.setElement(123);
assert.sameValue(classOrInstance.getElement(), 456);
28 changes: 28 additions & 0 deletions src/decorator/accessor-with-init-deco-returns-get.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator can return a new getter
template: accessors/with-init/**/*
features: [decorators]
---*/

//- initializer
123

//- decorators
function dec({ get }) {
return {
get() {
assert.sameValue(get.call(this), 123);
return 456;
}
};
}

//- application
@dec

//- assertions
assert.sameValue(classOrInstance.getElement(), 456);
30 changes: 30 additions & 0 deletions src/decorator/accessor-with-init-deco-returns-init.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator can return a new init that chains with default initializer
template: accessors/with-init/**/*
features: [decorators]
---*/

//- initializer
123

//- decorators
function dec({ get, set }) {
return {
init(value) {
assert.sameValue(value, 123);
return 456;
}
};
}

//- application
@dec

//- assertions
assert.sameValue(classOrInstance.getElement(), 456);
classOrInstance.setElement(789);
assert.sameValue(classOrInstance.getElement(), 789);
30 changes: 30 additions & 0 deletions src/decorator/accessor-with-init-deco-returns-set.case
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-applydecoratorstoelementdefinition
desc: Accessor decorator can return a new setter when initializer is present
template: accessors/with-init/**/*
features: [decorators]
---*/

//- initializer
123

//- decorators
function dec({ set }) {
return {
set(value) {
assert.sameValue(value, 456);
set.call(this, 789);
}
};
}

//- application
@dec

//- assertions
assert.sameValue(classOrInstance.getElement(), 123);
classOrInstance.setElement(456);
assert.sameValue(classOrInstance.getElement(), 789);
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
path: language/statements/class/decorator/accessor/error/private/instance/
name: private acessor decorator evaluation error in class declaration
features: [class, decorators, class-fields-private]
esid: prod-FieldDefinition
---*/

/*{ decorators }*/

function evaluate() {
class C {
/*{ application }*/
accessor #element;
}
}

assert.throws(/*{ error }*/, evaluate);
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (C) 2024 Kristen Maevyn Hewell Garrett. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
path: language/expressions/class/decorator/accessor/error/private/instance/
name: private acessor decorator behavior in class expression
features: [class, decorators, class-fields-private]
esid: prod-FieldDefinition
---*/

/*{ decorators }*/

function evaluate() {
var C = class {
/*{ application }*/
accessor #element;
}
}

assert.throws(/*{ error }*/, evaluate);

Loading
Loading