' Gambas class file Export Create Static Private $hHarness As New TestHarness Private $bVerbose As Boolean ''' The static procedure Unittest.Main() starts test(s). '' Runs all tests in all testcontainers and prints the result to the console. '' 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. Public Sub Main(Optional NameTestModule As String, Optional NameProcedure As String, Optional Verbose As Boolean = True, Optional RawTap As Boolean = True) Assert.Reset() ' only if you run this Main multiple times per process, which you shouldn't $bVerbose = Verbose RunTests(NameTestModule, NameProcedure, RawTap) If Not RawTap Then PrintSummary() End 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 Print .Name;; IIf(.Success, "PASSED", "FAILED");; Print "("; "exit code";; .ExitCode; ",";; Print "runtime";; Format$(DateDiff(.Started, .Ended, gb.Second), "0.00s"); ")" If .Run <> .Planned Then Print "Planned";; .Planned;; "tests but ran";; .Run Endif 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 If .Bonus Then Print "Passed";; .Bonus;; "additional tests marked as TODO" Endif If .BailedOut Then Print "Bailed out with message";; .BailMessage Endif Print Print String$(80, "*") Print End With End ' '' Run all tests, optional limited by Container or TestCaseName. Track contains . Private Function RunTests(SingleTestModule As String, Optional NameProcedure As String, Optional RawTap As Boolean) Dim sTestModule As String Dim TestModule As Class Dim Suite As New TestSuite Dim hTapStream As Stream, sTap As String 'FIXME: If included as component then TestContainers can only be loaded if they contain the magic word Export For Each sTestModule In GetAllTestTestModules(SingleTestModule) TestModule = Class.Load(sTestModule) Suite.AddAllTestCases(TestModule, NameProcedure) Next ' 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 Suite.Run() Endif End Function GetAllTestTestModules(Optional SingleTestModule As String) As String[] Dim TestClass As Class Dim TestModuleNames As New String[] Dim sNames As New String[] Dim sName As String If Exist(".../.test") sNames = Split(File.Load(".../.test"), gb.Lf, Null, True) Endif Assert sNames sNames.Sort For Each sName In sNames TestClass = Class.Load(sName) If Not TestClass Then Error.Raise(Subst$(("Could not load test module '&1'"), sName)) 'sName = Class.Stat(sName).Name 'Atention: Class.Stat(sName).Name does not work if included as component 'Then this creates the error: 'Bail out! Error in Unittest->GetAllTestModuleNames: Unknown symbol 'Stat' in class 'Class' If TestModuleNames.Exist(sName) Then Continue If SingleTestModule = Null Then TestModuleNames.Add(sName) Else If Lower(sName) = Lower(SingleTestModule) Then TestModuleNames.Add(sName) Endif Endif Next TestModuleNames.Sort ' Print "# These TestContainer will be executed:\n#\n# " & TestModuleNames.Join("\n# ") & "\n" Return TestModuleNames Catch Assert.BailOut("Error in Unittest->GetAllTestModuleNames: " & Error.Text) Quit 1 End ' 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