Skip to content

Commit

Permalink
Address the review
Browse files Browse the repository at this point in the history
  • Loading branch information
Thevakumar-Luheerathan committed Feb 21, 2024
1 parent bdf516d commit cce17ee
Show file tree
Hide file tree
Showing 57 changed files with 574 additions and 465 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,52 @@ scope = "testOnly"

[[package]]
org = "ballerina"
name = "lang.error"
name = "lang.__internal"
version = "0.0.0"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "lang.object"}
]

[[package]]
org = "ballerina"
name = "lang.runtime"
name = "lang.array"
version = "0.0.0"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "lang.__internal"}
]

[[package]]
org = "ballerina"
name = "lang.error"
version = "0.0.0"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]

[[package]]
org = "ballerina"
name = "lang.object"
version = "0.0.0"
scope = "testOnly"

[[package]]
org = "ballerina"
name = "test"
version = "0.0.0"
scope = "testOnly"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "lang.error"},
{org = "ballerina", name = "lang.runtime"}
{org = "ballerina", name = "lang.array"},
{org = "ballerina", name = "lang.error"}
]
modules = [
{org = "ballerina", packageName = "test", moduleName = "test"}
{org = "ballerina", packageName = "test", moduleName = "test"},
{org = "ballerina", packageName = "test", moduleName = "test.test"}
]

[[package]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,13 @@ isolated function hasTest(string name) returns boolean {
int? testIndex = testOptions.getFilterTestIndex(testName);
if testIndex == () {
foreach string filter in testOptions.getFilterTests() {
if (filter.includes(WILDCARD)) {
if filter.includes(WILDCARD) {
boolean|error wildCardMatch = matchWildcard(testName, filter);
return (wildCardMatch is boolean && wildCardMatch && matchModuleName(filter));
}
}
return false;
} else if (matchModuleName(testName)) {
} else if matchModuleName(testName) {
return true;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,142 +14,150 @@
// specific language governing permissions and limitations
// under the License.

isolated function executeTestIso(TestFunction testFunction, DataProviderReturnType? testFunctionArgs) {
isolated function executeTestIsolated(TestFunction testFunction, DataProviderReturnType? testFunctionArgs) {
if !isTestReadyToExecute(testFunction, testFunctionArgs) {
return;
}
executeBeforeGroupFunctionsIso(testFunction);
executeBeforeEachFunctionsIso();
executeBeforeGroupFunctionsIsolated(testFunction);
executeBeforeEachFunctionsIsolated();
boolean shouldSkipDependents = false;
if !isSkipFunction(testFunction) {
if (isDataDrivenTest(testFunctionArgs)) {
executeDataDrivenTestSetIso(testFunction, testFunctionArgs);
if isDataDrivenTest(testFunctionArgs) {
executeDataDrivenTestSetIsolated(testFunction, testFunctionArgs);
} else {
shouldSkipDependents = executeNonDataDrivenTestIso(testFunction, testFunctionArgs);
shouldSkipDependents = executeNonDataDrivenTestIsolated(testFunction, testFunctionArgs);
}
} else {
reportData.onSkipped(name = testFunction.name, testType = getTestType(testFunctionArgs));
shouldSkipDependents = true;
}
testFunction.groups.forEach('group => groupStatusRegistry.incrementExecutedTest('group));
executeAfterEachFunctionsIso();
executeAfterGroupFunctionsIso(testFunction);
executeAfterEachFunctionsIsolated();
executeAfterGroupFunctionsIsolated(testFunction);
finishTestExecution(testFunction, shouldSkipDependents);
}

isolated function executeBeforeGroupFunctionsIso(TestFunction testFunction) {
isolated function executeBeforeGroupFunctionsIsolated(TestFunction testFunction) {
foreach string 'group in testFunction.groups {
TestFunction[]? beforeGroupFunctions = beforeGroupsRegistry.getFunctions('group);
if beforeGroupFunctions != () && !groupStatusRegistry.firstExecuted('group) {
handleBeforeGroupOutput(testFunction, 'group, executeFunctionsIso(beforeGroupFunctions, getShouldSkip()));
handleBeforeGroupOutput(testFunction, 'group, executeFunctionsIsolated(beforeGroupFunctions, getShouldSkip()));
}
}
}

isolated function executeBeforeEachFunctionsIso() =>
handleBeforeEachOutput(executeFunctionsIso(beforeEachRegistry.getFunctions(), getShouldSkip()));
isolated function executeBeforeEachFunctionsIsolated() =>
handleBeforeEachOutput(executeFunctionsIsolated(beforeEachRegistry.getFunctions(), getShouldSkip()));

isolated function executeDataDrivenTestSetIso(TestFunction testFunction, DataProviderReturnType? testFunctionArgs) {
isolated function executeDataDrivenTestSetIsolated(TestFunction testFunction, DataProviderReturnType? testFunctionArgs) {
string[] keys = [];
AnyOrError[][] values = [];
TestType testType = prepareDataSet(testFunctionArgs, keys, values);
map<future> futuresMap = {};
while keys.length() != 0 {
string key = keys.remove(0);
final readonly & readonly[] readOnlyVal = from any|error item in values.remove(0)
AnyOrError[] value = values.remove(0);
final readonly & readonly[] readOnlyVal = from any|error item in value
where item is readonly
select item;
future<()> futureResult = start prepareDataDrivenTestIso(testFunction, key, readOnlyVal, testType);
if readOnlyVal.length() != value.length() {
reportData.onFailed(name = testFunction.name, suffix = key, message = string `[fail data provider for the function ${testFunction.name}]${"\n"} Data provider returned non-readonly values`, testType = testType);
println(string `${"\n"}${testFunction.name}:${key} has failed.${"\n"}`);
enableExit();
}
future<()> futureResult = start prepareDataDrivenTestIsolated(testFunction, key, readOnlyVal, testType);
futuresMap[key] = futureResult;
}
foreach [string, future<any|error>] futureResult in futuresMap.entries() {
string suffix = futureResult[0];
any|error parallelDataProviderResult = wait futureResult[1];
if parallelDataProviderResult is error {
reportData.onFailed(name = testFunction.name, suffix = suffix, message = "[fail data provider for the function " + testFunction.name
+ "]\n" + getErrorMessage(parallelDataProviderResult), testType = testType);
reportData.onFailed(name = testFunction.name, suffix = suffix, message = string `[fail data provider for the function ${testFunction.name}]${"\n"} ${getErrorMessage(parallelDataProviderResult)}`, testType = testType);
println(string `${"\n"}${testFunction.name}:${suffix} has failed.${"\n"}`);
enableExit();
}
}
}

isolated function executeNonDataDrivenTestIso(TestFunction testFunction, DataProviderReturnType? testFunctionArgs) returns boolean {
if executeBeforeFunctionIso(testFunction) {
isolated function executeNonDataDrivenTestIsolated(TestFunction testFunction, DataProviderReturnType? testFunctionArgs) returns boolean {
if executeBeforeFunctionIsolated(testFunction) {
conMgr.setSkip(testFunction.name);
reportData.onSkipped(name = testFunction.name, testType = getTestType(testFunctionArgs));
return true;
}
boolean failed = handleNonDataDrivenTestOutput(testFunction, executeTestFunctionIso(testFunction, "", GENERAL_TEST));
if executeAfterFunctionIso(testFunction) {
boolean failed = handleNonDataDrivenTestOutput(testFunction, executeTestFunctionIsolated(testFunction, "", GENERAL_TEST));
if executeAfterFunctionIsolated(testFunction) {
return true;
}
return failed;
}

isolated function executeAfterEachFunctionsIso() =>
handleAfterEachOutput(executeFunctionsIso(afterEachRegistry.getFunctions(), getShouldSkip()));
isolated function executeAfterEachFunctionsIsolated() =>
handleAfterEachOutput(executeFunctionsIsolated(afterEachRegistry.getFunctions(), getShouldSkip()));

isolated function executeAfterGroupFunctionsIso(TestFunction testFunction) {
isolated function executeAfterGroupFunctionsIsolated(TestFunction testFunction) {
foreach string 'group in testFunction.groups {
TestFunction[]? afterGroupFunctions = afterGroupsRegistry.getFunctions('group);
if afterGroupFunctions != () && groupStatusRegistry.lastExecuted('group) {
ExecutionError? err = executeFunctionsIso(afterGroupFunctions,
ExecutionError? err = executeFunctionsIsolated(afterGroupFunctions,
getShouldSkip() || groupStatusRegistry.getSkipAfterGroup('group));
handleAfterGroupOutput(err);
}
}
}

isolated function executeFunctionsIso(TestFunction[] testFunctions, boolean skip = false) returns ExecutionError? {
isolated function executeFunctionsIsolated(TestFunction[] testFunctions, boolean skip = false) returns ExecutionError? {
foreach TestFunction testFunction in testFunctions {
if !skip || testFunction.alwaysRun {
check executeFunctionIso(testFunction);
check executeFunctionIsolated(testFunction);
}
}
}

isolated function prepareDataDrivenTestIso(TestFunction testFunction, string key, AnyOrError[] value, TestType testType) {
if executeBeforeFunctionIso(testFunction) {
isolated function prepareDataDrivenTestIsolated(TestFunction testFunction, string key, AnyOrError[] value, TestType testType) {
if executeBeforeFunctionIsolated(testFunction) {
reportData.onSkipped(name = testFunction.name, testType = testType);
} else {
executeDataDrivenTestIso(testFunction, key, testType, value);
var _ = executeAfterFunctionIso(testFunction);
executeDataDrivenTestIsolated(testFunction, key, testType, value);
_ = executeAfterFunctionIsolated(testFunction);
}
}

isolated function executeDataDrivenTestIso(TestFunction testFunction, string suffix, TestType testType, AnyOrError[] params) {
if (skipDataDrivenTest(testFunction, suffix, testType)) {
isolated function executeDataDrivenTestIsolated(TestFunction testFunction, string suffix, TestType testType, AnyOrError[] params) {
if skipDataDrivenTest(testFunction, suffix, testType) {
return;
}
ExecutionError|boolean err = executeTestFunctionIso(testFunction, suffix, testType, params);
ExecutionError|boolean err = executeTestFunctionIsolated(testFunction, suffix, testType, params);
handleDataDrivenTestOutput(err, testFunction, suffix, testType);
}

isolated function executeBeforeFunctionIso(TestFunction testFunction) returns boolean {
isolated function executeBeforeFunctionIsolated(TestFunction testFunction) returns boolean {
boolean failed = false;
if isBeforeFuncConditionMet(testFunction) {
failed = handleBeforeFunctionOutput(executeFunctionIso(<function>testFunction.before));
failed = handleBeforeFunctionOutput(executeFunctionIsolated(<function>testFunction.before));
}
return failed;
}

isolated function executeTestFunctionIso(TestFunction testFunction, string suffix, TestType testType, AnyOrError[]? params = ()) returns ExecutionError|boolean {
any|error output = params == () ? trap function:call(<isolated function>testFunction.executableFunction)
: trap function:call(<isolated function>testFunction.executableFunction, ...params);
isolated function executeTestFunctionIsolated(TestFunction testFunction, string suffix, TestType testType, AnyOrError[]? params = ()) returns ExecutionError|boolean {
isolated function isolatedTestFunction = <isolated function>testFunction.executableFunction;
any|error output = params == () ? trap function:call(isolatedTestFunction)
: trap function:call(isolatedTestFunction, ...params);
return handleTestFuncOutput(output, testFunction, suffix, testType);
}

isolated function executeAfterFunctionIso(TestFunction testFunction) returns boolean {
isolated function executeAfterFunctionIsolated(TestFunction testFunction) returns boolean {
boolean failed = false;
if isAfterFuncConditionMet(testFunction) {
failed = handleAfterFunctionOutput(executeFunctionIso(<function>testFunction.after));
failed = handleAfterFunctionOutput(executeFunctionIsolated(<function>testFunction.after));
}
return failed;
}

isolated function executeFunctionIso(TestFunction|function testFunction) returns ExecutionError? {
any|error output = trap function:call(<isolated function>(testFunction is function ? testFunction : testFunction.executableFunction));
isolated function executeFunctionIsolated(TestFunction|function testFunction) returns ExecutionError? {
isolated function isolatedTestFunction = <isolated function>(testFunction is function ? testFunction : testFunction.executableFunction);
// casting is done outside the function to avoid the error of casting inside the function and trapping it.
any|error output = trap function:call(isolatedTestFunction);
if output is error {
enableExit();
return error(getErrorMessage(output), functionName = testFunction is function ? "" : testFunction.name);
Expand Down
Loading

0 comments on commit cce17ee

Please sign in to comment.