@@ -2218,3 +2218,69 @@ func TestCalculateCollisionNameInline_NumericSuffix(t *testing.T) {
22182218 assert .Equal (t , "Cat__external__2" , result )
22192219}
22202220
2221+ // TestBundlePreservesDynamicAnchorAndRef tests that $dynamicAnchor and $dynamicRef
2222+ // (JSON Schema 2020-12 keywords) are preserved during bundling.
2223+ func TestBundlePreservesDynamicAnchorAndRef (t * testing.T ) {
2224+ spec := `openapi: "3.1.0"
2225+ info:
2226+ title: Test API
2227+ version: "1.0"
2228+ paths: {}
2229+ components:
2230+ schemas:
2231+ TreeNode:
2232+ type: object
2233+ $dynamicAnchor: node
2234+ properties:
2235+ value:
2236+ type: string
2237+ children:
2238+ type: array
2239+ items:
2240+ $dynamicRef: "#node"
2241+ `
2242+
2243+ doc , err := libopenapi .NewDocument ([]byte (spec ))
2244+ require .NoError (t , err )
2245+
2246+ v3Doc , errs := doc .BuildV3Model ()
2247+ require .Nil (t , errs )
2248+ require .NotNil (t , v3Doc )
2249+
2250+ // Bundle the document
2251+ bundledBytes , err := BundleDocument (& v3Doc .Model )
2252+ require .NoError (t , err )
2253+
2254+ bundledStr := string (bundledBytes )
2255+
2256+ // Verify $dynamicAnchor is preserved
2257+ assert .Contains (t , bundledStr , "$dynamicAnchor: node" , "$dynamicAnchor should be preserved after bundling" )
2258+
2259+ // Verify $dynamicRef is preserved (not resolved/inlined)
2260+ assert .Contains (t , bundledStr , `$dynamicRef: "#node"` , "$dynamicRef should be preserved after bundling" )
2261+
2262+ // Additional verification: parse the bundled document and check the schema values
2263+ bundledDoc , err := libopenapi .NewDocument (bundledBytes )
2264+ require .NoError (t , err )
2265+
2266+ bundledV3 , errs := bundledDoc .BuildV3Model ()
2267+ require .Nil (t , errs )
2268+
2269+ treeNodeSchema := bundledV3 .Model .Components .Schemas .GetOrZero ("TreeNode" ).Schema ()
2270+ require .NotNil (t , treeNodeSchema )
2271+
2272+ // Check $dynamicAnchor
2273+ assert .Equal (t , "node" , treeNodeSchema .DynamicAnchor , "DynamicAnchor should be 'node'" )
2274+
2275+ // Check $dynamicRef on the items schema
2276+ childrenProp := treeNodeSchema .Properties .GetOrZero ("children" )
2277+ require .NotNil (t , childrenProp )
2278+ childrenSchema := childrenProp .Schema ()
2279+ require .NotNil (t , childrenSchema )
2280+ require .NotNil (t , childrenSchema .Items )
2281+ require .True (t , childrenSchema .Items .IsA (), "Items should be a schema" )
2282+ itemsSchema := childrenSchema .Items .A .Schema ()
2283+ require .NotNil (t , itemsSchema )
2284+ assert .Equal (t , "#node" , itemsSchema .DynamicRef , "DynamicRef should be '#node'" )
2285+ }
2286+
0 commit comments