gambas-source-code/comp/src/gb.test/.src/Assert.class

403 lines
8.6 KiB
Text
Raw Normal View History

' Gambas class file
''' Assertions which print TAP.
Export
Create Static
Public Struct Subtest
Printer As TapPrinter
Description As String
Indent As Integer
Success As Boolean
' Directive to apply to the next "ok" line
Directive As Integer
Comment As String
End Struct
Property Output As Stream
Property Read SubtestLevel As Integer
Property Read Finished As Boolean
Private $aActiveTests As Subtest[]
Private $hCurrent As New Subtest
Private $hOutput As Stream
Public Sub _new()
Reset()
End
Public Sub Reset()
$aActiveTests = New Subtest[]
$hOutput = File.Out
With $hCurrent = New Subtest
.Printer = New TapPrinter As "Printer"
.Indent = 0
.Success = True
.Directive = Tap.NONE
End With
End
Public Sub Setup(Optional Tests As Integer, Optional Comment As String, Optional {Output} As Stream)
If IsMissing({Output}) Then {Output} = $hOutput
$hCurrent.Printer.Output = {Output}
Plan(Tests, Comment)
End
Public Sub Subtest(Description As String, Optional Tests As Integer)
Dim iIndent As Integer = $hCurrent.Indent
Dim hOutput As Stream = $hCurrent.Printer.Output
$aActiveTests.Push($hCurrent)
With $hCurrent = New Subtest
.Printer = New TapPrinter As "Printer"
.Printer.Output = hOutput
.Description = Description
.Indent = iIndent + 1
.Success = True
.Directive = Tap.NONE
End With
If Tests Then Plan(Tests)
End
Public Sub Finish()
Dim hFinished As Subtest
With $hCurrent
.Printer.Finish()
.Success = .Success And (.Printer.SkippedAll Or (.Printer.Planned > 0 And .Printer.Count = .Printer.Planned))
End With
hFinished = $hCurrent
Try $hCurrent = $aActiveTests.Pop()
If Not Error Then
$hCurrent.Printer.Test(hFinished.Success,, hFinished.Description)
Endif
End
Public Sub Printer_Filter()
Last.Line = String$($hCurrent.Indent, "\t") & Last.Line
End
Public Sub Plan(Tests As Integer, Optional Comment As String)
$hCurrent.Printer.Plan(Tests, Comment)
End
Public Sub SkipAll(Optional Comment As String)
$hCurrent.Printer.SkipAll(Comment)
End
Public Sub Ok(Result As Boolean, Optional Description As String) As Boolean
With $hCurrent
If .Directive <> Tap.NONE Then
.Printer.Test(Result,, Description, .Directive, .Comment)
Else
.Printer.Test(Result,, Description)
.Success = .Success And Result
Endif
.Directive = Tap.NONE
.Comment = Null
End With
Return Result
End
Public Sub Todo(Optional Comment As String)
$hCurrent.Directive = Tap.TODO
$hCurrent.Comment = Comment
End
Public Sub Skip(Optional Comment As String)
$hCurrent.Directive = Tap.SKIP
$hCurrent.Comment = Comment
Pass()
End
'' Unwinds the subtest stack. BailOut will always bail out of all the
'' subtests, for example.
Private Sub Unwind()
While $hCurrent.Indent > 0
Note("Unwinding subtest stack!")
Finish()
Wend
End
Public Sub BailOut(Optional Comment As String)
Unwind()
$hCurrent.Printer.BailOut(Comment)
$hCurrent.Success = False
End
Public Sub Diagnostic(Comment As String)
$hCurrent.Printer.Diagnostic(Comment)
End
Public Sub Note(Comment As String)
Diagnostic(Comment)
End
Public Sub Print({Line} As String)
$hCurrent.Printer.Print({Line})
End
Private Function Output_Read() As Stream
Return $hOutput
End
Private Sub Output_Write(Value As Stream)
$hOutput = Value
$hCurrent.Printer.Output = Value
End
Private Function SubtestLevel_Read() As Integer
Return $hCurrent.Indent
End
Private Function Finished_Read() As Boolean
Return $hCurrent.Printer.Finished
End
' -------------------- High-level test functions --------------------
Public Sub Pass(Optional Description As String) As Boolean
Return Ok(True, Description)
End
Public Sub Fail(Optional Description As String) As Boolean
Return Ok(False, Description)
End
Public Sub NotOk(Result As Boolean, Optional Description As String) As Boolean
Return Ok(Not Result, Description)
End
Public Sub Equals(Got As Variant, Expected As Variant, Optional Description As String) As Boolean
Dim bRes As Boolean
bRes = Ok(Got = Expected, Description)
If Not bRes Then
Note(Subst$((" Got: &1"), Got))
Note(Subst$((" Expected: &1"), Expected))
Endif
Return bRes
End
Public Sub NotEquals(Got As Variant, UnExpected As Variant, Optional Description As String) As Boolean
Return Ok(Got <> UnExpected, Description)
End
Public Sub LessEqual(Got As Variant, Bound As Variant, Optional Description As String) As Boolean
Dim bRes As Boolean
bRes = Ok(Got <= Bound, Description)
If Not bRes Then
Note(Subst$((" Got: &1"), Got))
Note(Subst$((" Expected: <= &1"), Bound))
Endif
Return bRes
End
Public Sub Less(Got As Variant, Bound As Variant, Optional Description As String) As Boolean
Dim bRes As Boolean
bRes = Ok(Got < Bound, Description)
If Not bRes Then
Note(Subst$((" Got: &1"), Got))
Note(Subst$((" Expected: < &1"), Bound))
Endif
Return bRes
End
Public Sub GreaterEqual(Got As Variant, Bound As Variant, Optional Description As String) As Boolean
Dim bRes As Boolean
bRes = Ok(Got >= Bound, Description)
If Not bRes Then
Note(Subst$((" Got: &1"), Got))
Note(Subst$((" Expected: >= &1"), Bound))
Endif
Return bRes
End
Public Sub Greater(Got As Variant, Bound As Variant, Optional Description As String) As Boolean
Dim bRes As Boolean
bRes = Ok(Got > Bound, Description)
If Not bRes Then
Note(Subst$((" Got: &1"), Got))
Note(Subst$((" Expected: > &1"), Bound))
Endif
Return bRes
End
Public Sub Approximate(Got As Float, Expected As Float, Precision As Float, Optional Description As String) As Boolean
Return LessEqual(Abs(Got - Expected), Precision, Description)
End
Public Sub RelativeApproximate(Got As Float, Expected As Float, RelPrecision As Float, Optional Description As String) As Boolean
Return LessEqual(Abs((Got - Expected) / Expected), RelPrecision, Description)
End
Public Sub IsType(Got As Variant, Type As Integer, Optional Description As String) As Boolean
Return Equals(TypeOf(Got), Type, Description)
End
Public Sub Null(Got As Variant, Optional Description As String) As Boolean
Return Equals(Got, Null, Description)
End
Public Sub NotNull(Got As Variant, Optional Description As String) As Boolean
Return NotEquals(Got, Null, Description)
End
Public Sub Like(Got As String, Pattern As String, Optional Description As String) As Boolean
Dim bRes As Boolean
bRes = Ok(Got Like Pattern, Description)
If Not bRes Then
Note(Subst$((" Got: &1"), Got))
Note(Subst$((" Expected: &1"), Pattern))
Endif
Return bRes
End
Public Sub Match(Got As String, Pattern As String, Optional Description As String) As Boolean
Dim bRes As Boolean
bRes = Ok(Got Match Pattern, Description)
If Not bRes Then
Note(Subst$((" Got: &1"), Got))
Note(Subst$((" Expected: &1"), Pattern))
Endif
Return bRes
End
Public Sub StringEquals(Got As String, Expected As String, Optional Description As String) As Boolean
Dim bRes As Boolean
Dim iPos As Integer
bRes = Equals(Got, Expected, Description)
If Not bRes Then
If Len(Got) <> Len(Expected) Then
Note(Subst$(("Strings are of different lengths &1 and &2, respectively."), Len(Got), Len(Expected)))
Endif
For iPos = 1 To Min(Len(Got), Len(Expected))
If Mid$(Got, iPos, 1) <> Mid$(Expected, iPos, 1) Then Break
Next
Note(Subst$(("Strings differ at position &1."), iPos))
Endif
Return bRes
End
Public Sub Error(Optional Description As String) As Boolean
Return Ok( Error , Description)
End
Public Sub ErrorCode(Code As Integer, Optional Description As String) As Boolean
Dim bRes As Boolean
If Not Error Then
bRes = Fail(Description)
Note(("No error happened"))
Else
bRes = Equals(Error.Code, Code)
If Not bRes Then
Note(Subst$(("Error was: &1 (code: &2) at &3"), Error.Text, Error.Code, Error.Where))
Endif
Endif
Error.Clear()
Return bRes
End
Public Sub NotError(Optional Description As String) As Boolean
Dim bRes As Boolean
bRes = Ok(Not Error , Description)
If Not bRes Then
Note(Subst$(("Error was: &1 (code: &2) at &3"), Error.Text, Error.Code, Error.Where))
Endif
Error.Clear()
Return bRes
End