#!/usr/bin/env ruby # frozen_string_literal: true # Script to add test targets to the Xcode project # Usage: ruby Scripts/setup_tests.rb # # Prerequisites: # gem install xcodeproj require 'xcodeproj' PROJECT_PATH = 'PortfolioJournal.xcodeproj' UNIT_TEST_TARGET_NAME = 'PortfolioJournalTests' UNIT_TEST_BUNDLE_ID = 'com.alexandrevazquez.PortfolioJournalTests' def main puts "Opening project at #{PROJECT_PATH}..." project = Xcodeproj::Project.open(PROJECT_PATH) # Check if test target already exists if project.targets.any? { |t| t.name == UNIT_TEST_TARGET_NAME } puts "Test target '#{UNIT_TEST_TARGET_NAME}' already exists. Skipping creation." return end puts "Creating unit test target..." # Find the main app target main_target = project.targets.find { |t| t.name == 'PortfolioJournal' } unless main_target puts "Error: Could not find main app target 'PortfolioJournal'" exit 1 end # Create the unit test target test_target = project.new_target( :unit_test_bundle, UNIT_TEST_TARGET_NAME, :ios, '17.6', main_target ) # Configure build settings test_target.build_configurations.each do |config| config.build_settings['BUNDLE_LOADER'] = '$(TEST_HOST)' config.build_settings['TEST_HOST'] = '$(BUILT_PRODUCTS_DIR)/PortfolioJournal.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/PortfolioJournal' config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = UNIT_TEST_BUNDLE_ID config.build_settings['SWIFT_VERSION'] = '5.0' config.build_settings['CODE_SIGN_STYLE'] = 'Automatic' config.build_settings['DEVELOPMENT_TEAM'] = '2825Q76T7H' config.build_settings['INFOPLIST_FILE'] = '' config.build_settings['GENERATE_INFOPLIST_FILE'] = 'YES' config.build_settings['SWIFT_EMIT_LOC_STRINGS'] = 'NO' config.build_settings['ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'] = '$(inherited)' config.build_settings['LD_RUNPATH_SEARCH_PATHS'] = [ '$(inherited)', '@executable_path/Frameworks', '@loader_path/Frameworks' ] end # Add test target dependency on main target test_target.add_dependency(main_target) # Create file references for test files tests_group = project.main_group.find_subpath('PortfolioJournalTests', true) tests_group.set_source_tree('') tests_group.set_path('PortfolioJournalTests') # Find all test Swift files test_files_path = File.join(File.dirname(PROJECT_PATH), 'PortfolioJournalTests') if Dir.exist?(test_files_path) Dir.glob("#{test_files_path}/**/*.swift").each do |file_path| relative_path = file_path.sub("#{test_files_path}/", '') # Create subgroups as needed path_components = relative_path.split('/') current_group = tests_group path_components[0...-1].each do |component| subgroup = current_group.find_subpath(component, true) subgroup.set_source_tree('') current_group = subgroup end # Add file reference file_name = path_components.last file_ref = current_group.new_file(file_path) test_target.source_build_phase.add_file_reference(file_ref) end end puts "Saving project..." project.save puts "✅ Test target '#{UNIT_TEST_TARGET_NAME}' created successfully!" puts "" puts "Next steps:" puts "1. Open Xcode and build the project" puts "2. Run tests with: xcodebuild test -scheme PortfolioJournal -destination 'platform=iOS Simulator,name=iPhone 17'" puts " Or use: make test" end begin main rescue LoadError => e puts "Error: xcodeproj gem not found." puts "Install it with: gem install xcodeproj" puts "" puts "Alternatively, add the test target manually in Xcode:" puts "1. File > New > Target > iOS Unit Testing Bundle" puts "2. Name it 'PortfolioJournalTests'" puts "3. Add the test files from PortfolioJournalTests folder" exit 1 rescue => e puts "Error: #{e.message}" puts e.backtrace.first(5).join("\n") exit 1 end