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.
294 lines
8.4 KiB
294 lines
8.4 KiB
4 years ago
|
/**
|
||
|
* Class for storing and processing the information about how well testing
|
||
|
* against a certain issue went.
|
||
|
* 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 IssueSummary extends AcediaObject;
|
||
|
|
||
|
// Each issue is uniquely identified by these values.
|
||
|
var private class<TestCase> ownerCase;
|
||
|
var private string context;
|
||
|
var private string description;
|
||
|
|
||
|
// Records, in chronological order, results of the tests that were
|
||
|
// run to test this issue.
|
||
|
var private array<byte> successRecords;
|
||
|
|
||
|
private final function byte BoolToByte(bool boolToConvert)
|
||
|
{
|
||
|
if (boolToConvert) return 1;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets `TestCase`, context and description for the issue,
|
||
|
* tracked in this summary.
|
||
|
*
|
||
|
* Can only be successfully called once, but will fail if passed a `none`
|
||
|
* class reference to `TestCase`.
|
||
|
*
|
||
|
* @param targetCase `TestCase`, in which issue,
|
||
|
* relevant to this summary, is defined.
|
||
|
* @param targetContext Context, in which this issue,
|
||
|
* relevant to this summary, is defined.
|
||
|
* @param targetDescription Description of the issue relevant to
|
||
|
* this summary.
|
||
|
* @return `true` if `TestCase`, context and description were successfully set,
|
||
|
* `false` otherwise.
|
||
|
*/
|
||
|
public final function bool SetIssue(
|
||
|
class<TestCase> targetCase,
|
||
|
string targetContext,
|
||
|
string targetDescription
|
||
|
)
|
||
|
{
|
||
|
if (ownerCase != none) return false;
|
||
|
if (targetCase == none) return false;
|
||
|
ownerCase = targetCase;
|
||
|
context = targetContext;
|
||
|
description = targetDescription;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns context for the issue in question.
|
||
|
*
|
||
|
* `TestCase` can be important for both displaying information about testing to
|
||
|
* the user and distinguishing between two different issues with the same
|
||
|
* description and context.
|
||
|
* @see `TestCase` for more information.
|
||
|
*
|
||
|
* @return Test case that tested for relevant issue.
|
||
|
*/
|
||
|
public final function class<TestCase> GetTestCase()
|
||
|
{
|
||
|
return ownerCase;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns context for the issue in question.
|
||
|
*
|
||
|
* Context can be important for both displaying information about testing to
|
||
|
* the user and distinguishing between two different issues with
|
||
|
* the same description and in the same `TestCase`.
|
||
|
* @see `TestCase` for more information.
|
||
|
*
|
||
|
* @return Context for relevant issue.
|
||
|
*/
|
||
|
public final function string GetContext()
|
||
|
{
|
||
|
if (ownerCase == none) return "";
|
||
|
return context;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns description for the issue in question.
|
||
|
*
|
||
|
* Description of an issue is the main way to distinguish between
|
||
|
* different possibly arising problems.
|
||
|
* Two different issues can have the same description if they are defined
|
||
|
* in different `TestCase`s and/or in different context.
|
||
|
* @see `TestCase` for more information.
|
||
|
*
|
||
|
* @return Description for the issue in question.
|
||
|
*/
|
||
|
public final function string GetDescription()
|
||
|
{
|
||
|
if (ownerCase == none) return "";
|
||
|
return description;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds result of another test (success or not) to the records of this summary.
|
||
|
*
|
||
|
* @param success `true` if test was successful and had passed,
|
||
|
* `false` otherwise.
|
||
|
*/
|
||
|
public final function AddTestResult(bool success)
|
||
|
{
|
||
|
successRecords[successRecords.length] = BoolToByte(success);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns total amount of test results recorded in caller summary.
|
||
|
* Never a negative value.
|
||
|
*
|
||
|
* @return Amount of tests that were run.
|
||
|
*/
|
||
|
public final function int GetTotalTestsAmount()
|
||
|
{
|
||
|
return successRecords.length;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns total amount of recorded successful test results in caller summary.
|
||
|
* Never a negative value.
|
||
|
*
|
||
|
* @return Amount of recorded successfully performed tests for
|
||
|
* the relevant issue.
|
||
|
*/
|
||
|
public final function int GetSuccessfulTestsAmount()
|
||
|
{
|
||
|
local int i;
|
||
|
local int counter;
|
||
|
counter = 0;
|
||
|
for (i = 0; i < successRecords.length; i += 1)
|
||
|
{
|
||
|
if (successRecords[i] > 0) {
|
||
|
counter += 1;
|
||
|
}
|
||
|
}
|
||
|
return counter;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns total amount of recorded failed test results in caller summary.
|
||
|
* Never a negative value.
|
||
|
*
|
||
|
* @return Amount of recorded failed tests for the relevant issue.
|
||
|
*/
|
||
|
public final function int GetFailedTestsAmount()
|
||
|
{
|
||
|
return GetTotalTestsAmount() - GetSuccessfulTestsAmount();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns total success rate ("amount of successes" / "total amount of tests")
|
||
|
* of recorded test results for relevant issue
|
||
|
* (value between 0 and 1, including boundaries).
|
||
|
*
|
||
|
* If there are no test results recorded - returns `-1`.
|
||
|
*
|
||
|
* @return Success rate of recorded test results for the relevant issue
|
||
|
* Returns values outside [0; 1] segment (specifically, negative values)
|
||
|
* iff no test results at all were recorded.
|
||
|
*/
|
||
|
public final function float GetSuccessRate()
|
||
|
{
|
||
|
local int totalTestsAmount;
|
||
|
totalTestsAmount = GetTotalTestsAmount();
|
||
|
if (totalTestsAmount <= 0) {
|
||
|
return -1;
|
||
|
}
|
||
|
return GetSuccessfulTestsAmount() / totalTestsAmount;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks whether all tests recorded in this summary have passed.
|
||
|
*
|
||
|
* @return `true` if all tests for relevant issue have passed,
|
||
|
* `false` otherwise.
|
||
|
*/
|
||
|
public final function bool HasPassedAllTests()
|
||
|
{
|
||
|
return (GetFailedTestsAmount() <= 0);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns boolean array of test results: each element recording whether test
|
||
|
* was a success (`>0`) or a failure (`0`).
|
||
|
*
|
||
|
* All results in the array are in a chronological order of arrival.
|
||
|
*
|
||
|
* @return Returns copy of boolean array of recorded test results.
|
||
|
*/
|
||
|
public final function array<byte> GetTestRecords()
|
||
|
{
|
||
|
return successRecords;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns index numbers (starting from 1, not 0) of tests that ended in
|
||
|
* a success, while performed for the same test case, context and issue.
|
||
|
* So if tests went: [success, success, failure, success, failure],
|
||
|
* method will return: [1, 2, 4].
|
||
|
*
|
||
|
* All results in the array are in a chronological order of arrival.
|
||
|
*
|
||
|
* @return index numbers of successful tests.
|
||
|
*/
|
||
|
public final function array<int> GetSuccessfulTests()
|
||
|
{
|
||
|
local int i;
|
||
|
local array<int> result;
|
||
|
for (i = 0; i < successRecords.length; i += 1)
|
||
|
{
|
||
|
if (successRecords[i] > 0) {
|
||
|
result[result.length] = i + 1;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns index numbers (starting from 1, not 0) of tests that ended in
|
||
|
* a failure, while performed for the same test case, context and issue.
|
||
|
* So if tests went: [success, success, failure, success, failure],
|
||
|
* method will return: [3, 5].
|
||
|
*
|
||
|
* All results in the array are in a chronological order of arrival.
|
||
|
*
|
||
|
* @return index numbers of successful tests.
|
||
|
*/
|
||
|
public final function array<int> GetFailedTests()
|
||
|
{
|
||
|
local int i;
|
||
|
local array<int> result;
|
||
|
for (i = 0; i < successRecords.length; i += 1)
|
||
|
{
|
||
|
if (successRecords[i] == 0) {
|
||
|
result[result.length] = i + 1;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a formatted text representation of the caller `IssueSummary`
|
||
|
* in a following format:
|
||
|
* "{$text_default <issue_description>} {$text_subtle [<failed_test_numbers>]}"
|
||
|
*
|
||
|
* @return Formatted string with text representation of the
|
||
|
* caller `IssueSummary`.
|
||
|
*/
|
||
|
public final function string ToString()
|
||
|
{
|
||
|
local int i;
|
||
|
local string result;
|
||
|
local array<int> failedTests;
|
||
|
result = "{$text_default" @ GetDescription() $ "}";
|
||
|
if (GetFailedTestsAmount() <= 0) {
|
||
|
return result;
|
||
|
}
|
||
|
result @= "{$text_subtle [";
|
||
|
failedTests = GetFailedTests();
|
||
|
for (i = 0; i < failedTests.length; i += 1)
|
||
|
{
|
||
|
if (i < failedTests.length - 1) {
|
||
|
result $= string(failedTests[i]) $ ", ";
|
||
|
}
|
||
|
else {
|
||
|
result $= string(failedTests[i]);
|
||
|
}
|
||
|
}
|
||
|
return (result $ "]");
|
||
|
}
|
||
|
|
||
|
defaultproperties
|
||
|
{
|
||
|
}
|