gb.test: Subtest support for Assert

[GB.TEST]
* OPT: TapPrinter: use the Print method everywhere
* NEW: Add the TapPrinter_Filter event
* NEW: Assert: add subtest support
This commit is contained in:
Tobias Boege 2018-06-09 22:42:27 +02:00
parent 5e171d5a1c
commit 0c151bc812
3 changed files with 124 additions and 48 deletions

View file

@ -1,76 +1,124 @@
' Gambas module file
' Gambas class file
''' Assertions which print TAP.
Export
Create Static
Public Struct Directive
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
Private $hPrinter As New TapPrinter
Private $aDirectives As New Directive[]
Private $aActiveTests As New Subtest[]
Private $hCurrent As New Subtest
Public Sub Setup(Optional Tests As Integer, Optional Comment As String, Optional {Output} As Stream = File.Out)
Public Sub _new()
$hPrinter = New TapPrinter(Tests, Comment, {Output})
With $hCurrent = New Subtest
.Printer = New TapPrinter As "Printer"
.Indent = 0
.Success = True
.Directive = Tap.NONE
End With
End
Public Sub Plan(Tests As Integer, Optional Comment As String)
Public Sub Setup(Optional Tests As Integer, Optional Comment As String, Optional {Output} As Stream)
$hPrinter.Plan(Tests, Comment)
If IsMissing({Output}) Then
{Output} = $hCurrent.Printer.Output
If Not {Output} Then {Output} = File.Out
Endif
$hCurrent.Printer.Output = {Output}
Plan(Tests, Comment)
End
Public Sub Subtest(Description As String)
Dim iIndent As Integer = $hCurrent.Indent
$aActiveTests.Push($hCurrent)
With $hCurrent = New Subtest
.Printer = New TapPrinter As "Printer"
.Description = Description
.Indent = iIndent + 1
.Success = True
.Directive = Tap.NONE
End With
End
Public Sub Finish()
$hPrinter.Finish()
Dim hFinished As Subtest
$hCurrent.Printer.Finish()
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 Ok(Result As Boolean, Optional Description As String) As Boolean
Dim hDir As Directive
If $aDirectives.Count Then
hDir = $aDirectives.Pop()
$hPrinter.Test(Result,, Description, hDir.Directive, hDir.Comment)
Else
$hPrinter.Test(Result,, Description)
Endif
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)
Dim hDir As New Directive
hDir.Directive = Tap.TODO
hDir.Comment = Comment
$aDirectives.Push(hDir)
$hCurrent.Directive = Tap.TODO
$hCurrent.Comment = Comment
End
Public Sub Skip(Optional Comment As String)
Dim hDir As New Directive
hDir.Directive = Tap.SKIP
hDir.Comment = Comment
$aDirectives.Push(hDir)
$hCurrent.Directive = Tap.SKIP
$hCurrent.Comment = Comment
End
Public Sub Diagnostic(Comment As String)
$hPrinter.Diagnostic(Comment)
$hCurrent.Printer.Diagnostic(Comment)
End
Public Sub Print({Line} As String)
$hPrinter.Print({Line})
$hCurrent.Printer.Print({Line})
End

View file

@ -2,4 +2,8 @@
Export
' Plan
Public Const NO_PLAN As Integer = -1
' Directives
Public Enum NONE = 0, TODO = 1, SKIP

View file

@ -6,21 +6,28 @@
Export
Private Const NO_PLAN As Integer = -1
Private $hOutput As Stream
Private $iPlan As Integer = NO_PLAN
Private $iTestsRun As Integer = 0
Private $iLast As Integer = 0
Event Filter
Property {Output} As Stream
Property Read Planned As Integer
Property Read Count As Integer
Property Read Last As Integer
Property Line As String
Private $hOutput As Stream
Private $iPlan As Integer
Private $iTestsRun As Integer
Private $iLast As Integer
Private $bFinished As Boolean
Private $sLine As String
Public Sub _new(Optional Tests As Integer, Optional Comment As String, Optional {Output} As Stream = File.Out)
$hOutput = {Output}
$iPlan = Tap.NO_PLAN
$iTestsRun = 0
$iLast = 0
$bFinished = False
If Not IsMissing(Tests) Then Plan(Tests, Comment)
End
@ -30,26 +37,26 @@ Public Sub Plan(Tests As Integer, Optional Comment As String)
If $iTestsRun Then Error.Raise(Subst$(("Tests already started, at test #&1"), $iTestsRun))
' TAP specification lists '1..0 # Skipped: WWW::Mechanize not installed'
' as a valid example.
If Tests <= NO_PLAN Then Error.Raise(("Number of tests must be non-negative"))
If Tests <= Tap.NO_PLAN Then Error.Raise(("Number of tests must be non-negative"))
$iPlan = Tests
Print #$hOutput, "1.."; $iPlan;
Print #$hOutput, IIf(Comment, " # " & Comment, "")
Flush #$hOutput
Print(Subst$("1..&1&2", $iPlan, IIf(Comment, " # " & Comment, "")))
End
Public Sub Finish()
If $iPlan > NO_PLAN Then Return ' already printed the "plan" line
If $iPlan > Tap.NO_PLAN Then Return ' already printed the "plan" line
If $bFinished Then Error.Raise(("Tests already finished"))
$iPlan = $iTestsRun
Print #$hOutput, "1.."; $iPlan
Flush #$hOutput
Print("1.." & $iPlan)
$bFinished = True
End
Public Sub Test(Result As Boolean, Optional TestNr As Integer, Optional Description As String, Optional Directive As Integer, Optional Comment As String)
Dim sDirective As String
Dim sLine As String
' It is not advised to start a description with a number token because
' it will be interpreted as the (optional) test number. We issue a warning
@ -65,35 +72,40 @@ Public Sub Test(Result As Boolean, Optional TestNr As Integer, Optional Descript
Inc $iTestsRun
If Not TestNr Then TestNr = $iTestsRun
$iLast = TestNr
sLine = Subst$("&1 &2 - &3", IIf(Result, "ok", "not ok"), TestNr, Description)
If Not IsMissing(Directive) Then
' Matches the values of the Enum Tap.Todo, Tap.Skip
sDirective = Choose(Directive, "TODO", "SKIP")
If Not sDirective Then Error.Raise(Subst$(("Unsupported directive '&1'"), Directive))
sLine &= " # " & sDirective
If Comment Then sLine &= " " & Comment
Endif
Print #$hOutput, Subst$("&1 &2 - &3", IIf(Result, "ok", "not ok"), TestNr, Description);
Print #$hOutput, IIf(sDirective, Subst$(" # &1&2", sDirective, IIf(Comment, " " & Comment, "")), "")
Flush #$hOutput
Print(sLine)
End
Public Sub BailOut(Optional Comment As String)
Print #$hOutput, "Bail out!";; Comment
Flush #$hOutput
Print("Bail out!" & IIf(Comment, " " & Comment, ""))
End
Public Sub Diagnostic(Comment As String)
Print #$hOutput, "#";; Comment
Flush #$hOutput
Print("# " & Comment)
End
Public Sub Print({Line} As String)
Print #$hOutput, {Line}
Dim bCancel As Boolean
$sLine = {Line}
bCancel = Raise Filter
If bCancel Then Return
Print #$hOutput, $sLine
Flush #$hOutput
End
@ -127,3 +139,15 @@ Private Function Last_Read() As Integer
Return $iLast
End
Private Function Line_Read() As String
Return $sLine
End
Private Sub Line_Write(Value As String)
$sLine = Value
End