Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.2.0] - Unreleased

### Added
- #42: Added a listener interface and manager with an associated user parameter, allowing the user to broadcast output on test method/case/suite completion.

## [3.1.1] - 2024-07-31

Expand Down
8 changes: 8 additions & 0 deletions cls/TestCoverage/Listeners/ListenerInterface.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Class TestCoverage.Listeners.ListenerInterface Extends %RegisteredObject
{

Method Broadcast(pMessage As %DynamicObject) As %Status [ Abstract ]
{
}

}
48 changes: 48 additions & 0 deletions cls/TestCoverage/Listeners/ListenerManager.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Class TestCoverage.Listeners.ListenerManager Extends %RegisteredObject
{

Property listeners As list Of TestCoverage.Listeners.ListenerInterface;

Method BroadCastToAll(pMessage As %DynamicObject) As %Status
{
set tSC = $$$OK
try {
for i = 1:1:..listeners.Count() {
set tListener = ..listeners.GetAt(i)
$$$ThrowOnError(tListener.Broadcast(pMessage))
}
}
catch e {
Set tSC = e.AsStatus()
}
quit tSC
}

Method AddListener(pListener As TestCoverage.Listeners.ListenerInterface) As %Status
{
set tSC = $$$OK
try {
do ..listeners.Insert(pListener)
} catch e {
set tSC = e.AsStatus()
}
quit tSC
}

Method RemoveListener(pListener As TestCoverage.Listeners.ListenerInterface) As %Status
{
set tSC = $$$OK
try {
set tIndex = ..listeners.FindOref(pListener)
if (tIndex = "") {
Set tMsg = "Listener not found"
$$$ThrowStatus($$$ERROR($$$GeneralError,tMsg))
}
do ..listeners.RemoveAt(tIndex)
} catch e {
set tSC = e.AsStatus()
}
quit tSC
}

}
51 changes: 51 additions & 0 deletions cls/TestCoverage/Manager.cls
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ Property Hashes [ MultiDimensional ];

Property Monitor As TestCoverage.Utils.LineByLineMonitor [ InitialExpression = {##class(TestCoverage.Utils.LineByLineMonitor).%New()}, Private ];

/// keeps track of all the listeners that may need information broadcasted about the unit test progress
Property ListenerManager As TestCoverage.Listeners.ListenerManager;

/// Runs unit tests that have been loaded, with code coverage enabled. <br />
/// Note that if coverage is to be tracked for lots of code, it may be necessary to increase the "gmheap" setting
/// (under Configuration - Additional Settings - Advanced Memory in the Management Portal). <br />
Expand Down Expand Up @@ -563,6 +566,7 @@ ClassMethod OnBeforeAllTests(manager As TestCoverage.Manager, dir As %String, By
Set tCoverageRoutines = $Get(userparam("CoverageRoutines"))
Set tCoverageDetail = $Get(userparam("CoverageDetail"))
Set tSourceNamespace = $Get(userparam("SourceNamespace"),$Namespace)
Set tListenerManager = $Get(userparam("ListenerManager"))
Set tProcessIDs = $Get(userparam("ProcessIDs"),$ListBuild($Job))
If (tProcessIDs = "*") {
Set tProcessIDs = ""
Expand All @@ -584,6 +588,7 @@ ClassMethod OnBeforeAllTests(manager As TestCoverage.Manager, dir As %String, By
Set manager.ProcessIDs = tProcessIDs
Set manager.Timing = tTiming
Do manager.SetCoverageTargets(tCoverageClasses,tCoverageRoutines,1)
Set manager.ListenerManager = tListenerManager
If (tCoverageDetail '= "") {
If (tCoverageDetail '= +tCoverageDetail) {
// If we were passed a display value...
Expand Down Expand Up @@ -619,6 +624,10 @@ ClassMethod OnBeforeAllTests(manager As TestCoverage.Manager, dir As %String, By
}

If (manager.CoverageDetail = 0) {
if (manager.ListenerManager) {
set tObj = {"message": "Starting tests"}
Do manager.ListenerManager.BroadCastToAll(tObj)
}
Set tSC = manager.StartCoverageTracking()
$$$ThrowOnError(tSC)
}
Expand All @@ -637,6 +646,10 @@ ClassMethod OnAfterAllTests(manager As TestCoverage.Manager, dir As %String, ByR
Try {
If (manager.CoverageDetail = 0) {
Set tSC = manager.EndCoverageTracking()
if (manager.ListenerManager) {
set tObj = {"message": "All tests complete"}
Do manager.ListenerManager.BroadCastToAll(tObj)
}
}
Do manager.Monitor.Stop()
} Catch e {
Expand Down Expand Up @@ -673,9 +686,15 @@ Method OnBeforeTestSuite(dir As %String, suite As %String, testspec As %String,
Set ..CurrentTestSuite = $Case(suite,"":"(root)",:suite)
Set ..CurrentTestClass = ""
Set ..CurrentTestMethod = ""
if (..ListenerManager) {
set tObj = {"message": "Starting test suite: "}
do tObj.%Set("suite", suite)
Do ..ListenerManager.BroadCastToAll(tObj)
}
If (..CoverageDetail = 1) {
Set tSC = ..StartCoverageTracking()
}

} Catch e {
Set tSC = e.AsStatus()
}
Expand All @@ -688,9 +707,15 @@ Method OnAfterTestSuite(dir As %String, suite As %String, testspec As %String, B
{
Set tSC = $$$OK
Try {

If (..CoverageDetail = 1) {
Set tSC = ..EndCoverageTracking($Case(suite,"":"(root)",:suite))
}
if (..ListenerManager) {
set tObj = {"message": "Finished test suite: "}
do tObj.%Set("suite", suite)
Do ..ListenerManager.BroadCastToAll(tObj)
}
} Catch e {
Set tSC = e.AsStatus()
}
Expand All @@ -705,6 +730,12 @@ Method OnBeforeTestCase(suite As %String, class As %String) As %Status
Try {
Set ..CurrentTestClass = class
Set ..CurrentTestMethod = ""
if (..ListenerManager) {
set tObj = {"message": "Starting test case: "}
do tObj.%Set("suite", suite)
do tObj.%Set("class", class)
Do ..ListenerManager.BroadCastToAll(tObj)
}
If (..CoverageDetail = 2) {
Set tSC = ..StartCoverageTracking()
}
Expand All @@ -723,6 +754,12 @@ Method OnAfterTestCase(suite As %String, class As %String) As %Status
If (..CoverageDetail = 2) {
Set tSC = ..EndCoverageTracking(suite, class)
}
if (..ListenerManager) {
set tObj = {"message": "Finished test case: "}
do tObj.%Set("suite", suite)
do tObj.%Set("class", class)
Do ..ListenerManager.BroadCastToAll(tObj)
}
} Catch e {
Set tSC = e.AsStatus()
}
Expand All @@ -736,6 +773,13 @@ Method OnBeforeOneTest(suite As %String, class As %String, method As %String) As
Set tSC = $$$OK
Try {
Set ..CurrentTestMethod = method
if (..ListenerManager) {
set tObj = {"message": "Starting test method: "}
do tObj.%Set("suite", suite)
do tObj.%Set("class", class)
do tObj.%Set("method", method)
Do ..ListenerManager.BroadCastToAll(tObj)
}
If (..CoverageDetail = 3) {
Set tSC = ..StartCoverageTracking()
}
Expand All @@ -754,6 +798,13 @@ Method OnAfterOneTest(suite As %String, class As %String, method As %String) As
If (..CoverageDetail = 3) {
Set tSC = ..EndCoverageTracking(suite, class, method)
}
if (..ListenerManager) {
set tObj = {"message": "Finished test method: "}
do tObj.%Set("suite", suite)
do tObj.%Set("class", class)
do tObj.%Set("method", method)
Do ..ListenerManager.BroadCastToAll(tObj)
}
} Catch e {
Set tSC = e.AsStatus()
}
Expand Down
Loading