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 conformance tests for trap-expr #1085

Closed
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
351 changes: 351 additions & 0 deletions conformance/lang/expressions/trap_expr.balt
Original file line number Diff line number Diff line change
@@ -0,0 +1,351 @@
Test-Case: output
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved
Description: Test the result of the trap expression being `e`,
when evaluation of the expression completes abruptly with panic with associated value `e`.
Labels: error-type, function-call-expr, function-defn, optional-type, panic, trap-expr

function foo() {
panic error("foo panics");
}

function init() {
error? e1 = trap foo();
io:println(e1); // @output error("foo panics")
}

Test-Case: output
Description: Test the result of the trap expression being `v`,
when evaluation of the expression does not complete abruptly with panic.
Labels: error-type, function-call-expr, function-defn, int, nil-literal, nil-type, optional-type, trap-expr, union-type, variable-reference-expr

function init() {
int? nilVal = ();
int|error? e = trap nilVal;
io:println(e is ()); // @output true
}

Test-Case: error
Description: If type of expr is T, then type of trap expr is T|error.
Labels: error-type, int, local-init-var-decl-stmt, multiplicative-expr, nil-literal, optional-type, string, trap-expr, union-type, variable-reference-expr

function errorFunction() {
int zero = 0;
int? nilVal = ();
int _ = trap 2 / zero; // @error incompatible types: expected 'int', found '(int|error)'
string|error? x = trap nilVal; // @error incompatible types: expected '(string|error)?', found 'int?'
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved
int _ = trap 2; // @error incompatible types: expected 'int', found '(int|error)'
string _ = trap "str"; // @error incompatible types: expected 'string', found '(string|error)'
float _ = trap 2.3f; // @error incompatible types: expected 'float', found '(float|error)'
}

Test-Case: error
Description: If type of expr is T, then type of trap expr is T|error.
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved
Fail-Issue: ballerina-platform/ballerina-lang#36472
Labels: error-type, int, local-init-var-decl-stmt, multiplicative-expr, trap-expr, variable-reference-expr
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved

function errorFunction() {
int zero = 0;
error e = trap 2 / zero; // @error incompatible types: expected 'error', found 'int'
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved
}

Test-Case: output
Description: Test trap expression when the type of expression is never.
Labels: boolean, error-constructor-expr, error-type, function-call-expr, function-defn, int, never, panic, return-stmt, trap-expr, union-type

function funcNeverReturns() returns never {
panic error("msg");
}

function init() {
never|error e1 = trap funcNeverReturns();
io:println(e1); // @output error("msg")
error e2 = trap funcNeverReturns();
io:println(e2); // @output error("msg")
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved
}

Test-Case: output
Description: Test trap expression when the expression is a nil-literal and it does not panic.
Labels: error-type, is-expr, nil-literal, nil-type, null, optional-type, trap-expr, union-type

function init() {
()|error t1 = trap ();
io:println(t1 is ()); // @output true

error? t2 = trap null;
io:println(t2 is ()); // @output true
}

Test-Case: output
Description: Test trap expression when the expression is a boolean-literal and it does not panic.
Labels: boolean, boolean-literal, error-type, trap-expr, union-type

function init() {
boolean|error t = trap false;
io:println(t); // @output false
}

Test-Case: output
Description: Test trap expression when the expression is a numeric-literal and it does not panic.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When does a numeric literal panic?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on this?

Let's also remove the productions from the descriptions everywhere.

numeric-literal -> numeric literal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5303f62

Labels: decimal, error-type, float, int, trap-expr, union-type

function init() {
int|error t1 = trap 2;
io:println(t1); // @output 2
float|error t2 = trap 2e3f;
io:println(t2); // @output 2000.0
decimal|error t3 = trap 2e355d;
io:println(t3); // @output 2E+355
}

Test-Case: output
Description: Test trap expression when the expression is a string-literal and it does not panic.
Labels: string, trap-expr, union-type

function init() {
string|error t1 = trap "Hello";
io:println(t1); // @output Hello
t1 = trap "Hello\tWorld";
io:println(t1); // @output Hello World
}

Test-Case: output
Description: Test trap expression when the expression is a byte-array-literal and it does not panic.
Labels: byte, byte-array-literal, error-type, trap-expr, union-type

function init() {
byte[]|error t1 = trap base16 `aeeecdefabcd12345567888822`;
io:println(t1); // @output [174,238,205,239,171,205,18,52,85,103,136,136,34]
t1 = trap base64 `aGVsbG8gYmFsbGVyaW5hICEhIQ==`;
io:println(t1); // @output [104,101,108,108,111,32,98,97,108,108,101,114,105,110,97,32,33,33,33]
}

Test-Case: output
Description: Test trap expression when the expression is a string-template-expr and it does not panic.
Labels: error-type, string-template-expr, trap-expr, union-type

function init() {
string|error t1 = trap string `Hello World!`;
io:println(t1); // @output Hello World!
string s = string `Hello World!`;
string|error t2 = trap string `${s}`;
io:println(t2); // @output Hello World!
}

Test-Case: output
Description: Test trap expression when the expression is a xml-template-expr and it does not panic.
Labels: error-type, trap-expr, union-type, xml-template-expr

function init() {
xml|error t1 = trap xml `<Greeting>Hello!</Greeting>`;
io:println(t1); // @output <Greeting>Hello!</Greeting>
}

Test-Case: output
Description: Test trap expression when the expression is a list constructor expression. Test 1.
Labels: array-type, error-type, int, list-constructor-expr, string, trap-expr, union-type

function init() {
int[]|error t1 = trap [1, 2, 3, 4];
io:println(t1); // @output [1,2,3,4]
(int|string)[]|error t2 = trap [1, "2", 3, "4"];
io:println(t2); // @output [1,"2",3,"4"]
}

Test-Case: output
Description: Test trap expression when the expression is a list constructor expression. Test 2.
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved
Labels: array-type, error-type, function-call-expr, function-defn, int, list-constructor-expr, return-stmt, string, trap-expr, type-cast-expr, union-type

function foo() returns int|string {
return "2";
}

function init() {
int[]|error t = trap [1, 2, <int> foo(), 4];
io:println(t); // @output error("{ballerina}TypeCastError",message="incompatible types: 'string' cannot be cast to 'int'")
}

Test-Case: output
Description: Test trap expression when the expression is a table constructor expression.
Labels: error-type, int, multiplicative-expr, record-type, record-type-readonly-field, string, table-constructor-expr, union-type, trap-expr

function init() {
(table<record {|readonly string name; int id;|}> key(name))|error tbl1 = trap table key(name) [
{name: "John Doe", id: 9223372036854775807*2}
];
io:println(tbl1); // @output error("{ballerina}NumberOverflow",message="int range overflow")
}

Test-Case: output
Description: Test trap expression when the expression is a object constructor expression.
Labels: error-type, function-type, method-call-expr, object-constructor-expr, optional-type, panic, trap-expr

function init() {
object { function bar(); } obj = object {
error? i = ();
function bar() {
self.i = self.foo();
}
function foo() {
panic error("msg");
}
};
error? e = trap obj.bar();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also doesn't match the description.

io:println(e); // @output error("msg")
}

Test-Case: output
Description: Test trap expression when the expression is a new expression.
Labels: error-constructor-expr, error-type, function-defn, method-call-expr, module-class-defn, new-expr, optional-type, panic, trap-expr

class Obj {
function bar() {
panic error("msg");
}
}

function init() {
Obj obj = new();
error? t = trap obj.bar();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't match the description.

Test trap expression when the expression is a new expression.

io:println(t); // @output error("msg")
}

Test-Case: output
Description: Test trap expression when the expression is a member access expression.
Labels: array-type, error-type, int, member-access-expr, trap-expr

function init() {
int[] i = [];
io:println(trap i[3]); // @output error("{ballerina/lang.array}IndexOutOfRange",message="array index out of range: index: 3, size: 0")
}

Test-Case: output
Description: Test trap expression when the expression is a function call expression.
Labels: array-type, error-constructor-expr, error-type, function-call-expr, function-defn, int, optional-type, return-stmt, trap-expr, union-type

function foo() returns int {
int[] i = [];
return i[3];
Comment on lines +217 to +218
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing member access related labels in Labels.

}

function bar() {
panic error("msg");
}

function init() {
int|error t1 = trap foo();
io:println(t1); // @output error("{ballerina/lang.array}IndexOutOfRange",message="array index out of range: index: 3, size: 0")
error? t2 = trap bar();
io:println(t2); // @output error("msg")
}

Test-Case: output
Description: Test trap expression when the expression is a type cast expression.
Labels: error-type, function-call-expr, function-defn, int, return-stmt, string, trap-expr, type-cast-expr, union-type

function foo() returns int|string {
return "str";
}

function init() {
int|error t1 = trap <int>foo();
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved
io:println(t1); // @output error("{ballerina}TypeCastError",message="incompatible types: 'string' cannot be cast to 'int'")
string|error t2 = trap <string>foo();
io:println(t2); // @output str
}

Test-Case: output
Description: Test trap expression when the expression is a unary logical expression.
Labels: boolean, error-type, function-call-expr, function-defn, int, return-stmt, trap-expr, union-type

function foo() returns int|boolean {
return 23;
}

function init() {
boolean|error t1 = trap !<boolean>foo();
io:println(t1); // @output error("{ballerina}TypeCastError",message="incompatible types: 'int' cannot be cast to 'boolean'")
}

Test-Case: output
Description: Test trap expression when the expression is a multiplicative expression.
Labels: boolean, error-type, function-call-expr, function-defn, int, local-init-var-decl-stmt, multiplicative-expr, trap-expr, union-type, variable-reference-expr

function init() {
int zero = 0;
int|error t1 = trap 2 / zero;
io:println(t1); // @output error("{ballerina}DivisionByZero",message=" / by zero")
int|error t2 = trap int:MAX_VALUE * int:MAX_VALUE;
io:println(t2); // @output error("{ballerina}NumberOverflow",message="int range overflow")
}

Test-Case: output
Description: Test trap expression when the expression is a trap expression.
Labels: boolean, error-type, function-call-expr, function-defn, int, local-init-var-decl-stmt, multiplicative-expr, trap-expr, union-type, variable-reference-expr

function init() {
int zero = 0;
int|error t1 = trap trap 2 / zero;
io:println(t1); // @output error("{ballerina}DivisionByZero",message=" / by zero")
}

Test-Case: output
Description: Test trap expression when the expression is a checking expression.
Labels: boolean, check, checkpanic, error-type, int, local-init-var-decl-stmt, multiplicative-expr, trap-expr, union-type, variable-reference-expr

function init() {
int zero = 0;
int|error e1 = trap (check 2 / zero);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a bug. trap captures a panic. check should return the error from the function. Can you recheck in the spec and create a spec issue if required or a lang issue?

io:println(e1); // @output error("{ballerina}DivisionByZero",message=" / by zero")
int|error e2 = trap (checkpanic 2 / zero);
io:println(e2); // @output error("{ballerina}DivisionByZero",message=" / by zero")
}

Test-Case: output
Description: Test trap expression when the expression is a char and it does not panic.
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved
Labels: boolean, error-type, local-init-var-decl-stmt, string:Char, trap-expr, union-type, variable-reference-expr

function init() {
string:Char c = "c";
string:Char|error e1 = trap c;
io:println(e1); // @output c
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have tests for when the expression doesn't panic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added few tests at the bottom

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it the test immediately after this? Can we improve the descriptions to specifically mention that they don't panic?

Test-Case: output
Description: Test trap expression when the expression is a byte value and it does not panic.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add some tests with function calls here instead of literals and variable reference expressions that we know will never panic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MaryamZi, do you mean here to add function calls that causes panic or add functions that return literal?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like a function call, which at compile-time we don't know if it will panic.

function init() {
    int|error a = trap fn("1");
    io:println(a);
}

function fn(string str) returns int {
    return checkpanic int:fromString(str);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

Labels: boolean, byte, error-type, local-init-var-decl-stmt, trap-expr, union-type, variable-reference-expr

function init() {
byte b = 0;
byte|error e = trap b;
io:println(e); // @output 0
}

Test-Case: output
Description: Test trap expression when the expression is a byte value and it does not panic.
Labels: boolean, error-type, int:Signed32, int:Unsigned32, local-init-var-decl-stmt, trap-expr, union-type, variable-reference-expr

function init() {
int:Signed32 i1 = -12;
int:Signed32|error e1 = trap i1;
io:println(e1); // @output -12
int:Unsigned32 i2 = 1234;
int:Unsigned32|error e2 = trap i2;
io:println(e2); // @output 1234
}
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved

Test-Case: output
Description: Test trap expression when the expression is a query expression
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Description: Test trap expression when the expression is a query expression
Description: Test trap expression when the expression is a query expression.

Labels: array-type, error-type, list-constructor-expr, query-expr, trap-expr, union-type

function init() {
int[]|error res = trap from var item in [1, 0, 4]
select 5/item;
io:println(res); // @output error("{ballerina}DivisionByZero",message=" / by zero")
}

Test-Case: output
Description: Test trap expression when the expression is a transactional expression and it does not panic.
Labels: transactional-expr, trap-expr

function init() {
io:println(trap transactional); // @output false
}
KavinduZoysa marked this conversation as resolved.
Show resolved Hide resolved