2019-11-15 22:33:54 +01:00
' Gambas class file
Export
2020-02-24 17:59:14 +01:00
Create Static
Private $hHarness As New TestHarness
Private $bVerbose As Boolean
2019-11-15 22:33:54 +01:00
''' The static procedure Unittest.Main() starts test(s).
'' Runs all tests in all testcontainers and prints the result to the console.
2020-02-23 12:38:53 +01:00
'' With UnitTest.Main(NameTestModule) the tests can be restricted to only those of a single test module.
'' With UnitTest.Main(NameTestModule, NameProcedure) only a single test can be accomplished.
2019-11-15 22:33:54 +01:00
2020-04-07 15:03:13 +02:00
Public Sub Main(Optional NameTestModule As String, Optional NameProcedure As String, Optional Verbose As Boolean = True, Optional RawTap As Boolean = True)
2019-11-15 22:33:54 +01:00
2020-02-24 17:59:14 +01:00
Assert.Reset() ' only if you run this Main multiple times per process, which you shouldn't
$bVerbose = Verbose
2020-04-07 15:03:13 +02:00
RunTests(NameTestModule, NameProcedure, RawTap)
2020-02-27 20:28:49 +01:00
If Not RawTap Then PrintSummary()
2019-11-15 22:33:54 +01:00
End
2020-02-24 17:59:14 +01:00
Private Sub PrintSummary()
With $hHarness.Current
If $bVerbose Then
Dim sLine As String
Print "Transcript of the TAP stream:"
Print
For Each sLine In .Lines
Print sLine
Next
Print
Print String$(80, "*")
Print
Endif
2019-12-31 01:47:37 +01:00
2020-02-24 17:59:14 +01:00
Print .Name;; IIf(.Success, "PASSED", "FAILED");;
Print "("; "exit code";; .ExitCode; ",";;
Print "runtime";; Format$(DateDiff(.Started, .Ended, gb.Second), "0.00s"); ")"
2019-11-15 22:33:54 +01:00
2020-02-24 17:59:14 +01:00
If .Run <> .Planned Then
Print "Planned";; .Planned;; "tests but ran";; .Run
Endif
2019-11-15 22:33:54 +01:00
2020-02-24 17:59:14 +01:00
If .Failed > 0 Then
Dim iInd As Integer
Print "Failed";; .Failed;; "out of";; .Run;; "tests:";;
For iInd = 0 To .Failures.Max
Print .Failures[iInd];
If iInd < .Failures.Max Then Print ",";;
Next
Print
Endif
2019-11-15 22:33:54 +01:00
2020-02-24 17:59:14 +01:00
If .Bonus Then
Print "Passed";; .Bonus;; "additional tests marked as TODO"
Endif
2019-11-15 22:33:54 +01:00
2020-02-24 17:59:14 +01:00
If .BailedOut Then
Print "Bailed out with message";; .BailMessage
Endif
2019-11-15 22:33:54 +01:00
2020-02-24 17:59:14 +01:00
Print
Print String$(80, "*")
Print
2019-11-15 22:33:54 +01:00
2020-02-24 17:59:14 +01:00
End With
2019-11-15 22:33:54 +01:00
End
'
'' Run all tests, optional limited by Container or TestCaseName. Track contains .
2020-04-07 15:03:13 +02:00
Private Function RunTests(SingleTestModule As String, Optional NameProcedure As String, Optional RawTap As Boolean)
2019-11-15 22:33:54 +01:00
2020-02-23 12:38:53 +01:00
Dim sTestModule As String
Dim TestModule As Class
2019-11-15 22:33:54 +01:00
Dim Suite As New TestSuite
2020-02-24 17:59:14 +01:00
Dim hTapStream As Stream, sTap As String
2019-11-15 22:33:54 +01:00
'FIXME: If included as component then TestContainers can only be loaded if they contain the magic word Export
2020-04-07 15:03:13 +02:00
For Each sTestModule In GetAllTestTestModules(SingleTestModule)
2020-02-23 12:38:53 +01:00
TestModule = Class.Load(sTestModule)
Suite.AddAllTestCases(TestModule, NameProcedure)
2019-11-15 22:33:54 +01:00
Next
2020-02-27 20:28:49 +01:00
' FIXME: RawTap is hack that allows to see the TAP as it is produced.
' This is for tests which fail with an error and test gb.test's BailOut.
' Such tests are buffered to a string stream but before they can be echoed,
' the process dies.
If Not RawTap Then
' The TAP stream is produced in this process. We have to get it into the
' harness somehow. Since we don't start a new process, it is going to be
' done by a buffer.
hTapStream = Open String For Write
Assert.Output = hTapStream
Suite.Run()
sTap = Close #hTapStream
hTapStream = Open String sTap For Read
$hHarness.Read(hTapStream, Subst$("&1:&2", SingleTestModule, IIf(NameProcedure, NameProcedure, "*")))
Close #hTapStream
Else
2020-02-24 17:59:14 +01:00
Suite.Run()
2020-02-27 20:28:49 +01:00
Endif
2019-11-15 22:33:54 +01:00
End
2020-04-07 15:03:13 +02:00
Function GetAllTestTestModules(Optional SingleTestModule As String) As String[]
2019-11-15 22:33:54 +01:00
Dim TestClass As Class
2020-02-23 12:38:53 +01:00
Dim TestModuleNames As New String[]
2019-11-15 22:33:54 +01:00
Dim sNames As New String[]
Dim sName As String
2020-02-23 12:38:53 +01:00
If Exist(".../.test")
sNames = Split(File.Load(".../.test"), gb.Lf, Null, True)
Endif
2019-11-15 22:33:54 +01:00
Assert sNames
sNames.Sort
For Each sName In sNames
2020-04-07 15:03:13 +02:00
TestClass = Class.Load(sName)
If Not TestClass Then Error.Raise(Subst$(("Could not load test module '&1'"), sName))
2020-02-23 12:38:53 +01:00
2019-11-15 22:33:54 +01:00
'sName = Class.Stat(sName).Name
2020-02-23 12:38:53 +01:00
2020-01-22 09:13:41 +01:00
'Atention: Class.Stat(sName).Name does not work if included as component
2020-01-04 14:48:51 +01:00
'Then this creates the error:
2020-02-23 12:38:53 +01:00
'Bail out! Error in Unittest->GetAllTestModuleNames: Unknown symbol 'Stat' in class 'Class'
2020-01-04 14:48:51 +01:00
2020-04-07 15:03:13 +02:00
If TestModuleNames.Exist(sName) Then Continue
If SingleTestModule = Null Then
2020-02-23 12:38:53 +01:00
TestModuleNames.Add(sName)
2020-04-07 15:03:13 +02:00
Else
If Lower(sName) = Lower(SingleTestModule) Then
TestModuleNames.Add(sName)
Endif
2019-11-15 22:33:54 +01:00
Endif
2020-04-07 15:03:13 +02:00
Next
2019-11-15 22:33:54 +01:00
2020-02-23 12:38:53 +01:00
TestModuleNames.Sort
' Print "# These TestContainer will be executed:\n#\n# " & TestModuleNames.Join("\n# ") & "\n"
Return TestModuleNames
2019-11-15 22:33:54 +01:00
2020-01-04 14:48:51 +01:00
Catch
2020-02-27 20:28:49 +01:00
Assert.BailOut("Error in Unittest->GetAllTestModuleNames: " & Error.Text)
Quit 1
2019-12-30 22:10:37 +01:00
2019-11-15 22:33:54 +01:00
End
2020-02-23 12:38:53 +01:00
' Private Function CaseNames_Read() As String[]
'
' Return $CaseNames
'
' End
'
' '' Returns the classname of the TestContainer
' Private Function Name_Read() As String
'
' Return Object.Class(Me).Name
'
' End