Permissive module

The Permissive module of the Assert package supplies assertions that compare values as if the comparison had been written directly in twinBASIC code, with case-insensitive string comparison. Object default members are evaluated. Permissive ignores case differences in strings — for example, when asserting that an error message contains a particular phrase regardless of capitalisation — and uses the same default-member rules as = for object comparison.

Comparison semantics

The four equality assertions in this module — AreEqual, AreNotEqual, SequenceEquals, and NotSequenceEquals — apply the rules listed below. The remaining assertions are unaffected.

  • String comparisons are case-insensitive (regardless of the project’s Option Compare setting).
  • All other comparisons are evaluated as if the operands had been written either side of = in twinBASIC code — numeric promotions apply (5 equals 5.0), vbNullString and "" are both empty strings, and object comparison retrieves and compares default members where they exist.
  • Null is never equal to anything, not even to itself — use IsNull / IsNotNull to test for it.
' All pass under Permissive:
Permissive.AreEqual "Hello", "hello" ' case-insensitive
Permissive.AreEqual 5, 5.0           ' twinBASIC promotes 5 to 5.0
Permissive.AreEqual vbNullString, "" ' both empty strings

Diagnostic outcome

Succeed

Records that the test reached this point without failure.

Syntax: Permissive.Succeed

A test procedure that returns without any assertion having failed is reported as passing implicitly, so calling Succeed explicitly is rarely necessary. It is occasionally useful in branches that would otherwise look ambiguous about their outcome — for example, the body of a loop that should reach the end.

Fail

Unconditionally records a test failure.

Syntax: Permissive.Fail [ Message ]

Message
optional A String describing the failure, recorded together with the source location of the call.

Fail marks code paths that should be unreachable in a passing test — most often after a call that is expected to raise an error, in a branch that runs when the call returned normally instead.

On Error Resume Next
target.SomethingThatShouldRaise
If Err.Number = 0 Then Permissive.Fail "expected an error, got success"

Inconclusive

Records the test as inconclusive — neither a pass nor a failure.

Syntax: Permissive.Inconclusive [ Message ]

Message
optional A String describing why the result is inconclusive.

Inconclusive records that a precondition for the test could not be established and the assertion logic that follows would be meaningless. A common case is a setup step that failed to find a required external resource — a test database, a configured network endpoint — where the test itself is neither passing nor failing on its own merits.

Equality

AreEqual

Asserts that Actual is equal to Expected.

Syntax: Permissive.AreEqual Expected, Actual [, Message ]

Expected
required A Variant holding the expected value.
Actual
required A Variant holding the value produced by the code under test.
Message
optional A String included in the failure record if the comparison fails.

The comparison follows this module’s comparison semantics — strings are compared case-insensitively, object comparison reads default members where they exist, and everything else uses normal twinBASIC equality (so numeric promotions apply and vbNullString matches ""). If either operand is Null, the assertion fails — Null is never equal to anything; use IsNull to test for Null explicitly.

Permissive.AreEqual 42, result          ' passes if result equals 42 (numeric promotion applies)
Permissive.AreEqual "Hello", greeting   ' passes if greeting equals "hello", "HELLO", etc.

' These all pass under Permissive (would fail under Exact or Strict):
Permissive.AreEqual "Hello", "hello"    ' case-insensitive string comparison
Permissive.AreEqual 5, 5.0             ' numeric promotion makes them equal
Permissive.AreEqual "", vbNullString   ' both treated as the empty string

AreNotEqual

Asserts that Actual is not equal to Expected.

Syntax: Permissive.AreNotEqual Expected, Actual [, Message ]

Expected
required A Variant holding a value that Actual must differ from.
Actual
required A Variant holding the value produced by the code under test.
Message
optional A String included in the failure record if the values are equal.

Comparison uses this module’s comparison semantics — strings are compared case-insensitively, object comparison reads default members where they exist, and numeric promotions apply. If either operand is Null, the assertion passes — Null is never equal to anything.

Permissive.AreNotEqual "Hello", "world"  ' passes — different strings
Permissive.AreNotEqual 5, 6              ' passes — different numeric values
Permissive.AreNotEqual "Hello", "hello"  ' fails — Permissive is case-insensitive
Permissive.AreNotEqual 5, 5.0            ' fails — numeric promotion makes them equal

AreSame

Asserts that Actual and Expected refer to the same object — equivalent to Expected Is Actual.

Syntax: Permissive.AreSame Expected, Actual [, Message ]

Expected
required A Variant holding the expected object reference.
Actual
required A Variant holding the reference produced by the code under test.
Message
optional A String included in the failure record if the references differ.

Reference identity is independent of the module’s other comparison rules — AreSame always uses the Is operator, never default-member equality. To compare values rather than references, use AreEqual.

AreNotSame

Asserts that Actual and Expected refer to different objects — equivalent to Expected IsNot Actual.

Syntax: Permissive.AreNotSame Expected, Actual [, Message ]

Expected
required A Variant holding a reference that Actual must differ from.
Actual
required A Variant holding the reference produced by the code under test.
Message
optional A String included in the failure record if the references are the same.

Reference identity is independent of the module’s other comparison rules — AreNotSame always uses the IsNot operator, never default-member equality. To compare values rather than references, use AreNotEqual.

Dim a As New Collection
Dim b As New Collection
Permissive.AreNotSame a, b   ' passes — a and b are distinct object instances
Permissive.AreNotSame a, a   ' fails — same reference

Boolean

IsTrue

Asserts that Condition evaluates to True.

Syntax: Permissive.IsTrue Condition [, Message ]

Condition
required A Variant holding the condition to test. The value is interpreted as a Boolean — zero is False, any non-zero value is True.
Message
optional A String included in the failure record if the condition is False.

If Condition is Null, the assertion fails.

IsFalse

Asserts that Condition evaluates to False.

Syntax: Permissive.IsFalse Condition [, Message ]

Condition
required A Variant holding the condition to test. Zero is False, any non-zero value is True.
Message
optional A String included in the failure record if the condition is True.

If Condition is Null, the assertion fails — Null is neither True nor False.

Reference and value state

IsNothing

Asserts that Value is the Nothing object reference.

Syntax: Permissive.IsNothing Value [, Message ]

Value
required A Variant holding the object reference to test.
Message
optional A String included in the failure record if Value refers to an object.

This is the object-reference test, equivalent to Value Is Nothing. To check for the Null value of a Variant instead, use IsNull.

IsNotNothing

Asserts that Value refers to an object — i.e. is not the Nothing reference.

Syntax: Permissive.IsNotNothing Value [, Message ]

Value
required A Variant holding the object reference to test.
Message
optional A String included in the failure record if Value is Nothing.

This is the object-reference test, equivalent to Not (Value Is Nothing). To check that a Variant does not hold the Null value instead, use IsNotNull.

Dim col As Collection
Set col = New Collection

Permissive.IsNotNothing col    ' passes — col refers to a Collection object
Set col = Nothing
Permissive.IsNotNothing col    ' fails — col is Nothing

IsNull

Asserts that Value is the Null value of a Variant.

Syntax: Permissive.IsNull Value [, Message ]

Value
required A Variant holding the value to test.
Message
optional A String included in the failure record if Value is not Null.

Equivalent to checking IsNull(Value) = True. Because Null is never equal to anything — not even to itself — the equality assertions (AreEqual, AreNotEqual) cannot be used to test for Null; this assertion exists specifically for that purpose. To check for the Nothing object reference instead, use IsNothing.

Dim rs As Object   ' assume this is a Recordset
' A field value may be Null when the database column contains no data:
Permissive.IsNull rs.Fields("MiddleName").Value

IsNotNull

Asserts that Value is not the Null value of a Variant.

Syntax: Permissive.IsNotNull Value [, Message ]

Value
required A Variant holding the value to test.
Message
optional A String included in the failure record if Value is Null.

Equivalent to checking IsNull(Value) = False. Because Null is never equal to anything — not even to itself — the equality assertions (AreEqual, AreNotEqual) cannot be used to confirm absence of Null; this assertion exists specifically for that purpose. To check that an object reference is not Nothing instead, use IsNotNothing.

Dim rs As Object   ' assume this is a Recordset
' Assert that a required field is not Null before reading it:
Permissive.IsNotNull rs.Fields("CustomerID").Value

Sequence

SequenceEquals

Asserts that Actual and Expected contain the same number of elements, in the same order, with each pair of elements equal under this module’s comparison semantics.

Syntax: Permissive.SequenceEquals Expected, Actual [, FailMessage ]

Expected
required A Variant holding an array, Collection, or other enumerable value.
Actual
required A Variant holding the sequence produced by the code under test.
FailMessage
optional A String included in the failure record if the sequences differ.

Both arguments must support iteration via For Each. The assertion fails on the first mismatched pair, on a length difference, or if one side is empty while the other is not. Element comparison uses the same per-pair rules as AreEqual, so string elements are compared case-insensitively while numbers compare under normal twinBASIC equality.

NotSequenceEquals

Asserts that Actual and Expected differ — they contain a different number of elements, or at least one pair of corresponding elements differs under this module’s comparison semantics.

Syntax: Permissive.NotSequenceEquals Expected, Actual [, FailMessage ]

Expected
required A Variant holding an array, Collection, or other enumerable value.
Actual
required A Variant holding the sequence produced by the code under test.
FailMessage
optional A String included in the failure record if the sequences are equal.

Both arguments must support iteration via For Each. The assertion passes when the sequences have a different number of elements, or when at least one pair of corresponding elements differs under this module’s comparison semantics — meaning string elements are compared case-insensitively and numbers follow normal twinBASIC equality. The inverse of SequenceEquals.

See Also

  • Exact – the strictest comparison flavour: datatypes must match and conversions never happen
  • Strict – like Permissive, but with case-sensitive string comparisons and reference-identity object equality
  • Assert package – overview of all three modules and the comparison-semantics table