2020-04-27 12:01:47 +02:00
|
|
|
' Gambas module file
|
2019-11-15 22:33:54 +01:00
|
|
|
|
|
|
|
Export
|
|
|
|
|
2020-04-27 12:01:47 +02:00
|
|
|
Property Read Printer As TapPrinter
|
|
|
|
Property Output As Stream
|
|
|
|
Property Read Session As TapContext
|
|
|
|
Property Read Finished As Boolean
|
|
|
|
Property _Next As TestAssertion
|
|
|
|
|
|
|
|
Private $hPrinter As New TapPrinter
|
|
|
|
Private $hNext As TestAssertion
|
|
|
|
|
2020-02-24 17:59:14 +01:00
|
|
|
|
2020-04-07 16:48:46 +02:00
|
|
|
''' The static procedure Test.Main() starts test(s).
|
2019-11-15 22:33:54 +01:00
|
|
|
|
|
|
|
'' Runs all tests in all testcontainers and prints the result to the console.
|
2020-04-07 16:48:46 +02:00
|
|
|
'' With Test.Main(NameTestModule) the tests can be restricted to only those of a single test module.
|
|
|
|
'' With Test.Main(NameTestModule, NameProcedure) only a single test can be accomplished.
|
2019-11-15 22:33:54 +01:00
|
|
|
|
2020-04-25 05:22:10 +02:00
|
|
|
Public Sub Main(Optional Tests As String)
|
2019-11-15 22:33:54 +01:00
|
|
|
|
2020-04-27 12:01:47 +02:00
|
|
|
Test.Reset() ' only if you run this Main multiple times per process, which you shouldn't
|
2020-04-25 05:22:10 +02:00
|
|
|
RunTests(Tests)
|
|
|
|
PrintSummary()
|
2019-11-15 22:33:54 +01:00
|
|
|
|
|
|
|
End
|
|
|
|
|
2020-02-24 17:59:14 +01:00
|
|
|
Private Sub PrintSummary()
|
|
|
|
|
2020-04-25 11:38:52 +02:00
|
|
|
'needed for debugging, to doubleclick on it
|
|
|
|
Dim Session As TapContext
|
|
|
|
|
2020-04-27 12:01:47 +02:00
|
|
|
Session = Test.Session
|
2020-04-25 11:38:52 +02:00
|
|
|
With Session
|
2020-04-27 12:01:47 +02:00
|
|
|
Test.Print(gb.Lf) ' better readability for humans
|
|
|
|
Test.Note(Subst$(("&2 - ran: '&1' "), .Summary.Description, IIf(.Summary.Success, "PASSED", "FAILED")))
|
|
|
|
If .TestsRun <> .Plan Then Test.Note(Subst$(("Planned &1 tests but ran &2"), .Plan, .TestsRun))
|
2020-05-01 15:57:53 +02:00
|
|
|
Test.Note(gb.Lf)
|
|
|
|
|
|
|
|
If Not .Summary.Success Then ShowTestCollection(("&1 tests failed:"), FindFailures(.Summary.Subtests, ""))
|
|
|
|
ShowTestCollection(("&1 tests skipped:"), FindSkips(.Summary.Subtests, ""))
|
|
|
|
ShowTestCollection(("&1 tests todo:"), FindTodos(.Summary.Subtests, ""))
|
|
|
|
ShowTestCollection(("&1 tests bonus:"), FindBonus(.Summary.Subtests, ""))
|
2020-02-24 17:59:14 +01:00
|
|
|
End With
|
2019-11-15 22:33:54 +01:00
|
|
|
|
|
|
|
End
|
|
|
|
|
2020-05-01 15:57:53 +02:00
|
|
|
'' Prints a Collection[] of tests as returned by FindFailures, FindSkips, FindTodos.
|
|
|
|
'' _Description_ can contain '&1' which is substituted for _TestCollection_.Count.
|
|
|
|
Private Sub ShowTestCollection(Description As String, TestCollection As Collection[])
|
|
|
|
|
|
|
|
Dim cTest As Collection
|
|
|
|
|
|
|
|
If TestCollection.Count Then
|
|
|
|
Test.Note(Subst$(Description, TestCollection.Count))
|
|
|
|
For Each cTest In TestCollection
|
|
|
|
Dim hTest As TestAssertion = cTest!Assertion
|
|
|
|
Test.Note(Subst$(("&2: &1 -- &3 &4"), cTest["Path"], hTest.Id, hTest.Description, IIf(hTest.Comment, "# " & hTest.Comment, "")))
|
|
|
|
Next
|
|
|
|
Test.Note(gb.Lf)
|
|
|
|
Endif
|
|
|
|
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Function FindFailures(Tests As TestAssertion[], Prefix As String) As Collection[]
|
2020-04-25 05:22:10 +02:00
|
|
|
|
|
|
|
Dim hTest As TestAssertion
|
|
|
|
Dim sName As String
|
2020-05-01 15:57:53 +02:00
|
|
|
Dim aRet As New Collection[]
|
2020-04-25 05:22:10 +02:00
|
|
|
|
|
|
|
For Each hTest In Tests
|
|
|
|
sName = Prefix &/ hTest.Description
|
|
|
|
' Only show the deepest subtests that caused failures.
|
2020-05-01 15:57:53 +02:00
|
|
|
If Not hTest.Success And If Not hTest.Subtests.Count Then aRet.Add(["Path": Prefix, "Assertion": hTest])
|
|
|
|
aRet.Insert(FindFailures(hTest.Subtests, sName))
|
|
|
|
Next
|
|
|
|
Return aRet
|
|
|
|
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Function FindSkips(Tests As TestAssertion[], Prefix As String) As Collection[]
|
|
|
|
|
|
|
|
Dim hTest As TestAssertion
|
|
|
|
Dim sName As String
|
|
|
|
Dim aRet As New Collection[]
|
|
|
|
|
|
|
|
For Each hTest In Tests
|
|
|
|
sName = Prefix &/ hTest.Description
|
|
|
|
If hTest.Directive = Tap.SKIP Then aRet.Add(["Path": Prefix, "Assertion": hTest])
|
|
|
|
aRet.Insert(FindSkips(hTest.Subtests, sName))
|
|
|
|
Next
|
|
|
|
Return aRet
|
|
|
|
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Function FindTodos(Tests As TestAssertion[], Prefix As String) As Collection[]
|
|
|
|
|
|
|
|
Dim hTest As TestAssertion
|
|
|
|
Dim sName As String
|
|
|
|
Dim aRet As New Collection[]
|
|
|
|
|
|
|
|
For Each hTest In Tests
|
|
|
|
sName = Prefix &/ hTest.Description
|
|
|
|
If hTest.Directive = Tap.TODO And If Not hTest.Ok Then aRet.Add(["Path": Prefix, "Assertion": hTest])
|
|
|
|
aRet.Insert(FindTodos(hTest.Subtests, sName))
|
|
|
|
Next
|
|
|
|
Return aRet
|
|
|
|
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Function FindBonus(Tests As TestAssertion[], Prefix As String) As Collection[]
|
|
|
|
|
|
|
|
Dim hTest As TestAssertion
|
|
|
|
Dim sName As String
|
|
|
|
Dim aRet As New Collection[]
|
|
|
|
|
|
|
|
For Each hTest In Tests
|
|
|
|
sName = Prefix &/ hTest.Description
|
|
|
|
If hTest.Directive = Tap.TODO And If hTest.Ok Then aRet.Add(["Path": Prefix, "Assertion": hTest])
|
|
|
|
aRet.Insert(FindBonus(hTest.Subtests, sName))
|
2020-04-25 05:22:10 +02:00
|
|
|
Next
|
2020-05-01 15:57:53 +02:00
|
|
|
Return aRet
|
2020-04-25 05:22:10 +02:00
|
|
|
|
|
|
|
End
|
|
|
|
|
2019-11-15 22:33:54 +01:00
|
|
|
'' Run all tests, optional limited by Container or TestCaseName. Track contains .
|
|
|
|
|
2020-04-25 05:22:10 +02:00
|
|
|
Private Function RunTests(Tests As String)
|
2019-11-15 22:33:54 +01:00
|
|
|
|
2020-04-08 12:39:55 +02:00
|
|
|
Dim aTestCommands As TestCommand[]
|
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-04-08 12:39:55 +02:00
|
|
|
aTestCommands = TestCommand.ParseCommands(Tests)
|
|
|
|
|
|
|
|
For Each sTestModule In GetAllTestModules(aTestCommands)
|
2020-02-23 12:38:53 +01:00
|
|
|
TestModule = Class.Load(sTestModule)
|
2020-04-08 12:39:55 +02:00
|
|
|
Suite.AddAllTestCases(TestModule, aTestCommands)
|
2019-11-15 22:33:54 +01:00
|
|
|
Next
|
|
|
|
|
2020-04-27 12:01:47 +02:00
|
|
|
Test.Session.Summary.Description = Tests
|
2020-04-25 05:22:10 +02:00
|
|
|
Suite.Run()
|
2020-04-27 12:01:47 +02:00
|
|
|
If Not Test.Finished Then Test.Finish()
|
2020-02-27 20:28:49 +01:00
|
|
|
|
2019-11-15 22:33:54 +01:00
|
|
|
End
|
|
|
|
|
2020-04-08 12:39:55 +02:00
|
|
|
Function GetAllTestModules(Commands As TestCommand[]) 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-04-08 12:39:55 +02:00
|
|
|
Dim Command As TestCommand
|
2019-11-15 22:33:54 +01:00
|
|
|
|
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
|
2020-04-25 11:38:52 +02:00
|
|
|
|
2019-11-15 22:33:54 +01:00
|
|
|
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))
|
|
|
|
If TestModuleNames.Exist(sName) Then Continue
|
2020-04-08 12:39:55 +02:00
|
|
|
If Commands.Count = 0 Then
|
|
|
|
'Add every Testmodule
|
2020-02-23 12:38:53 +01:00
|
|
|
TestModuleNames.Add(sName)
|
2020-04-07 15:03:13 +02:00
|
|
|
Else
|
2020-04-25 11:38:52 +02:00
|
|
|
'Add only testmodules whose names exist in Commands
|
2020-04-08 12:39:55 +02:00
|
|
|
For Each Command In Commands
|
2020-04-26 11:23:01 +02:00
|
|
|
If Not sNames.Exist(Command.ModuleName) Then
|
2020-04-27 12:01:47 +02:00
|
|
|
Test.BailOut(Subst$(("There is no test called &1."), Command.ModuleName))
|
2020-04-26 11:23:01 +02:00
|
|
|
Endif
|
2020-04-08 12:39:55 +02:00
|
|
|
If Lower(Command.ModuleName) = Lower(sName) Then
|
|
|
|
TestModuleNames.Add(sName)
|
|
|
|
Endif
|
|
|
|
Next
|
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
|
2020-04-25 11:38:52 +02:00
|
|
|
|
2020-02-23 12:38:53 +01:00
|
|
|
Return TestModuleNames
|
2019-11-15 22:33:54 +01:00
|
|
|
|
2020-01-04 14:48:51 +01:00
|
|
|
Catch
|
2020-04-27 12:01:47 +02:00
|
|
|
Test.BailOut("Error in " & Error.Where & ": " & Error.Text)
|
|
|
|
|
|
|
|
End
|
|
|
|
|
|
|
|
' ------------------------------------------------- Test controls
|
|
|
|
|
|
|
|
Public Sub BailOut(Optional Comment As String)
|
|
|
|
$hPrinter.BailOut(Comment)
|
2020-02-27 20:28:49 +01:00
|
|
|
Quit 1
|
2020-04-27 12:01:47 +02:00
|
|
|
End
|
|
|
|
'' Synonym for Note
|
|
|
|
Public Sub Diagnostic(Comment As String)
|
|
|
|
$hPrinter.Diagnostic(Comment)
|
|
|
|
End
|
|
|
|
'' Synonym for Diagnostic
|
|
|
|
Public Sub Note(Comment As String)
|
|
|
|
$hPrinter.Note(Comment)
|
|
|
|
End
|
|
|
|
|
|
|
|
Public Sub Print({Line} As String)
|
|
|
|
$hPrinter.Print({Line})
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Function Printer_Read() As TapPrinter
|
|
|
|
Return $hPrinter
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Function Output_Read() As Stream
|
|
|
|
Return $hPrinter.Output
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Sub Output_Write(Value As Stream)
|
|
|
|
$hPrinter.Output = Value
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Function Session_Read() As TapContext
|
|
|
|
Return $hPrinter.Session
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Function Finished_Read() As Boolean
|
|
|
|
Return $hPrinter.Session.Finished
|
|
|
|
End
|
|
|
|
|
|
|
|
Public Sub Reset()
|
|
|
|
$hPrinter = New TapPrinter As "Printer"
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Function _Next_Read() As TestAssertion
|
|
|
|
|
|
|
|
If $hNext = Null Then
|
|
|
|
$hNext = New TestAssertion
|
|
|
|
Endif
|
|
|
|
|
|
|
|
Return $hNext
|
|
|
|
|
|
|
|
End
|
|
|
|
|
|
|
|
Private Sub _Next_Write(Value As TestAssertion)
|
|
|
|
|
|
|
|
$hNext = Value
|
2019-12-30 22:10:37 +01:00
|
|
|
|
2019-11-15 22:33:54 +01:00
|
|
|
End
|
2020-04-27 12:01:47 +02:00
|
|
|
|
|
|
|
|
|
|
|
Public Sub Subtest(Description As String, Optional Tests As Integer, Optional Comment As String)
|
|
|
|
Test.Printer.Subtest(Description, Tests, Comment)
|
|
|
|
End
|
|
|
|
|
|
|
|
Public Sub Plan(Tests As Integer, Optional Comment As String)
|
|
|
|
Test.Printer.Plan(Tests, Comment)
|
|
|
|
End
|
|
|
|
|
|
|
|
Public Sub SkipAll(Optional Comment As String)
|
|
|
|
Test.Printer.SkipAll(Comment)
|
|
|
|
End
|
|
|
|
|
|
|
|
Public Sub Finish()
|
|
|
|
Test.Printer.Finish()
|
|
|
|
End
|
|
|
|
|