Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
986 lines (831 sloc) 39.7 KB
require File.expand_path('../../spec_helper', __FILE__)
require 'cocoapods_stats/sender'
# @return [Lockfile]
#
def generate_lockfile(lockfile_version: Pod::VERSION)
hash = {}
hash['PODS'] = []
hash['DEPENDENCIES'] = []
hash['SPEC CHECKSUMS'] = {}
hash['COCOAPODS'] = lockfile_version
Pod::Lockfile.new(hash)
end
# @return [Podfile]
#
def generate_podfile(pods = ['JSONKit'])
Pod::Podfile.new do
platform :ios
project SpecHelper.fixture('SampleProject/SampleProject'), 'Test' => :debug, 'App Store' => :release
target 'SampleProject' do
pods.each { |name| pod name }
target 'SampleProjectTests' do
inherit! :search_paths
end
end
end
end
# @return [Podfile]
#
def generate_local_podfile
Pod::Podfile.new do
platform :ios
project SpecHelper.fixture('SampleProject/SampleProject'), 'Test' => :debug, 'App Store' => :release
target 'SampleProject' do
pod 'Reachability', :path => SpecHelper.fixture('integration/Reachability')
target 'SampleProjectTests' do
inherit! :search_paths
end
end
end
end
#-----------------------------------------------------------------------------#
module Pod
describe Installer do
before do
CocoaPodsStats::Sender.any_instance.stubs(:send)
podfile = generate_podfile
lockfile = generate_lockfile
@installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
end
#-------------------------------------------------------------------------#
describe 'In general' do
before do
@installer.stubs(:resolve_dependencies)
@installer.stubs(:download_dependencies)
@installer.stubs(:verify_no_duplicate_framework_names)
@installer.stubs(:verify_no_static_framework_transitive_dependencies)
@installer.stubs(:verify_framework_usage)
@installer.stubs(:generate_pods_project)
@installer.stubs(:integrate_user_project)
@installer.stubs(:run_plugins_post_install_hooks)
@installer.stubs(:ensure_plugins_are_installed!)
@installer.stubs(:perform_post_install_actions)
end
it 'in runs the pre-install hooks before cleaning the Pod sources' do
@installer.unstub(:download_dependencies)
@installer.stubs(:create_file_accessors)
@installer.stubs(:install_pod_sources)
def @installer.run_podfile_pre_install_hooks
@hook_called = true
end
def @installer.clean_pod_sources
@hook_called.should.be.true
end
@installer.install!
end
it 'in runs the post-install hooks before serializing the Pods project' do
@installer.stubs(:prepare_pods_project)
@installer.stubs(:run_podfile_pre_install_hooks)
@installer.stubs(:install_file_references)
@installer.stubs(:install_libraries)
@installer.stubs(:set_target_dependencies)
@installer.stubs(:write_lockfiles)
@installer.stubs(:aggregate_targets).returns([])
@installer.unstub(:generate_pods_project)
def @installer.run_podfile_post_install_hooks
@hook_called = true
end
def @installer.write_pod_project
@hook_called.should.be.true
end
@installer.install!
end
it 'runs source provider hooks before analyzing' do
@installer.unstub(:resolve_dependencies)
@installer.stubs(:validate_build_configurations)
@installer.stubs(:clean_sandbox)
def @installer.run_source_provider_hooks
@hook_called = true
end
def @installer.analyze(*)
@hook_called.should.be.true
end
@installer.install!
end
it 'includes sources from source provider plugins' do
plugin_name = 'test-plugin'
Pod::HooksManager.register(plugin_name, :source_provider) do |context, options|
source_url = options['sources'].first
return unless source_url
source = Pod::Source.new(source_url)
context.add_source(source)
end
test_source_name = 'https://github.com/artsy/Specs.git'
plugins_hash = Installer::DEFAULT_PLUGINS.merge(plugin_name => { 'sources' => [test_source_name] })
@installer.podfile.stubs(:plugins).returns(plugins_hash)
@installer.unstub(:resolve_dependencies)
@installer.stubs(:validate_build_configurations)
@installer.stubs(:clean_sandbox)
@installer.stubs(:ensure_plugins_are_installed!)
@installer.stubs(:analyze)
analyzer = Installer::Analyzer.new(config.sandbox, @installer.podfile, @installer.lockfile)
analyzer.stubs(:analyze)
@installer.stubs(:create_analyzer).returns(analyzer)
@installer.install!
source = Pod::Source.new(test_source_name)
names = analyzer.sources.map(&:name)
names.should.include(source.name)
end
it 'integrates the user targets if the corresponding config is set' do
@installer.installation_options.integrate_targets = true
@installer.expects(:integrate_user_project)
@installer.install!
end
it "doesn't integrates the user targets if the corresponding config is not set" do
@installer.installation_options.integrate_targets = false
@installer.expects(:integrate_user_project).never
@installer.install!
end
it 'prints a list of deprecated pods' do
spec = Spec.new
spec.name = 'RestKit'
spec.deprecated_in_favor_of = 'AFNetworking'
spec_two = Spec.new
spec_two.name = 'BlocksKit'
spec_two.deprecated = true
@installer.stubs(:root_specs).returns([spec, spec_two])
@installer.send(:warn_for_deprecations)
UI.warnings.should.include 'deprecated in favor of AFNetworking'
UI.warnings.should.include 'BlocksKit has been deprecated'
end
it 'does not raise if command is run outside sandbox directory' do
Dir.chdir(@installer.sandbox.root.parent) do
should.not.raise(Informative) { @installer.install! }
end
end
it 'raises if command is run in sandbox directory' do
Dir.chdir(@installer.sandbox.root) do
should.raise Informative do
@installer.install!
end.message.should.match /should.*run.*outside.*Pods directory.*Current directory.*\./m
end
end
describe 'handling CocoaPods version updates' do
it 'does not deintegrate when there is no lockfile' do
installer = Pod::Installer.new(config.sandbox, generate_podfile, nil)
UI.expects(:section).never
installer.send(:deintegrate_if_different_major_version)
end
it 'does not deintegrate when the major version is the same' do
should_not_deintegrate = %w(1.0.0 1.0.1 1.1.0 1.2.2)
should_not_deintegrate.each do |version|
lockfile = generate_lockfile(:lockfile_version => version)
installer = Pod::Installer.new(config.sandbox, generate_podfile, lockfile)
Pathname.expects(:glob).never
installer.send(:deintegrate_if_different_major_version)
end
end
it 'does deintegrate when the major version is different' do
should_not_deintegrate = %w(0.39.0 2.0.0 10.0-beta)
should_not_deintegrate.each do |version|
lockfile = generate_lockfile(:lockfile_version => version)
installer = Pod::Installer.new(config.sandbox, generate_podfile, lockfile)
project = fixture('SampleProject/SampleProject.xcodeproj')
Pathname.expects(:glob).with(config.installation_root + '*.xcodeproj').returns([project])
Deintegrator.any_instance.expects(:deintegrate_project)
installer.send(:deintegrate_if_different_major_version)
end
end
end
end
#-------------------------------------------------------------------------#
describe '#determine_dependency_product_type' do
it 'does propagate that frameworks are required to all pod targets' do
Sandbox::FileAccessor.any_instance.stubs(:vendored_libraries).returns([])
fixture_path = ROOT + 'spec/fixtures'
config.repos_dir = fixture_path + 'spec-repos'
podfile = Pod::Podfile.new do
platform :ios, '8.0'
project 'SampleProject/SampleProject'
use_frameworks!
pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s
pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s
pod 'matryoshka', :path => (fixture_path + 'matryoshka').to_s
pod 'monkey', :path => (fixture_path + 'monkey').to_s
target 'SampleProject'
target 'TestRunner' do
inherit! :search_paths
pod 'monkey', :path => (fixture_path + 'monkey').to_s
end
end
lockfile = generate_lockfile
@installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
@installer.install!
target = @installer.aggregate_targets.first
target.requires_frameworks?.should == true
target.pod_targets.select(&:requires_frameworks?).map(&:name).sort.should == %w(
BananaLib
OrangeFramework
matryoshka
monkey
)
end
end
#-------------------------------------------------------------------------#
describe '#verify_no_duplicate_framework_names' do
it 'detects duplicate framework names' do
Sandbox::FileAccessor.any_instance.stubs(:vendored_frameworks).
returns([Pathname('a/monkey.framework')]).then.
returns([Pathname('b/monkey.framework')]).then.
returns([Pathname('c/monkey.framework')])
fixture_path = ROOT + 'spec/fixtures'
config.repos_dir = fixture_path + 'spec-repos'
podfile = Pod::Podfile.new do
platform :ios, '8.0'
project 'SampleProject/SampleProject'
pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s
pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s
pod 'matryoshka', :path => (fixture_path + 'matryoshka').to_s
pod 'monkey', :path => (fixture_path + 'monkey').to_s
target 'SampleProject'
end
lockfile = generate_lockfile
@installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
should.raise(Informative) { @installer.install! }.message.should.match /conflict.*monkey/
end
it 'allows duplicate references to the same expanded framework path' do
Sandbox::FileAccessor.any_instance.stubs(:vendored_frameworks).returns([fixture('monkey/dynamic-monkey.framework')])
Sandbox::FileAccessor.any_instance.stubs(:dynamic_binary?).returns(true)
fixture_path = ROOT + 'spec/fixtures'
config.repos_dir = fixture_path + 'spec-repos'
podfile = Pod::Podfile.new do
platform :ios, '8.0'
project 'SampleProject/SampleProject'
use_frameworks!
pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s
pod 'monkey', :path => (fixture_path + 'monkey').to_s
target 'SampleProject'
end
lockfile = generate_lockfile
@installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
should.not.raise(Informative) { @installer.install! }
end
end
#-------------------------------------------------------------------------#
describe '#verify_no_static_framework_transitive_dependencies' do
before do
fixture_path = ROOT + 'spec/fixtures'
config.repos_dir = fixture_path + 'spec-repos'
@podfile = Pod::Podfile.new do
install! 'cocoapods', 'integrate_targets' => false
platform :ios, '8.0'
project 'SampleProject/SampleProject'
use_frameworks!
pod 'BananaLib', :path => (fixture_path + 'banana-lib').to_s
pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s
pod 'matryoshka', :path => (fixture_path + 'matryoshka').to_s
pod 'monkey', :path => (fixture_path + 'monkey').to_s
target 'SampleProject'
end
@lockfile = generate_lockfile
@file = Pathname('/yolo.m')
@file.stubs(:realpath).returns(@file)
@lib_thing = Pathname('/libThing.a')
@lib_thing.stubs(:realpath).returns(@lib_thing)
end
it 'detects transitive static dependencies which are linked directly to the user target' do
Sandbox::FileAccessor.any_instance.stubs(:vendored_libraries).returns([@lib_thing])
@installer = Installer.new(config.sandbox, @podfile, @lockfile)
should.raise(Informative) { @installer.install! }.message.should.match /transitive.*libThing/
end
it 'allows transitive static dependencies which contain other source code' do
Sandbox::FileAccessor.any_instance.stubs(:source_files).returns([@file])
Sandbox::FileAccessor.any_instance.stubs(:vendored_libraries).returns([@lib_thing])
@installer = Installer.new(config.sandbox, @podfile, @lockfile)
should.not.raise(Informative) { @installer.install! }
end
it 'allows transitive static dependencies when both dependencies are linked against the user target' do
PodTarget.any_instance.stubs(:should_build? => false)
Sandbox::FileAccessor.any_instance.stubs(:vendored_libraries).returns([@lib_thing])
@installer = Installer.new(config.sandbox, @podfile, @lockfile)
should.not.raise(Informative) { @installer.install! }
end
end
#-------------------------------------------------------------------------#
describe '#verify_framework_usage' do
it 'raises when Swift pods are used without explicit `use_frameworks!`' do
fixture_path = ROOT + 'spec/fixtures'
config.repos_dir = fixture_path + 'spec-repos'
podfile = Pod::Podfile.new do
platform :ios, '8.0'
project 'SampleProject/SampleProject'
pod 'OrangeFramework', :path => (fixture_path + 'orange-framework').to_s
pod 'matryoshka', :path => (fixture_path + 'matryoshka').to_s
target 'SampleProject'
end
lockfile = generate_lockfile
@installer = Installer.new(config.sandbox, podfile, lockfile)
@installer.installation_options.integrate_targets = false
should.raise(Informative) { @installer.install! }.message.should.match /use_frameworks/
end
end
#-------------------------------------------------------------------------#
describe 'Dependencies Resolution' do
describe 'updating spec repos' do
it 'does not updates the repositories by default' do
config.sources_manager.expects(:update).never
@installer.send(:resolve_dependencies)
end
it 'updates the repositories if that was requested' do
@installer.repo_update = true
config.sources_manager.expects(:update).once
@installer.send(:resolve_dependencies)
end
end
#--------------------------------------#
describe '#analyze' do
it 'prints a warning if the version of the Lockfile is higher than the one of the executable' do
Lockfile.any_instance.stubs(:cocoapods_version).returns(Version.new('999'))
STDERR.expects(:puts)
@installer.send(:analyze)
end
it 'analyzes the Podfile, the Lockfile and the Sandbox' do
@installer.send(:analyze)
@installer.analysis_result.sandbox_state.added.should == Set.new(%w(JSONKit))
end
it 'stores the targets created by the analyzer' do
@installer.send(:analyze)
@installer.aggregate_targets.map(&:name).sort.should == ['Pods-SampleProject', 'Pods-SampleProjectTests']
@installer.pod_targets.map(&:name).sort.should == ['JSONKit']
end
it 'configures the analyzer to use update mode if appropriate' do
@installer.update = true
Installer::Analyzer.any_instance.expects(:update=).with(true)
@installer.send(:analyze)
@installer.aggregate_targets.map(&:name).sort.should == ['Pods-SampleProject', 'Pods-SampleProjectTests']
@installer.pod_targets.map(&:name).sort.should == ['JSONKit']
end
end
#--------------------------------------#
describe '#validate_whitelisted_configurations' do
it "raises when a whitelisted configuration doesn’t exist in the user's project" do
target_definition = @installer.podfile.target_definitions.values.first
target_definition.whitelist_pod_for_configuration('JSONKit', 'YOLO')
@installer.send(:analyze)
should.raise Informative do
@installer.send(:validate_build_configurations)
end
end
it "does not raise if all whitelisted configurations exist in the user's project" do
target_definition = @installer.podfile.target_definitions.values.first
target_definition.whitelist_pod_for_configuration('JSONKit', 'Test')
@installer.send(:analyze)
should.not.raise do
@installer.send(:validate_build_configurations)
end
end
end
#--------------------------------------#
describe '#clean_sandbox' do
before do
@analysis_result = Installer::Analyzer::AnalysisResult.new
@analysis_result.specifications = []
@analysis_result.sandbox_state = Installer::Analyzer::SpecsState.new
@pod_targets = [PodTarget.new([stub('Spec')], [fixture_target_definition], config.sandbox)]
@installer.stubs(:analysis_result).returns(@analysis_result)
@installer.stubs(:pod_targets).returns(@pod_targets)
end
it 'cleans the header stores' do
config.sandbox.public_headers.expects(:implode!)
@installer.pod_targets.each do |pods_target|
pods_target.build_headers.expects(:implode!)
end
@installer.send(:clean_sandbox)
end
it 'deletes the sources of the removed Pods' do
@analysis_result.sandbox_state.add_name('Deleted-Pod', :deleted)
config.sandbox.expects(:clean_pod).with('Deleted-Pod')
@installer.send(:clean_sandbox)
end
end
end
#-------------------------------------------------------------------------#
describe 'Downloading dependencies' do
describe '#install_pod_sources' do
it 'installs all the Pods which are marked as needing installation' do
spec = fixture_spec('banana-lib/BananaLib.podspec')
spec_2 = Spec.new
spec_2.name = 'RestKit'
@installer.stubs(:root_specs).returns([spec, spec_2])
sandbox_state = Installer::Analyzer::SpecsState.new
sandbox_state.added << 'BananaLib'
sandbox_state.changed << 'RestKit'
@installer.stubs(:sandbox_state).returns(sandbox_state)
@installer.expects(:install_source_of_pod).with('BananaLib')
@installer.expects(:install_source_of_pod).with('RestKit')
@installer.send(:install_pod_sources)
end
it 'correctly configures the Pod source installer' do
spec = fixture_spec('banana-lib/BananaLib.podspec')
pod_target = PodTarget.new([spec], [fixture_target_definition], config.sandbox)
pod_target.stubs(:platform).returns(:ios)
@installer.stubs(:pod_targets).returns([pod_target])
@installer.instance_variable_set(:@installed_specs, [])
Installer::PodSourceInstaller.any_instance.expects(:install!)
@installer.send(:install_source_of_pod, 'BananaLib')
end
it 'maintains the list of the installed specs' do
spec = fixture_spec('banana-lib/BananaLib.podspec')
pod_target = PodTarget.new([spec], [fixture_target_definition], config.sandbox)
pod_target.stubs(:platform).returns(:ios)
@installer.stubs(:pod_targets).returns([pod_target, pod_target])
@installer.instance_variable_set(:@installed_specs, [])
Installer::PodSourceInstaller.any_instance.stubs(:install!)
@installer.send(:install_source_of_pod, 'BananaLib')
@installer.installed_specs.should == [spec]
end
it 'prints the previous version of a pod while updating the spec' do
spec = Spec.new
spec.name = 'RestKit'
spec.version = '2.0'
manifest = Lockfile.new({})
manifest.stubs(:version).with('RestKit').returns('1.0')
@installer.sandbox.stubs(:manifest).returns(manifest)
@installer.stubs(:root_specs).returns([spec])
sandbox_state = Installer::Analyzer::SpecsState.new
sandbox_state.changed << 'RestKit'
@installer.stubs(:sandbox_state).returns(sandbox_state)
@installer.expects(:install_source_of_pod).with('RestKit')
@installer.send(:install_pod_sources)
UI.output.should.include 'was 1.0'
end
#--------------------------------------#
describe '#clean' do
it 'it cleans only if the config instructs to do it' do
@installer.installation_options.clean = false
@installer.send(:clean_pod_sources)
Installer::PodSourceInstaller.any_instance.expects(:install!).never
end
end
#--------------------------------------#
end
end
#-------------------------------------------------------------------------#
describe 'Generating pods project' do
describe '#prepare_pods_project' do
before do
@installer.stubs(:aggregate_targets).returns([])
end
it "creates build configurations for all of the user's targets" do
@installer.installation_options.integrate_targets = true
@installer.send(:analyze)
@installer.send(:prepare_pods_project)
@installer.pods_project.build_configurations.map(&:name).sort.should == ['App Store', 'Debug', 'Release', 'Test']
end
it 'sets STRIP_INSTALLED_PRODUCT to NO for all configurations for the whole project' do
@installer.installation_options.integrate_targets = true
@installer.send(:analyze)
@installer.send(:prepare_pods_project)
@installer.pods_project.build_settings('Debug')['STRIP_INSTALLED_PRODUCT'].should == 'NO'
@installer.pods_project.build_settings('Test')['STRIP_INSTALLED_PRODUCT'].should == 'NO'
@installer.pods_project.build_settings('Release')['STRIP_INSTALLED_PRODUCT'].should == 'NO'
@installer.pods_project.build_settings('App Store')['STRIP_INSTALLED_PRODUCT'].should == 'NO'
end
before do
@installer.stubs(:analysis_result).returns(stub(:all_user_build_configurations => {}, :target_inspections => nil))
end
it 'creates the Pods project' do
@installer.send(:prepare_pods_project)
@installer.pods_project.class.should == Pod::Project
end
it 'preserves Pod paths specified as absolute or rooted to home' do
local_podfile = generate_local_podfile
local_installer = Installer.new(config.sandbox, local_podfile)
local_installer.send(:analyze)
local_installer.send(:prepare_pods_project)
group = local_installer.pods_project.group_for_spec('Reachability')
Pathname.new(group.path).should.be.absolute
end
it 'adds the Podfile to the Pods project' do
config.stubs(:podfile_path).returns(Pathname.new('/Podfile'))
@installer.send(:prepare_pods_project)
@installer.pods_project['Podfile'].should.be.not.nil
end
it 'sets the deployment target for the whole project' do
target_definition_osx = fixture_target_definition('OSX Target', Platform.new(:osx, '10.8'))
target_definition_ios = fixture_target_definition('iOS Target', Platform.new(:ios, '6.0'))
aggregate_target_osx = AggregateTarget.new(target_definition_osx, config.sandbox)
aggregate_target_ios = AggregateTarget.new(target_definition_ios, config.sandbox)
@installer.stubs(:aggregate_targets).returns([aggregate_target_osx, aggregate_target_ios])
@installer.stubs(:pod_targets).returns([])
@installer.send(:prepare_pods_project)
build_settings = @installer.pods_project.build_configurations.map(&:build_settings)
build_settings.each do |build_setting|
build_setting['MACOSX_DEPLOYMENT_TARGET'].should == '10.8'
build_setting['IPHONEOS_DEPLOYMENT_TARGET'].should == '6.0'
end
end
end
#--------------------------------------#
describe '#install_file_references' do
it 'installs the file references' do
@installer.stubs(:pod_targets).returns([])
Installer::FileReferencesInstaller.any_instance.expects(:install!)
@installer.send(:install_file_references)
end
end
#--------------------------------------#
describe '#install_libraries' do
it 'install the targets of the Pod project' do
spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new(:default, nil)
target_definition.abstract = false
target_definition.store_pod('BananaLib')
pod_target = PodTarget.new([spec], [target_definition], config.sandbox)
@installer.stubs(:aggregate_targets).returns([])
@installer.stubs(:pod_targets).returns([pod_target])
Installer::PodTargetInstaller.any_instance.expects(:install!)
@installer.send(:install_libraries)
end
it 'does not skip empty pod targets' do
spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new(:default, nil)
target_definition.abstract = false
pod_target = PodTarget.new([spec], [target_definition], config.sandbox)
@installer.stubs(:aggregate_targets).returns([])
@installer.stubs(:pod_targets).returns([pod_target])
Installer::PodTargetInstaller.any_instance.expects(:install!).once
@installer.send(:install_libraries)
end
it 'adds the frameworks required by to the pod to the project for informative purposes' do
Specification::Consumer.any_instance.stubs(:frameworks).returns(['QuartzCore'])
@installer.install!
names = @installer.sandbox.project['Frameworks']['iOS'].children.map(&:name)
names.sort.should == ['Foundation.framework', 'QuartzCore.framework']
end
end
#--------------------------------------#
describe '#set_target_dependencies' do
def test_extension_target(symbol_type)
mock_user_target = mock('UserTarget', :symbol_type => symbol_type)
@target.stubs(:user_targets).returns([mock_user_target])
build_settings = {}
mock_configuration = mock('BuildConfiguration', :build_settings => build_settings)
@mock_target.stubs(:build_configurations).returns([mock_configuration])
@installer.send(:set_target_dependencies)
build_settings.should == { 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }
end
before do
spec = fixture_spec('banana-lib/BananaLib.podspec')
target_definition = Podfile::TargetDefinition.new(:default, @installer.podfile.root_target_definitions.first)
@pod_target = PodTarget.new([spec], [target_definition], config.sandbox)
@target = AggregateTarget.new(target_definition, config.sandbox)
@mock_target = mock('PodNativeTarget')
mock_project = mock('PodsProject', :frameworks_group => mock('FrameworksGroup'))
@installer.stubs(:pods_project).returns(mock_project)
@target.stubs(:native_target).returns(@mock_target)
@target.stubs(:pod_targets).returns([@pod_target])
@installer.stubs(:aggregate_targets).returns([@target])
end
it 'sets resource bundles for not build pods as target dependencies of the user target' do
@pod_target.stubs(:resource_bundle_targets).returns(['dummy'])
@pod_target.stubs(:should_build? => false)
@mock_target.expects(:add_dependency).with('dummy')
@installer.send(:set_target_dependencies)
end
it 'configures APPLICATION_EXTENSION_API_ONLY for app extension targets' do
test_extension_target(:app_extension)
end
it 'configures APPLICATION_EXTENSION_API_ONLY for watch extension targets' do
test_extension_target(:watch_extension)
end
it 'configures APPLICATION_EXTENSION_API_ONLY for watchOS 2 extension targets' do
test_extension_target(:watch2_extension)
end
it 'configures APPLICATION_EXTENSION_API_ONLY for tvOS extension targets' do
test_extension_target(:tv_extension)
end
it 'configures APPLICATION_EXTENSION_API_ONLY for targets where the user target has it set' do
mock_user_target = mock('UserTarget', :symbol_type => :application)
mock_user_target.expects(:common_resolved_build_setting).with('APPLICATION_EXTENSION_API_ONLY').returns('YES')
@target.stubs(:user_targets).returns([mock_user_target])
build_settings = {}
mock_configuration = mock('BuildConfiguration', :build_settings => build_settings)
@mock_target.stubs(:build_configurations).returns([mock_configuration])
@installer.send(:set_target_dependencies)
build_settings.should == { 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }
end
it 'does not try to set APPLICATION_EXTENSION_API_ONLY if there are no pod targets' do
lambda do
mock_user_target = mock('UserTarget', :symbol_type => :app_extension)
@target.stubs(:user_targets).returns([mock_user_target])
@target.stubs(:native_target).returns(nil)
@target.stubs(:pod_targets).returns([])
@installer.send(:set_target_dependencies)
end.should.not.raise NoMethodError
end
end
#--------------------------------------#
describe '#write_pod_project' do
before do
@installer.stubs(:aggregate_targets).returns([])
@installer.stubs(:analysis_result).returns(stub(:all_user_build_configurations => {}, :target_inspections => nil))
@installer.send(:prepare_pods_project)
end
it 'recursively sorts the project' do
Xcodeproj::Project.any_instance.stubs(:recreate_user_schemes)
@installer.pods_project.main_group.expects(:sort)
@installer.send(:write_pod_project)
end
it 'saves the project to the given path' do
Xcodeproj::Project.any_instance.stubs(:recreate_user_schemes)
temporary_directory + 'Pods/Pods.xcodeproj'
@installer.pods_project.expects(:save)
@installer.send(:write_pod_project)
end
describe 'sharing schemes of development pods' do
before do
spec = fixture_spec('banana-lib/BananaLib.podspec')
pod_target = fixture_pod_target(spec)
@installer.stubs(:pod_targets).returns([pod_target])
@installer.sandbox.stubs(:development_pods).returns('BananaLib' => nil)
end
it 'does not share by default' do
Xcodeproj::XCScheme.expects(:share_scheme).never
@installer.send(:share_development_pod_schemes)
end
it 'can share all schemes' do
@installer.installation_options.
stubs(:share_schemes_for_development_pods).
returns(true)
Xcodeproj::XCScheme.expects(:share_scheme).with(
@installer.pods_project.path,
'BananaLib')
@installer.send(:share_development_pod_schemes)
end
it 'allows opting out' do
@installer.installation_options.
stubs(:share_schemes_for_development_pods).
returns(false)
Xcodeproj::XCScheme.expects(:share_scheme).never
@installer.send(:share_development_pod_schemes)
@installer.installation_options.
stubs(:share_schemes_for_development_pods).
returns(nil)
Xcodeproj::XCScheme.expects(:share_scheme).never
@installer.send(:share_development_pod_schemes)
end
it 'allows specifying strings of pods to share' do
@installer.installation_options.
stubs(:share_schemes_for_development_pods).
returns(%w(BananaLib))
Xcodeproj::XCScheme.expects(:share_scheme).with(
@installer.pods_project.path,
'BananaLib')
@installer.send(:share_development_pod_schemes)
@installer.installation_options.
stubs(:share_schemes_for_development_pods).
returns(%w(orange-framework))
Xcodeproj::XCScheme.expects(:share_scheme).never
@installer.send(:share_development_pod_schemes)
end
it 'allows specifying regular expressions of pods to share' do
@installer.installation_options.
stubs(:share_schemes_for_development_pods).
returns([/bAnaNalIb/i, /B*/])
Xcodeproj::XCScheme.expects(:share_scheme).with(
@installer.pods_project.path,
'BananaLib')
@installer.send(:share_development_pod_schemes)
@installer.installation_options.
stubs(:share_schemes_for_development_pods).
returns([/banana$/, /[^\A]BananaLib/])
Xcodeproj::XCScheme.expects(:share_scheme).never
@installer.send(:share_development_pod_schemes)
end
it 'raises when an invalid type is set' do
@installer.installation_options.
stubs(:share_schemes_for_development_pods).
returns(Pathname('foo'))
Xcodeproj::XCScheme.expects(:share_scheme).never
e = should.raise(Informative) { @installer.send(:share_development_pod_schemes) }
e.message.should.match /share_schemes_for_development_pods.*set it to true, false, or an array of pods to share schemes for/
end
end
it "uses the user project's object version for the pods project" do
tmp_directory = Pathname(Dir.tmpdir) + 'CocoaPods'
FileUtils.mkdir_p(tmp_directory)
proj = Xcodeproj::Project.new(tmp_directory + 'Yolo.xcodeproj', false, 1)
proj.save
aggregate_target = AggregateTarget.new(fixture_target_definition, config.sandbox)
aggregate_target.user_project = proj
@installer.stubs(:aggregate_targets).returns([aggregate_target])
@installer.send(:prepare_pods_project)
@installer.pods_project.object_version.should == '1'
FileUtils.rm_rf(tmp_directory)
end
end
#--------------------------------------#
describe '#write_lockfiles' do
before do
@analysis_result = Installer::Analyzer::AnalysisResult.new
@analysis_result.specifications = [fixture_spec('banana-lib/BananaLib.podspec')]
@installer.stubs(:analysis_result).returns(@analysis_result)
end
it 'generates the lockfile' do
@installer.send(:write_lockfiles)
@installer.lockfile.pod_names.should == ['BananaLib']
end
it 'writes the lockfile' do
@installer.send(:write_lockfiles)
lockfile = Lockfile.from_file(temporary_directory + 'Podfile.lock')
lockfile.pod_names.should == ['BananaLib']
end
it 'writes the sandbox manifest' do
@installer.send(:write_lockfiles)
lockfile = Lockfile.from_file(temporary_directory + 'Pods/Manifest.lock')
lockfile.pod_names.should == ['BananaLib']
end
end
end
#-------------------------------------------------------------------------#
describe 'Integrating client projects' do
it 'integrates the client projects' do
@installer.stubs(:aggregate_targets).returns([AggregateTarget.new(fixture_target_definition, config.sandbox)])
Installer::UserProjectIntegrator.any_instance.expects(:integrate!)
@installer.send(:integrate_user_project)
end
end
describe 'Plugins Hooks' do
before do
@installer.send(:analyze)
@specs = @installer.pod_targets.map(&:specs).flatten
@spec = @specs.find { |spec| spec && spec.name == 'JSONKit' }
@installer.stubs(:installed_specs).returns(@specs)
end
describe 'DEFAULT_PLUGINS' do
before do
@default_plugins = @installer.send(:plugins)
end
it 'includes cocoapods-stats' do
@default_plugins['cocoapods-stats'].should == {}
end
end
it 'runs plugins pre install hook' do
context = stub
Installer::PreInstallHooksContext.expects(:generate).returns(context)
HooksManager.expects(:run).with(:pre_install, context, Installer::DEFAULT_PLUGINS)
@installer.send(:run_plugins_pre_install_hooks)
end
it 'runs plugins post install hook' do
context = stub
Installer::PostInstallHooksContext.expects(:generate).returns(context)
HooksManager.expects(:run).with(:post_install, context, Installer::DEFAULT_PLUGINS)
@installer.send(:run_plugins_post_install_hooks)
end
it 'runs plugins source provider hook' do
context = stub
context.stubs(:sources).returns([])
Installer::SourceProviderHooksContext.expects(:generate).returns(context)
HooksManager.expects(:run).with(:source_provider, context, Installer::DEFAULT_PLUGINS)
@installer.send(:run_source_provider_hooks)
end
it 'only runs the podfile-specified hooks' do
context = stub
Installer::PostInstallHooksContext.expects(:generate).returns(context)
plugins_hash = Installer::DEFAULT_PLUGINS.merge('cocoapods-keys' => { 'keyring' => 'Eidolon' })
@installer.podfile.stubs(:plugins).returns(plugins_hash)
HooksManager.expects(:run).with(:post_install, context, plugins_hash)
@installer.send(:run_plugins_post_install_hooks)
end
it 'raises if a podfile-specified plugin is not loaded' do
@installer.podfile.stubs(:plugins).returns('cocoapods-keys' => {})
Command::PluginManager.stubs(:specifications).returns([])
should.raise Informative do
@installer.send(:ensure_plugins_are_installed!)
end.message.should.match /require.*plugin.*`cocoapods-keys`/
end
it 'does not raise if all podfile-specified plugins are loaded' do
@installer.podfile.stubs(:plugins).returns('cocoapods-keys' => {})
spec = stub
spec.stubs(:name).returns('cocoapods-keys')
Command::PluginManager.stubs(:specifications).returns([spec])
should.not.raise do
@installer.send(:ensure_plugins_are_installed!)
end
end
end
#-------------------------------------------------------------------------#
describe 'Podfile Hooks' do
before do
podfile = Pod::Podfile.new do
platform :ios
end
@installer = Installer.new(config.sandbox, podfile)
@installer.installation_options.integrate_targets = false
end
it 'runs the pre install hooks' do
@installer.podfile.expects(:pre_install!).with(@installer)
@installer.install!
end
it 'runs the post install hooks' do
@installer.podfile.expects(:post_install!).with(@installer)
@installer.install!
end
end
end
end
Something went wrong with that request. Please try again.