-
Botond Baranyi authored
OOP: catching exceptions of class type is now determined by the dynamic class type, instead of the static type raised (issue #533) Signed-off-by:
Botond Baranyi <botond.baranyi@ericsson.com>
Botond Baranyi authoredOOP: catching exceptions of class type is now determined by the dynamic class type, instead of the static type raised (issue #533) Signed-off-by:
Botond Baranyi <botond.baranyi@ericsson.com>
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
exceptions.ttcn 5.13 KiB
/******************************************************************************
* Copyright (c) 2000-2021 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* Contributors:
* Baranyi, Botond
*
******************************************************************************/
module exceptions {
type record Rec {
integer num,
charstring str
}
type record of integer RoI;
type class BaseClass {
public function toString() return universal charstring {
return "BaseClass";
}
}
type class Class extends BaseClass {
public function toString() return universal charstring {
return "Class";
}
}
type class Class2 {
public function toString() return universal charstring {
return "Class2";
}
}
type component CT {
var integer cvar := 4;
var integer cv_finally_counter := 0;
timer tmr;
}
type integer SmallNumber (-100..100);
function test_block(in integer p_exception_type, in charstring p_dummy := "a") runs on CT {
var integer v_finally_increment := 1;
p_dummy := "abc";
{
select (p_exception_type) {
case (1) {
raise 3; // integer
}
case (2) {
var integer x := 6;
raise x;
}
case (3) {
raise Rec: { 2, "xy" };
}
case (4) {
raise Class.create();
}
case (5) {
raise SmallNumber:11;
}
case (6) {
var Rec x := { 9, "" };
raise x.num;
}
case (7) {
raise RoI[-]: 23;
}
case (8) {
raise Class2.create;
}
case (9) {
var object x := Class.create();
raise x;
}
}
// otherwise don't raise anything
}
catch (SmallNumber a) {
if (a != 11) {
setverdict(fail, "Unexpected SmallNumber exception: ", a);
}
}
catch (Rec.num a) {
if (a != 9) {
setverdict(fail, "Unexpected Rec.num exception: ", a);
}
}
catch (RoI[-] a) {
if (a != 23) {
setverdict(fail, "Unexpected RoI[-] exception: ", a);
}
}
catch (integer a) {
var integer a2 := a;
if (a2 != 3 and a2 != 6) {
setverdict(fail, "Unexpected integer exception: ", a2);
}
}
catch (Rec b) {
if (b != { 2, "xy" }) {
setverdict(fail, "Unexpected Rec exception: ", b);
}
}
catch (BaseClass c) {
if (c.toString() != "Class") {
setverdict(fail, "Unexpected BaseClass exception: ", c);
}
}
catch (Class c) {
setverdict(fail, "Unexpected Class exception: ", c);
}
catch (object c) {
if (c.toString() != "Class2") {
setverdict(fail, "Unexpected BaseClass exception: ", c);
}
}
finally {
cv_finally_counter := cv_finally_counter + v_finally_increment; // test referencing a local variable (in the main block)
log(p_dummy); // test referencing a shadowed function parameter (in the main block)
if (cv_finally_counter > 0) {
log(p_exception_type); // test referencing a function parameter (in a sub-block)
}
setverdict(pass);
}
}
testcase tc_exceptions_block() runs on CT {
for (var integer i := 1; i <= 9; i := i + 1) {
test_block(i);
}
test_block(200);
if (cv_finally_counter != 10) {
setverdict(fail, "Invalid 'finally' execution count: ", cv_finally_counter);
}
}
function test_function(boolean p_raise) runs on CT {
if (p_raise) {
raise "abc";
}
}
catch (charstring x) {
if (x != "abc") {
setverdict(fail, "Unexpected exception: ", x);
}
}
finally {
cv_finally_counter := cv_finally_counter + 1;
setverdict(pass);
}
testcase tc_exceptions_function() runs on CT {
test_function(true);
test_function(false);
if (cv_finally_counter != 2) {
setverdict(fail, "Invalid 'finally' execution count: ", cv_finally_counter);
}
}
altstep test_altstep(boolean p_raise) runs on CT {
[] tmr.timeout {
if (p_raise) {
raise 6;
}
}
}
catch (integer x) {
if (x != 6) {
setverdict(fail, "Unexpected exception: ", x);
}
}
finally {
cv_finally_counter := cv_finally_counter + 1;
setverdict(pass);
}
testcase tc_exceptions_altstep() runs on CT {
tmr.start(0.1);
test_altstep(true);
tmr.start(0.1);
alt {
[] test_altstep(false);
}
var default def := activate(test_altstep(true));
timer tmr2;
tmr2.start(10.0);
tmr.start(0.1);
alt {
[] tmr2.timeout { setverdict(fail, "Default altstep not called."); }
}
if (cv_finally_counter != 6) {
setverdict(fail, "Invalid 'finally' execution count: ", cv_finally_counter);
}
}
testcase tc_exceptions_testcase() runs on CT {
raise 100;
cvar := -1;
}
catch (integer x) {
cvar := x;
}
finally {
if (cvar == 100) {
setverdict(pass);
}
else if (cvar == 4) {
setverdict(fail, "Exception not caught.");
}
else if (cvar == -1) {
setverdict(fail, "Not exception raised.");
}
else {
setverdict(fail, "Unknown error...");
}
}
control {
execute(tc_exceptions_block());
execute(tc_exceptions_function());
execute(tc_exceptions_altstep());
execute(tc_exceptions_testcase());
}
}