Skip to content

Commit 5f6eceb

Browse files
committed
Fix dual responsibility of ResolveChildren()
1 parent dfdda46 commit 5f6eceb

4 files changed

Lines changed: 44 additions & 3 deletions

File tree

src/cls/IPM/ResourceProcessor/Test.cls

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,7 @@ Method OnResolveChildren(ByRef pResourceArray) As %Status
288288
set tResourceInfo("UnitTest") = 1
289289
set tResource = $case(..Package '= "", 1: ..Package, : ..Class)_..Extension
290290
// GetChildren has Output semantics — it kills its output array before populating it.
291-
// Using tClassArray (not pResourceArray directly) preserves any existing entries
292-
// in pResourceArray (e.g., the "/tests/" path entry added before this call).
291+
// Use tClassArray as the intermediate to avoid killing any existing entries in pResourceArray.
293292
kill tClassArray
294293
$$$ThrowOnError(##class(%IPM.Storage.ResourceReference).GetChildren(tResource,tModuleName,1,.tResourceInfo,.tClassArray))
295294
$$$ThrowOnError(..EmbeddedProcessor.OnResolveChildren(.tClassArray))

src/cls/IPM/Storage/Module.cls

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,11 @@ Method GetResolvedReferences(
13711371
kill tempArray("Scope")
13721372
if ..HasScope(pPhases, resourceScope) && ..HasScope(pPhases, attrScope) {
13731373
merge pReferenceArray(..Name) = tempArray
1374+
// ResolveChildren does not emit path entries for document enumeration. Re-add here
1375+
// because ExportSingleModule needs the path entry to trigger its directory-copy branch.
1376+
if $extract(tResource.Name) = "/" {
1377+
set pReferenceArray(..Name, tResource.Name) = ..Name
1378+
}
13741379
}
13751380
if $$$ISERR(tSC) {
13761381
quit

src/cls/IPM/Storage/ResourceReference.cls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ ClassMethod GetChildren(
193193
quit
194194
}
195195
} else {
196-
if pResourceName '= "" {
196+
if (pResourceName '= "") && ($extract(pResourceName) '= "/") {
197197
merge pResourceArray(pResourceName) = pResourceInfoArray
198198
}
199199

tests/integration_tests/Test/PM/Integration/IncludeTests.cls

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,41 @@ Method TestIncludeTestsModuleXml()
107107
}
108108
}
109109

110+
// Regression test: ResolveChildren must not return path entries (names starting with /)
111+
// as top-level keys. Path resources have no Studio document representation; returning them
112+
// as document names can crash callers.
113+
Method TestResolveChildrenNoPathEntries()
114+
{
115+
set status = $$$OK
116+
try {
117+
set testRoot = ##class(%File).NormalizeDirectory($get(^UnitTestRoot))
118+
set moduleDir = ##class(%File).NormalizeDirectory(##class(%File).GetDirectory(testRoot)_"/_data/test-output-format/")
119+
set status = ##class(%IPM.Main).Shell("load "_moduleDir)
120+
do $$$AssertStatusOK(status,"Loaded test-output-format module successfully.")
121+
122+
set module = ##class(%IPM.Storage.Module).NameOpen("test-output-format",,.status)
123+
do $$$AssertStatusOK(status,"Opened test-output-format module.")
124+
125+
set foundPathEntry = 0
126+
set key = ""
127+
for {
128+
set tResource = module.Resources.GetNext(.key)
129+
quit:(key = "")
130+
kill tChildren
131+
do $$$AssertStatusOK(tResource.ResolveChildren(.tChildren),"ResolveChildren succeeded for "_tResource.Name)
132+
set childKey = ""
133+
for {
134+
set childKey = $order(tChildren(childKey))
135+
quit:(childKey = "")
136+
if ($extract(childKey) = "/") {
137+
set foundPathEntry = 1
138+
}
139+
}
140+
}
141+
do $$$AssertNotTrue(foundPathEntry,"ResolveChildren output contains no path entries.")
142+
} catch e {
143+
do $$$AssertStatusOK(e.AsStatus(),"An exception occurred.")
144+
}
145+
}
146+
110147
}

0 commit comments

Comments
 (0)