j.stdlib.4.6.0-P.source-code.VDMUnit.vdmpp Maven / Gradle / Ivy
The newest version!
-- Overture STANDARD LIBRARY: VDM-Unit
-- --------------------------------------------
-- Version 2.1.0
--
-- Standard library for the Overture Interpreter. When the interpreter
-- evaluates the preliminary functions/operations in this file,
-- corresponding internal functions is called instead of issuing a run
-- time error. Signatures should not be changed, as well as name of
-- module (VDM-SL) or class (VDM++). Pre/post conditions is
-- fully user customisable.
-- Dont care's may NOT be used in the parameter lists.
--
--
-- define VDM++ equivalents to the JUnit 3.8.2 classes
--
--===========================================================================
-- Using VDMUnit
--
-- VDM Unit generally supports the same features as JUnit for Java
--
-- Approach:
-- * Define one Test Case per class which should be tested
-- ** Specify all test *operations* in the test case
-- * Define a TestResult and TestSuite to execute the tests
--
-- Running the tests:
-- Option 1.
-- Use the automated reflection search to find Test classes.
-- new TestRunner().run()
--
-- Option 2.
-- Use the automated reflection search to find test operations.
-- All operations must begin with "test".
-- Usage:
-- let tests : set of Test = {new TestCase1(), new TestCase2()},
-- ts : TestSuite = new TestSuite(tests),
-- result : TestResult = new TestResult()
-- in
-- (
-- ts.run(result);
-- IO`print(result.toString());
-- );
--
-- Option 3.
-- Use explicit definition to call tests.
-- All test cases must *override* the operation
-- "protected runTest : () ==> ()"
-- This means that only a single test can be performed in each test case
--
-- Usage:
-- let ts : TestSuite = new TestSuite(),
-- result = new TestResult()
-- in
-- (
-- ts.addTest(new TestCase1());
-- ts.addTest(new TestCase2());
-- ts.run(result);
-- IO`println(result.toString());
-- )
--
--===========================================================================
-- forward definition of java.lang.Throwable
-- do not code generate (but import from Java library)
class Throwable
end Throwable
-- forward definition of java.lang.Error
-- do not code generate (but import from Java library)
class Error is subclass of Throwable
instance variables
protected fMessage : seq of char := []
operations
public Error: () ==> Error
Error () == skip;
public Error: seq of char ==> Error
Error (pmessage) == fMessage := pmessage;
public hasMessage: () ==> bool
hasMessage () == return len fMessage > 0;
public getMessage: () ==> seq of char
getMessage () == return fMessage
pre len fMessage > 0;--hasMessage()
public static throw: seq of char ==> ()
throw (pmessage) == exit new Error(pmessage)
end Error
--
-- forward definition of junit.framework.AssertionFailedError
--
class AssertionFailedError is subclass of Error
operations
public AssertionFailedError: () ==> AssertionFailedError
AssertionFailedError () == skip;
public AssertionFailedError: seq of char ==> AssertionFailedError
AssertionFailedError (pmessage) == fMessage := pmessage;
end AssertionFailedError
--
-- forward definition of junit.framework.Assert
--
class Assert
operations
public static assertTrue: bool ==> ()
assertTrue (pbool) ==
if not pbool then exit new AssertionFailedError();
public static assertTrue: seq of char * bool ==> ()
assertTrue (pmessage, pbool) ==
if not pbool then exit new AssertionFailedError(pmessage);
public static assertFalse: bool ==> ()
assertFalse (pbool) ==
if pbool then exit new AssertionFailedError();
public static assertFalse: seq of char * bool ==> ()
assertFalse (pmessage, pbool) ==
if pbool then exit new AssertionFailedError(pmessage);
public static fail: () ==> ()
fail () == exit new AssertionFailedError();
public static fail: seq of char ==> ()
fail (pmessage) == exit new AssertionFailedError(pmessage)
end Assert
--
-- forward definition of junit.framework.Test
--
class Test is subclass of Assert
instance variables
private fName : seq of char := []
operations
-- instance variables access operations
public getName: () ==> seq of char
getName () == return fName;
public setName: seq of char ==> ()
setName (name) == fName := name;
public run: TestResult ==> ()
run (-) == is subclass responsibility;
public runOnly: seq of char * TestResult ==> ()
runOnly (-,-) == is subclass responsibility
end Test
--
-- forward definition of junit.framework.TestCase
--
class TestCase is subclass of Test
operations
-- /**
-- * A convenience method to run this test, collecting the results with a
-- * default TestResult object.
-- *
-- * @see TestResult
-- */
public run :() ==> TestResult
run() ==
(
let result : TestResult = createResult() in (
run(result);
return result);
);
-- /**
-- * Runs the test case and collects the results in TestResult.
-- */
public run : TestResult ==> ()
run(result) ==
(
result.run(self);
);
public runOnly: seq of char * TestResult ==> ()
runOnly (name,result) ==
if name = getName() then
result.run(self);
protected createResult : () ==> TestResult
createResult() == return new TestResult();
operations
-- constructor
public TestCase: seq of char ==> TestCase
TestCase (name) == setName(name);
public TestCase: () ==> TestCase
TestCase () == skip;
-- template method pattern
public setUp: () ==> ()
setUp () == skip;
--
-- This method might be overriden in a sub class or it will
-- use reflection to call the test method as specified in the name
--
protected runTest: () ==> ()
runTest () == reflectionRunTest(self,getName());
--
-- External Method
--
private static reflectionRunTest : TestCase * seq of char ==> ()
reflectionRunTest(obj,name) == is not yet specified;
public runBare : () ==> ()
runBare() ==
(
dcl exception : [Throwable] := nil;
setUp();
trap exc :Throwable
with
exception := exc
in
(
runTest();
);
trap exc :Throwable
with
if exception = nil then
exception := exc
in
(
tearDown();
);
if exception <> nil then exit exception;
);
public tearDown: () ==> ()
tearDown () == skip;
end TestCase
--
-- forward definition of junit.framework.TestSuite
--
class TestSuite is subclass of Test
instance variables
private fTests : seq of Test := []
operations
public TestSuite: seq of char ==> TestSuite
TestSuite (name) == setName(name);
public TestSuite: () ==> TestSuite
TestSuite () == setName("");
public TestSuite: set of Test * seq of char ==> TestSuite
TestSuite (tests,name) ==
(
setName(name);
for all test in set tests do
(
for all t in set elems createTests(test) do
(
addTest(t);
);
);
);
public TestSuite: set of Test ==> TestSuite
TestSuite (tests) ==
(
setName("");
for all test in set tests do
(
for all t in set elems createTests(test) do
(
addTest(t);
);
);
);
public TestSuite: Test ==> TestSuite
TestSuite (test) ==
(
setName("");
for all t in set elems createTests(test) do
(
addTest(t);
);
);
public TestSuite: Test * seq of char ==> TestSuite
TestSuite (test,name) ==
(
setName(name);
for all t in set elems createTests(test) do
(
addTest(t);
);
);
public addTest: Test ==> ()
addTest (ptst) == fTests := fTests ^ [ptst];
-- implementing the abstract run operation
public run: TestResult ==> ()
run (ptr) ==for ptst in fTests do ptst.run(ptr);
public runOnly: seq of char * TestResult ==> ()
runOnly (name,ptr) ==
for ptst in fTests do
if ptst.getName() = name then
ptst.run(ptr);
public run: Test * TestResult ==> ()
run (test, ptr) == test.run(ptr);
public tests : () ==> seq of Test
tests()==return fTests;
public testCount : () ==> int
testCount()== return len fTests;
public testAt : int ==> Test
testAt(index) == return fTests(index)
pre index >0 and index < len fTests;
private getTestMethodNamed : Test ==> seq of seq of char
getTestMethodNamed(test)== is not yet specified;
public createTests : Test ==> seq of Test
createTests(test)== is not yet specified;
end TestSuite
--
-- forward definition of junit.framework.TestListener
--
class TestListener
operations
public initListener: () ==> ()
initListener () == is subclass responsibility;
public exitListener: () ==> ()
exitListener () == is subclass responsibility;
public addFailure: Test * AssertionFailedError ==> ()
addFailure (-, -) == is subclass responsibility;
public addError: Test * Throwable ==> ()
addError (-, -) == is subclass responsibility;
public startTest: Test ==> ()
startTest (-) == is subclass responsibility;
public endTest: Test ==> ()
endTest (-) == is subclass responsibility;
end TestListener
--
-- forward definition of junit.framework.TestResult
--
class TestResult
types
private InternalError :: tcname : seq of char
except : Error
instance variables
-- keep track of assertions failed
private fFailures : seq of AssertionFailedError := [];
-- keep track of exceptions thrown
private fErrors : seq of InternalError := [];
-- count the number of executed tests
private fRunTests : nat := 0;
-- the list of interested listeners
private fListeners : set of TestListener := {}
operations
public addListener: TestListener ==> ()
addListener (ptl) ==
( -- first add the listener to the set
fListeners := fListeners union {ptl};
-- execute the initializer for the listener
ptl.initListener() )
pre ptl not in set fListeners;
public removeListener: TestListener ==> ()
removeListener (ptl) ==
( -- execute the exit operation for the listener
ptl.exitListener();
-- remove the listener from the set
fListeners := fListeners \ {ptl} )
pre ptl in set fListeners;
public addFailure: Test * AssertionFailedError ==> ()
addFailure (ptst, pafe) ==
( -- first handle the failed assertion locally
if pafe.hasMessage()
then fFailures := fFailures ^ [pafe]
else let str = "Assertion failed in test "^ptst.getName() in
fFailures := fFailures ^ [new AssertionFailedError(str)];
-- now inform all listeners
for all listener in set fListeners do
listener.addFailure(ptst, pafe) );
public addError: Test * Throwable ==> ()
addError (ptst, perr) ==
( -- add the error to the list of exceptions caught so far
fErrors := fErrors ^ [mk_InternalError(ptst.getName(), perr)];
-- now inform all listeners
for all listener in set fListeners do
listener.addError(ptst, perr) );
public startTest: Test ==> ()
startTest (ptst) ==
( -- first increase the local run test counter
fRunTests := fRunTests + 1;
-- now inform all listeners
for all listener in set fListeners do
listener.startTest(ptst) );
public endTest: Test ==> ()
endTest (ptst) ==
for all listener in set fListeners do
listener.endTest(ptst);
public run : TestCase ==> ()
run(test)==
(
startTest(test);
runProtected(test);
endTest(test);
);
public runProtected : TestCase ==> ()
runProtected(test) ==
(
trap exc :Throwable
with
if isofclass(AssertionFailedError,exc)
then addFailure(test, exc)
else if isofbaseclass(Throwable, exc)
then addError(test, exc)
else error -- We hope this never happens
in (
test.runBare();
);
);
public runCount: () ==> nat
runCount () == return fRunTests;
public failureCount: () ==> nat
failureCount () == return len fFailures;
public errorCount: () ==> nat
errorCount () == return len fErrors;
public wasSuccessful: () ==> bool
wasSuccessful () == return failureCount() = 0 and errorCount() = 0;
public toString : () ==> seq of char
toString()==
(
dcl tmp: seq of char :=
"----------------------------------------\n"^
"| TEST RESULTS |\n"^
"|--------------------------------------|\n"^
"| Executed: "^ToStringInt(runCount())^"\n"^
"| Failures: "^ToStringInt(failureCount())^"\n"^
"| Errors: "^ToStringInt(errorCount())^"\n";
tmp := tmp^"|______________________________________|\n|";
for all i in set inds fFailures do
tmp := tmp^"\n| "^fFailures(i).getMessage();
tmp := tmp^"\n|";
for all i in set inds fErrors do
tmp := tmp^"\n| Error in test "^fErrors(i).tcname^" "^fErrors(i).except.getMessage();
tmp := tmp^"\n|--------------------------------------|\n";
if wasSuccessful()
then
(
tmp := tmp^"| SUCCESS |";
)
else
(
tmp := tmp^"| FAILURE |";
);
tmp := tmp^"\n|______________________________________|";
return tmp;
);
functions
-------------------------------------
-- Convert a int to a String
-------------------------------------
public static ToStringInt : int | nat1 | nat -> seq of char
ToStringInt(val) ==
let result : int = val mod 10,
rest : int = val div 10
in if rest > 0 then
ToStringInt(rest) ^ GetStringFromNum(result)
else GetStringFromNum(result)
pre val >= 0
measure ToStringIntMeasure;
private ToStringIntMeasure : nat -> nat
ToStringIntMeasure(a) == a;
-------------------------------------
-- Convert a int < 10 to a String
-------------------------------------
public static GetStringFromNum : int -> seq of char --| nat | real
GetStringFromNum(val) == ["0123456789"(val+1)]
pre val < 10;
end TestResult
class TestRunner
operations
public run : () ==> ()
run() ==
let tests : set of Test = collectTests(new TestRunner()),
ts : TestSuite = new TestSuite(tests),
result : TestResult = new TestResult()
in
(
ts.run(result);
IO`print(result.toString());
);
collectTests : TestRunner ==> set of Test
collectTests(obj) == is not yet specified;
end TestRunner
© 2015 - 2024 Weber Informatics LLC | Privacy Policy