You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
7.1 KiB
226 lines
7.1 KiB
/** |
|
* Base class aimed to contain sets of tests for various components of |
|
* Acedia and it's features. |
|
* Neither this class, nor it's children aren't supposed to |
|
* be instantiated. |
|
* Copyright 2020 Anton Tarasenko |
|
*------------------------------------------------------------------------------ |
|
* This file is part of Acedia. |
|
* |
|
* Acedia is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation, version 3 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* Acedia is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. |
|
*/ |
|
class TestCase extends AcediaObject |
|
abstract; |
|
|
|
// Name by which this set of unit tests can be referred to. |
|
var protected const string caseName; |
|
// Name of group to which this set of unit tests belong. |
|
var protected const string caseGroup; |
|
|
|
// Were all tests performed? |
|
var private bool finishedTests; |
|
// Context under which we are currently performing our tests. |
|
var private string currentContext; |
|
// Error message that will be generated if some test will fail now. |
|
var private string currentIssue; |
|
|
|
// Summary where we are recording results of all our tests. |
|
var private TestCaseSummary currentSummary; |
|
|
|
/** |
|
* Sets context for any tests that will follow this call (but before the next |
|
* `Context()` call). |
|
* |
|
* Context is supposed to be a short description about what |
|
* exactly you are testing. When reporting failed tests, - failures will be |
|
* grouped up by a context. |
|
* |
|
* Changing current context will also reset current issue, to set it up |
|
* use `Issue()` method. |
|
* |
|
* @param context Context for the following tests. |
|
*/ |
|
public final static function Context(string context) |
|
{ |
|
default.currentContext = context; |
|
default.currentIssue = ""; // Reset issue. |
|
} |
|
|
|
// Call this function to define an error message for tests that |
|
// would fail after it. |
|
// Message is reset by another call of `Issue()` or |
|
// by changing the context via `Context()`. |
|
/** |
|
* Changes an issue that any following tests (but before the next `Issue()` or |
|
* `Context()` call) will test for. |
|
* |
|
* Issue is the message that will be displayed to the user if any relevant |
|
* tests have failed. |
|
* |
|
* NOTE: Current issue will be reset by any `Context()` call. |
|
* |
|
* @param issue Issue that following tests will test for. |
|
*/ |
|
public final static function Issue(string issue) |
|
{ |
|
default.currentIssue = issue; |
|
} |
|
|
|
// Following functions provide simple test primitives |
|
|
|
/** |
|
* This call will record either one success or one failure for the caller |
|
* `TestCase` class, depending on passed `bool` argument. |
|
* |
|
* @param result Your test's result as a `bool` value: `true` will record a |
|
* success and `false` a failure. |
|
*/ |
|
public final static function TEST_ExpectTrue(bool result) |
|
{ |
|
RecordTestResult(result); |
|
} |
|
|
|
/** |
|
* This call will record either one success or one failure for the caller |
|
* `TestCase` class, depending on passed `bool` argument. |
|
* |
|
* @param result Your test's result as a `bool` value: `false` will result in |
|
* recording a success and `true` in a failure. |
|
*/ |
|
public final static function TEST_ExpectFalse(bool result) |
|
{ |
|
RecordTestResult(!result); |
|
} |
|
|
|
/** |
|
* This call will record either one success or one failure for the caller |
|
* `TestCase` class, depending on passed `Object` argument. |
|
* |
|
* @param result Your test's result as an `Object` value: `none` will result |
|
* in recording success and any non-`none` value in failure. |
|
*/ |
|
public final static function TEST_ExpectNone(Object object) |
|
{ |
|
RecordTestResult(object == none); |
|
} |
|
|
|
/** |
|
* This call will record either one success or one failure for the caller |
|
* `TestCase` class, depending on passed `Object` argument. |
|
* |
|
* @param result Your test's result as an `Object` value: any non-`none` |
|
* value will result in recording success and `none` in failure. |
|
*/ |
|
public final static function TEST_ExpectNotNone(Object object) |
|
{ |
|
RecordTestResult(object != none); |
|
} |
|
|
|
// Records (in current context summary) that another test was performed and |
|
// succeeded/failed, along with given error message. |
|
private final static function RecordTestResult(bool isSuccessful) |
|
{ |
|
if (default.finishedTests) return; |
|
if (default.currentSummary == none) return; |
|
default.currentSummary.AddTestResult( default.currentContext, |
|
default.currentIssue, |
|
isSuccessful); |
|
} |
|
|
|
/** |
|
* Once testing has finished returns compiled results as a |
|
* `TestCaseSummary` object. |
|
* |
|
* @return `TestCaseSummary` with compiled results if the testing has finished |
|
* and `none` otherwise. |
|
*/ |
|
public final static function TestCaseSummary GetSummary() |
|
{ |
|
if (!default.finishedTests) { |
|
return none; |
|
} |
|
return default.currentSummary; |
|
} |
|
|
|
/** |
|
* Checks whether this `TestCase` has already finished running all it's tests. |
|
* Finished testing means a prepared `TestCaseSummary` is available |
|
* (by `GetSummary()` method). |
|
* |
|
* @return `true` if this test case already did the testing |
|
* and `false` otherwise. |
|
*/ |
|
public final static function bool HasFinishedTesting() |
|
{ |
|
return default.finishedTests; |
|
} |
|
|
|
/** |
|
* Returns name of this `TestCase`. |
|
* |
|
* @return Name of this `TestCase`. |
|
*/ |
|
public final static function string GetName() |
|
{ |
|
return default.caseName; |
|
} |
|
|
|
/** |
|
* Returns group name of this `TestCase`. |
|
* |
|
* @return Group name of this `TestCase`. |
|
*/ |
|
public final static function string GetGroup() |
|
{ |
|
return default.caseGroup; |
|
} |
|
|
|
// Calling this function will perform unit tests defined in `TESTS()` |
|
// function of this test case and will prepare the summary, |
|
// obtainable through `GetSummary()` function. |
|
// Returns `true` if all tests have successfully passed |
|
// and `false` otherwise. |
|
/** |
|
* Performs all tests for this `TestCase`. |
|
* Guaranteed to be done after this finishes. |
|
* |
|
* @return `true` if all tests have finished successfully |
|
* and `false` otherwise. |
|
*/ |
|
public final static function bool PerformTests() |
|
{ |
|
default.finishedTests = false; |
|
_().memory.Free(default.currentSummary); |
|
default.currentSummary = new class'TestCaseSummary'; |
|
default.currentSummary.Initialize(default.class); |
|
TESTS(); |
|
default.finishedTests = true; |
|
return default.currentSummary.HasPassedAllTests(); |
|
} |
|
|
|
/** |
|
* Any tests that your `TestCase` class needs to perform should be put in |
|
* this function. |
|
* To separate tests into groups it's recommended (as a style |
|
* consideration) to put them in separate function calls and give these |
|
* functions names starting with "Test_". They can have further folded |
|
* functions with prefix "SubTest_", which can contain "SubSubTest_", etc.. |
|
*/ |
|
protected static function TESTS(){} |
|
|
|
defaultproperties |
|
{ |
|
caseName = "" |
|
caseGroup = "" |
|
} |