@@ -288,6 +288,52 @@ def add_build_rule(target, rule_name)
288288 ] . sorted_md5s
289289 end
290290
291+ it 'generates UUIDs for project_references with product groups not in main_group' do
292+ # Simulate the CocoaPods scenario: project_references contains a product_group
293+ # that is NOT a child of any group under main_group.
294+ other_project = Xcodeproj ::Project . open ( 'spec/fixtures/OtherProject.xcodeproj' )
295+
296+ # Use add_dependency to create a proper project_reference entry
297+ target = @project . new_target ( :application , 'AppTarget' , :ios )
298+ target . build_phases . first . remove_from_project until target . build_phases . empty?
299+ @project [ 'Frameworks/iOS' ] . children . first . remove_from_project
300+ @project [ 'Frameworks/iOS' ] . remove_from_project
301+ Xcodeproj ::Project ::FileReferencesFactory . new_reference ( @project . main_group , other_project . path , :group )
302+ target . add_dependency ( other_project . targets . first )
303+
304+ # Now detach the product group from main_group to simulate CocoaPods.
305+ # Use children.delete (not remove_from_project) to keep it in the project objects.
306+ product_group = @project . root_object . project_references . first [ :product_group ]
307+ @project . main_group . children . delete ( product_group )
308+
309+ @generator . generate!
310+
311+ # The product group's hierarchy_path includes the project name since it's
312+ # detached from main_group (simulating how CocoaPods sets up project_references).
313+ pg_path = product_group . hierarchy_path
314+ expect ( @project . sorted_md5s ) . to eq ( %W[
315+ PBXProject(#{ @spec_safe_name } )
316+ PBXProject(#{ @spec_safe_name } )/PBXFileReference(${BUILT_PRODUCTS_DIR}/AppTarget.app)
317+ PBXProject(#{ @spec_safe_name } )/PBXFileReference(spec/fixtures/OtherProject.xcodeproj)
318+ PBXProject(#{ @spec_safe_name } )/PBXGroup(/)
319+ PBXProject(#{ @spec_safe_name } )/PBXGroup(/Frameworks)
320+ PBXProject(#{ @spec_safe_name } )/PBXNativeTarget(AppTarget)
321+ ] + [
322+ "PBXProject(#{ @spec_safe_name } )/PBXGroup(#{ pg_path } )" ,
323+ "PBXProject(#{ @spec_safe_name } )/PBXGroup(#{ pg_path } )/PBXReferenceProxy(BUILT_PRODUCTS_DIR/FrameworkTargetInOtherProject.framework)" ,
324+ "PBXProject(#{ @spec_safe_name } )/PBXGroup(#{ pg_path } )/PBXReferenceProxy(BUILT_PRODUCTS_DIR/FrameworkTargetInOtherProject.framework)/PBXContainerItemProxy(type: 2, containerPortal: OtherProject.xcodeproj, remoteInfo: Subproject)" ,
325+ "PBXProject(#{ @spec_safe_name } )/PBXNativeTarget(AppTarget)/PBXTargetDependency(FrameworkTargetInOtherProject)" ,
326+ "PBXProject(#{ @spec_safe_name } )/PBXNativeTarget(AppTarget)/PBXTargetDependency(FrameworkTargetInOtherProject)/PBXContainerItemProxy(type: 1, containerPortal: OtherProject.xcodeproj, remoteInfo: FrameworkTargetInOtherProject)"
327+ ] + %W[
328+ PBXProject(#{ @spec_safe_name } )/PBXNativeTarget(AppTarget)/XCConfigurationList
329+ PBXProject(#{ @spec_safe_name } )/PBXNativeTarget(AppTarget)/XCConfigurationList/XCBuildConfiguration(Debug)
330+ PBXProject(#{ @spec_safe_name } )/PBXNativeTarget(AppTarget)/XCConfigurationList/XCBuildConfiguration(Release)
331+ PBXProject(#{ @spec_safe_name } )/XCConfigurationList
332+ PBXProject(#{ @spec_safe_name } )/XCConfigurationList/XCBuildConfiguration(Debug)
333+ PBXProject(#{ @spec_safe_name } )/XCConfigurationList/XCBuildConfiguration(Release)
334+ ] ) . sorted_md5s
335+ end
336+
291337 it 'generates UUIDs for SwiftPM dependencies' do
292338 target = @project . new_target ( :application , 'AppTarget' , :ios )
293339 target . resources_build_phase . remove_from_project
0 commit comments