/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* This source file is part of the Cangjie project, licensed under Apache-2.0
* with Runtime Library Exception.
*
* See https://cangjie-lang.cn/pages/LICENSE for license information.
*/
// The Cangjie API is in Beta. For details on its capabilities and limitations, please refer to the README file.
package std.unittest
import std.unittest.diff.AssertPrintable
import std.unittest.common.*
/**
* Checks two values for equality and will throw an exception if the check fails.
*
* @param leftStr string representation of expected.
* @param rightStr string representation of actual.
* @param expected expected value.
* @param actual actual value.
* @param optParentCtx context where fail message is stored
* @throws AssertException If <expected> and <actual> are not equal.
*/
public func assertEqual<T>(
leftStr: String,
rightStr: String,
expected: T,
actual: T,
optParentCtx!: ?AssertionCtx = None
): Unit where T <: Equatable<T> {
assertEqual(leftStr, rightStr, expected, actual, isDelta: false, optParentCtx: optParentCtx)
}
/**
* Checks two values for equality and will throw an exception if the check fails.
*
* @param leftStr string representation of expected.
* @param rightStr string representation of actual.
* @param expected expected value.
* @param actual actual value.
* @param isDelta is delta comparison
* @param optParentCtx context where fail message is stored
* @throws AssertException If <expected> and <actual> are not equal.
*/
public func assertEqual<T>(
leftStr: String,
rightStr: String,
expected: T,
actual: T,
isDelta!: Bool,
optParentCtx!: ?AssertionCtx = None
): Unit where T <: Equatable<T> {
cancellationPoint()
if (let Some(parentCtx) <- optParentCtx) {
if (expected != actual) {
let cr = buildCheckResult(leftStr, rightStr, expected, actual, Assert, isDelta: isDelta)
parentCtx._errors.add(Leaf(cr))
throw AssertException("", cr)
}
} else {
if (expected != actual) {
let cr = buildCheckResult(leftStr, rightStr, expected, actual, Assert, isDelta: isDelta)
Framework.withCurrentContext{ ctx => ctx.checkFailed(cr) }
throw AssertException("", cr)
} else {
Framework.withCurrentContext{ ctx => ctx.checkPassed() }
}
}
}
/**
* Same as assertEqual but will not throw an exception immediately.
*
* @param leftStr string representation of expected.
* @param rightStr string representation of actual.
* @param expected expected value.
* @param actual actual value.
* @param optParentCtx context where fail message is stored
*/
public func expectEqual<T>(
leftStr: String,
rightStr: String,
expected: T,
actual: T,
optParentCtx!: ?AssertionCtx = None
): Unit where T <: Equatable<T> {
expectEqual(leftStr, rightStr, expected, actual, isDelta: false, optParentCtx: optParentCtx)
}
/**
* Same as assertEqual but will not throw an exception immediately.
*
* @param leftStr string representation of expected.
* @param rightStr string representation of actual.
* @param expected expected value.
* @param actual actual value.
* @param isDelta is delta comparison
* @param optParentCtx context where fail message is stored
*/
public func expectEqual<T>(
leftStr: String,
rightStr: String,
expected: T,
actual: T,
isDelta!: Bool,
optParentCtx!: ?AssertionCtx = None
): Unit where T <: Equatable<T> {
cancellationPoint()
if (let Some(parentCtx) <- optParentCtx) {
if (expected != actual) {
let cr = buildCheckResult(leftStr, rightStr, expected, actual, Expect, isDelta: isDelta)
parentCtx._errors.add(Leaf(cr))
}
} else {
if (expected != actual) {
let cr = buildCheckResult(leftStr, rightStr, expected, actual, Expect, isDelta: isDelta)
Framework.withCurrentContext{ ctx => ctx.checkFailed(cr) }
} else {
Framework.withCurrentContext{ ctx => ctx.checkPassed() }
}
}
}
func buildCheckResult<T>(
leftStr: String,
rightStr: String,
expected: T,
actual: T,
checkResultKind: CheckResultKind,
isDelta!: Bool = false
): AssertExpectCheckResult {
match (expected) {
case te: AssertPrintable<T> =>
let message = PrettyText()
te.pprintForAssertion(message, actual, leftStr, rightStr, 1)
DiffCheckResult(checkResultKind, message)
case _ =>
if (isDelta) {
PlainDeltaCompareCheckResult(checkResultKind, leftStr)
} else {
PlainCompareCheckResult(
checkResultKind, leftStr, rightStr, toStringOrPlaceholder(expected), toStringOrPlaceholder(actual)
)
}
}
}