require 'spec_helper' describe XCJobs::Xcodebuild do before(:each) do @commands = [] allow_any_instance_of(FileUtils).to receive(:sh) do |object, command| @commands << command end allow_any_instance_of(XCJobs::Xcodebuild).to receive(:run) do |object, command| @commands << command.join(' ') end Rake.application = rake end let(:rake) { Rake::Application.new } let(:destinations) do ['name=iPhone 6,OS=8.1', 'name=iPhone 6 Plus,OS=8.1', 'name=iPad 2,OS=7.1', 'name=iPad Air,OS=8.1'] end describe XCJobs::Test do context 'when a scheme is not specified' do subject do XCJobs::Test.new do |t| t.project = 'Example.xcodeproj' end end it 'fails' do expect { subject }.to raise_error(RuntimeError, 'test action requires specifying a scheme') end end context 'when both scheme and targets specified' do subject do XCJobs::Test.new do |t| t.project = 'Example.xcodeproj' t.scheme = 'Example' t.target = 'Example' end end it 'fails' do expect { subject.invoke }.to raise_error(RuntimeError, 'cannot specify both a scheme and targets') end end context 'When no file extension (project)' do let!(:task) do XCJobs::Test.new do |t| t.project = 'Project' t.scheme = 'Scheme' end end it 'Automatically complemented' do expect(task.project).to eq 'Project.xcodeproj' end end context 'When no file extension (workspace)' do let!(:task) do XCJobs::Test.new do |t| t.workspace = 'Workspace' t.scheme = 'Scheme' end end it 'Automatically complemented' do expect(task.workspace).to eq 'Workspace.xcworkspace' end end describe 'test project with simulator' do let!(:task) do XCJobs::Test.new do |t| t.project = 'Example.xcodeproj' t.scheme = 'Example' t.configuration = 'Debug' destinations.each do |destination| t.add_destination(destination) end end end it 'configures the project' do expect(task.project).to eq 'Example.xcodeproj' end it 'configures the scheme' do expect(task.scheme).to eq 'Example' end it 'configures the build configuration' do expect(task.configuration).to eq 'Debug' end describe 'tasks' do describe 'test' do subject { Rake.application['test'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild test -project Example.xcodeproj -scheme Example -sdk iphonesimulator -configuration Debug -destination name=iPhone 6,OS=8.1 -destination name=iPhone 6 Plus,OS=8.1 -destination name=iPad 2,OS=7.1 -destination name=iPad Air,OS=8.1 GCC_SYMBOLS_PRIVATE_EXTERN=NO'] end end end end describe 'test workspace with simulator' do let!(:task) do XCJobs::Test.new do |t| t.workspace = 'Example.xcworkspace' t.scheme = 'Example' t.configuration = 'Debug' destinations.each do |destination| t.add_destination(destination) end end end it 'configures the workspace' do expect(task.workspace).to eq 'Example.xcworkspace' end it 'configures the scheme' do expect(task.scheme).to eq 'Example' end it 'configures the build configuration' do expect(task.configuration).to eq 'Debug' end it 'configures destinations' do expect(task.destinations).to eq destinations end describe 'tasks' do describe 'test' do subject { Rake.application['test'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild test -workspace Example.xcworkspace -scheme Example -sdk iphonesimulator -configuration Debug -destination name=iPhone 6,OS=8.1 -destination name=iPhone 6 Plus,OS=8.1 -destination name=iPad 2,OS=7.1 -destination name=iPad Air,OS=8.1 GCC_SYMBOLS_PRIVATE_EXTERN=NO'] end end end end describe 'test project with device' do let(:destination) { 'platform=iOS,id=8d18c8c4d1a6988ac4a70d370bfcbe99fef3f7b5' } let!(:task) do XCJobs::Test.new do |t| t.project = 'Example.xcodeproj' t.scheme = 'Example' t.configuration = 'Debug' t.sdk = 'iphoneos' t.add_destination(destination) end end it 'configures the project' do expect(task.project).to eq 'Example.xcodeproj' end it 'configures the scheme' do expect(task.scheme).to eq 'Example' end it 'configures the build configuration' do expect(task.configuration).to eq 'Debug' end it 'configures the sdk' do expect(task.sdk).to eq 'iphoneos' end it 'configures destinations' do expect(task.destinations).to eq [destination] end describe 'tasks' do describe 'test' do subject { Rake.application['test'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild test -project Example.xcodeproj -scheme Example -sdk iphoneos -configuration Debug -destination platform=iOS,id=8d18c8c4d1a6988ac4a70d370bfcbe99fef3f7b5 GCC_SYMBOLS_PRIVATE_EXTERN=NO'] end end end end end describe XCJobs::Build do context 'when specifying build_dir' do subject do XCJobs::Build.new do |t| t.project = 'Example.xcodeproj' t.build_dir = 'build' end end it 'fails' do expect { subject }.to raise_error(RuntimeError, 'the scheme is required when specifying build_dir') end end context 'when both scheme and targets specified' do subject do XCJobs::Build.new do |t| t.project = 'Example.xcodeproj' t.scheme = 'Example' t.target = 'Example' end end it 'fails' do expect { subject.invoke }.to raise_error(RuntimeError, 'cannot specify both a scheme and targets') end end context 'When no file extension (project)' do let!(:task) do XCJobs::Build.new do |t| t.project = 'Project' t.scheme = 'Scheme' end end it 'Automatically complemented' do expect(task.project).to eq 'Project.xcodeproj' end end context 'When no file extension (workspace)' do let!(:task) do XCJobs::Build.new do |t| t.workspace = 'Workspace' t.scheme = 'Scheme' end end it 'Automatically complemented' do expect(task.workspace).to eq 'Workspace.xcworkspace' end end describe 'simple task with a project' do let!(:task) do XCJobs::Build.new do |t| t.project = 'Example.xcodeproj' t.target = 'Example' t.configuration = 'Release' end end it 'configures the project' do expect(task.project).to eq 'Example.xcodeproj' end it 'configures the target' do expect(task.target).to eq 'Example' end it 'configures the build configuration' do expect(task.configuration).to eq 'Release' end describe 'tasks' do describe 'build' do subject { Rake.application['build'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild build -project Example.xcodeproj -target Example -configuration Release'] end end end end describe 'simple task with a workspace' do let(:signing_identity) { 'iPhone Developer: Katsumi Kishikawa (9NXEJ2L8Q6)' } let!(:task) do XCJobs::Build.new do |t| t.workspace = 'Example.xcworkspace' t.scheme = 'Example' t.configuration = 'Debug' t.signing_identity = signing_identity unless ENV['CI'] t.provisioning_profile = './spec/profiles/development.mobileprovision' end t.build_dir = 'build' end end it 'configures the workspace' do expect(task.workspace).to eq 'Example.xcworkspace' end it 'configures the scheme' do expect(task.scheme).to eq 'Example' end it 'configures the build configuration' do expect(task.configuration).to eq 'Debug' end it 'configures the code signing identity' do expect(task.signing_identity).to eq signing_identity end it 'configures the build directory' do expect(task.build_dir).to eq('build') end describe 'tasks' do describe 'build' do subject { Rake.application['build'] } it 'executes the appropriate commands' do subject.invoke if ENV['CI'] expect(@commands).to eq ['xcodebuild build -workspace Example.xcworkspace -scheme Example -configuration Debug -derivedDataPath build CONFIGURATION_TEMP_DIR=build/temp CODE_SIGN_IDENTITY=iPhone Developer: Katsumi Kishikawa (9NXEJ2L8Q6)'] else expect(@commands).to eq ['xcodebuild build -workspace Example.xcworkspace -scheme Example -configuration Debug -derivedDataPath build CONFIGURATION_TEMP_DIR=build/temp CODE_SIGN_IDENTITY=iPhone Developer: Katsumi Kishikawa (9NXEJ2L8Q6) PROVISIONING_PROFILE=a55e7d27-6196-4994-ab9d-871d5d56b3fd'] end end end end end describe 'unsetenv_others' do it 'defaults to false' do task = XCJobs::Build.new do |t| t.project = 'Example.xcodeproj' t.target = 'Example' t.configuration = 'Release' end expect(task.unsetenv_others).to eq false end it 'can be configured' do task = XCJobs::Build.new do |t| t.project = 'Example.xcodeproj' t.target = 'Example' t.configuration = 'Release' t.unsetenv_others = true end expect(task.unsetenv_others).to eq true end end end describe XCJobs::Archive do context 'when a scheme is not specified' do subject do XCJobs::Archive.new do |t| t.project = 'Example.xcodeproj' end end it 'fails' do expect { subject }.to raise_error(RuntimeError, 'archive action requires specifying a scheme') end end context 'when both scheme and targets specified' do subject do XCJobs::Archive.new do |t| t.project = 'Example.xcodeproj' t.scheme = 'Example' t.target = 'Example' end end it 'fails' do expect { subject.invoke }.to raise_error(RuntimeError, 'cannot specify both a scheme and targets') end end describe 'simple task with a project' do let!(:task) do XCJobs::Archive.new do |t| t.project = 'Example.xcodeproj' t.scheme = 'Example' t.configuration = 'Release' t.build_dir = 'build' end end it 'configures the project' do expect(task.project).to eq 'Example.xcodeproj' end it 'configures the target' do expect(task.scheme).to eq 'Example' end it 'configures the build configuration' do expect(task.configuration).to eq 'Release' end it 'configures the build directory' do expect(task.build_dir).to eq('build') end describe 'tasks' do describe 'build:archive' do subject { Rake.application['build:archive'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq [ 'xcodebuild archive -project Example.xcodeproj -scheme Example -configuration Release -derivedDataPath build CONFIGURATION_TEMP_DIR=build/temp -archivePath build/Example', '(cd build; zip -ryq dSYMs.zip Example.xcarchive/dSYMs)', '(cd build; zip -ryq Example.xcarchive.zip Example.xcarchive)', ] end end end end describe 'archive task with a workspace' do let!(:task) do XCJobs::Archive.new do |t| t.workspace = 'Example.xcworkspace' t.scheme = 'Example' t.configuration = 'Release' t.signing_identity = 'iPhone Distribution: kishikawa katsumi' unless ENV['CI'] t.provisioning_profile = 'spec/profiles/distribution.mobileprovision' end t.build_dir = 'build' end end it 'configures the workspace' do expect(task.workspace).to eq('Example.xcworkspace') end it 'configures the scheme' do expect(task.scheme).to eq('Example') end it 'configures the build configuration' do expect(task.configuration).to eq('Release') end it 'configures the code signing identity' do expect(task.signing_identity).to eq('iPhone Distribution: kishikawa katsumi') end unless ENV['CI'] it 'configures the provisioning profile' do expect(task.provisioning_profile).to eq('spec/profiles/distribution.mobileprovision') end it 'configures the provisioning profile name' do expect(task.provisioning_profile_name).to eq('Distribution Provisioning Profile') end it 'configures the provisioning profile UUID' do expect(task.provisioning_profile_uuid).to eq('5d09b88d-ff09-43aa-a6fd-3907f98fe467') end end it 'configures the build directory' do expect(task.build_dir).to eq('build') end describe 'tasks' do describe 'build:archive' do subject { Rake.application['build:archive'] } it 'executes the appropriate commands' do subject.invoke if ENV['CI'] expect(@commands).to eq [ 'xcodebuild archive -workspace Example.xcworkspace -scheme Example -configuration Release -derivedDataPath build CONFIGURATION_TEMP_DIR=build/temp CODE_SIGN_IDENTITY=iPhone Distribution: kishikawa katsumi -archivePath build/Example', '(cd build; zip -ryq dSYMs.zip Example.xcarchive/dSYMs)', '(cd build; zip -ryq Example.xcarchive.zip Example.xcarchive)', ] else expect(@commands).to eq [ 'xcodebuild archive -workspace Example.xcworkspace -scheme Example -configuration Release -derivedDataPath build CONFIGURATION_TEMP_DIR=build/temp CODE_SIGN_IDENTITY=iPhone Distribution: kishikawa katsumi PROVISIONING_PROFILE=5d09b88d-ff09-43aa-a6fd-3907f98fe467 -archivePath build/Example', '(cd build; zip -ryq dSYMs.zip Example.xcarchive/dSYMs)', '(cd build; zip -ryq Example.xcarchive.zip Example.xcarchive)', ] end end end end end end describe XCJobs::Export do describe 'export task for IPA' do let!(:task) do XCJobs::Export.new do |t| t.archive_path = 'build/Example' t.export_format = 'IPA' t.export_path = 'build/Example.ipa' if ENV['CI'] t.export_provisioning_profile = 'Ad Hoc Provisioning Profile' else t.export_provisioning_profile = './spec/profiles/adhoc.mobileprovision' end t.export_signing_identity = 'iPhone Distribution: kishikawa katsumi' end end it 'configures the archive path' do expect(task.archive_path).to eq 'build/Example' end it 'configures the export format' do expect(task.export_format).to eq 'IPA' end it 'configures the export path' do expect(task.export_path).to eq 'build/Example.ipa' end it 'configures the export provisioning profile' do expect(task.export_provisioning_profile).to eq 'Ad Hoc Provisioning Profile' end it 'configures the export signing identity' do expect(task.export_signing_identity).to eq 'iPhone Distribution: kishikawa katsumi' end it 'configures unsetenv_others to true by default' do expect(task.unsetenv_others).to be_truthy end describe 'tasks' do describe 'export' do subject { Rake.application['build:export'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild -exportArchive -archivePath build/Example -exportFormat IPA -exportPath build/Example.ipa -exportProvisioningProfile Ad Hoc Provisioning Profile -exportSigningIdentity iPhone Distribution: kishikawa katsumi'] end end end end describe 'export task for IPA' do let!(:task) do XCJobs::Export.new do |t| t.archive_path = 'build/Example' t.export_format = 'IPA' t.export_path = 'build/Example.ipa' t.export_provisioning_profile = 'Ad Hoc Provisioning Profile' t.export_signing_identity = 'iPhone Distribution: kishikawa katsumi' end end it 'configures the archive path' do expect(task.archive_path).to eq 'build/Example' end it 'configures the export format' do expect(task.export_format).to eq 'IPA' end it 'configures the export path' do expect(task.export_path).to eq 'build/Example.ipa' end it 'configures the export provisioning profile' do expect(task.export_provisioning_profile).to eq 'Ad Hoc Provisioning Profile' end it 'configures the export signing identity' do expect(task.export_signing_identity).to eq 'iPhone Distribution: kishikawa katsumi' end describe 'tasks' do describe 'export' do subject { Rake.application['build:export'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild -exportArchive -archivePath build/Example -exportFormat IPA -exportPath build/Example.ipa -exportProvisioningProfile Ad Hoc Provisioning Profile -exportSigningIdentity iPhone Distribution: kishikawa katsumi'] end end end end describe 'export task for IPA' do let!(:task) do XCJobs::Export.new do |t| t.archive_path = 'build/Example' t.export_format = nil t.export_path = 'build' end end it 'configures the export_format to be nil' do expect(task.export_format).to be_nil end describe 'tasks' do describe 'export' do subject { Rake.application['build:export'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild -exportArchive -archivePath build/Example -exportPath build'] end end end end describe 'export task for IPA' do let!(:task) do XCJobs::Export.new do |t| t.archive_path = 'build/Example' t.export_path = 'build' end end it 'has default export_format default to be IPA' do expect(task.export_format).to eq 'IPA' end describe 'tasks' do describe 'export' do subject { Rake.application['build:export'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild -exportArchive -archivePath build/Example -exportFormat IPA -exportPath build'] end end end end describe 'export task for IPA' do let!(:task) do XCJobs::Export.new do |t| t.archive_path = 'build/Example' t.export_format = nil t.export_path = 'build' t.options_plist = 'options.plist' end end it 'configures the export options plist' do expect(task.options_plist).to eq 'options.plist' end describe 'tasks' do describe 'export' do subject { Rake.application['build:export'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild -exportArchive -exportOptionsPlist options.plist -archivePath build/Example -exportPath build'] end end end end describe 'export task for PKG' do let!(:task) do XCJobs::Export.new do |t| t.archive_path = 'build/Example' t.export_format = 'PKG' t.export_path = 'build/Example.pkg' t.export_signing_identity = 'Developer ID Application' t.export_installer_identity = 'Developer ID Installer' end end it 'configures the archive path' do expect(task.archive_path).to eq 'build/Example' end it 'configures the export format' do expect(task.export_format).to eq 'PKG' end it 'configures the export path' do expect(task.export_path).to eq 'build/Example.pkg' end it 'configures the export signing identity' do expect(task.export_signing_identity).to eq 'Developer ID Application' end it 'configures the export installer identity' do expect(task.export_installer_identity).to eq 'Developer ID Installer' end describe 'tasks' do describe 'export' do subject { Rake.application['build:export'] } it 'executes the appropriate commands' do subject.invoke expect(@commands).to eq ['xcodebuild -exportArchive -archivePath build/Example -exportFormat PKG -exportPath build/Example.pkg -exportSigningIdentity Developer ID Application -exportInstallerIdentity Developer ID Installer'] end end end end end end