Commit 38391fc7 authored by Dimitris Koutsogiorgas's avatar Dimitris Koutsogiorgas Committed by GitHub

Merge pull request #7014 from dnkoutso/filter_test_only_pod_targets

Use the resolver to identify which pod targets are test only
parents 821f2080 99084c7d
...@@ -34,6 +34,11 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -34,6 +34,11 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[Dimitris Koutsogiorgas](https://github.com/dnkoutso) [Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[#7019](https://github.com/CocoaPods/CocoaPods/pull/7019) [#7019](https://github.com/CocoaPods/CocoaPods/pull/7019)
* Use the resolver to identify which pod targets are test only
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[Justin Martin](https://github.com/justinseanmartin)
[#7014](https://github.com/CocoaPods/CocoaPods/pull/7014)
* Perform code signing on xctest bundles in the Pods project generated by a test spec * Perform code signing on xctest bundles in the Pods project generated by a test spec
[Justin Martin](https://github.com/justinseanmartin) [Justin Martin](https://github.com/justinseanmartin)
[#7013](https://github.com/CocoaPods/CocoaPods/pull/7013) [#7013](https://github.com/CocoaPods/CocoaPods/pull/7013)
......
This diff is collapsed.
...@@ -12,6 +12,39 @@ module Pod ...@@ -12,6 +12,39 @@ module Pod
# by target for a given Podfile. # by target for a given Podfile.
# #
class Resolver class Resolver
# A small container that wraps a resolved specification for a given target definition. Additional metadata
# is included here such as if the specification is only used by tests.
#
class ResolverSpecification
# @return [Specification] the specification that was resolved
#
attr_reader :spec
# @return [Bool] whether this resolved specification is only used by tests.
#
attr_reader :used_by_tests_only
alias used_by_tests_only? used_by_tests_only
def initialize(spec, used_by_tests_only)
@spec = spec
@used_by_tests_only = used_by_tests_only
end
def name
spec.name
end
def root
spec.root
end
def ==(other)
self.class == other &&
spec == other.spec &&
used_by_tests_only == other.test_only
end
end
include Pod::Installer::InstallationOptions::Mixin include Pod::Installer::InstallationOptions::Mixin
delegate_installation_options { podfile } delegate_installation_options { podfile }
...@@ -64,8 +97,8 @@ module Pod ...@@ -64,8 +97,8 @@ module Pod
# Identifies the specifications that should be installed. # Identifies the specifications that should be installed.
# #
# @return [Hash{TargetDefinition => Array<Specification>}] specs_by_target # @return [Hash{TargetDefinition => Array<ResolverSpecification>}] resolver_specs_by_target
# the specifications that need to be installed grouped by target # the resolved specifications that need to be installed grouped by target
# definition. # definition.
# #
def resolve def resolve
...@@ -75,28 +108,28 @@ module Pod ...@@ -75,28 +108,28 @@ module Pod
end end
end end
@activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies) @activated = Molinillo::Resolver.new(self, self).resolve(dependencies, locked_dependencies)
specs_by_target resolver_specs_by_target
rescue Molinillo::ResolverError => e rescue Molinillo::ResolverError => e
handle_resolver_error(e) handle_resolver_error(e)
end end
# @return [Hash{Podfile::TargetDefinition => Array<Specification>}] # @return [Hash{Podfile::TargetDefinition => Array<ResolverSpecification>}]
# returns the resolved specifications grouped by target. # returns the resolved specifications grouped by target.
# #
# @note The returned specifications can be subspecs. # @note The returned specifications can be subspecs.
# #
def specs_by_target def resolver_specs_by_target
@specs_by_target ||= {}.tap do |specs_by_target| @resolver_specs_by_target ||= {}.tap do |resolver_specs_by_target|
podfile.target_definition_list.each do |target| podfile.target_definition_list.each do |target|
dependencies = {} dependencies = {}
specs = target.dependencies.map(&:name).flat_map do |name| specs = target.dependencies.map(&:name).flat_map do |name|
node = @activated.vertex_named(name) node = @activated.vertex_named(name)
valid_dependencies_for_target_from_node(target, dependencies, node) << node (valid_dependencies_for_target_from_node(target, dependencies, node) << node).map { |s| [s, node.payload.test_specification?] }
end end
specs_by_target[target] = specs. resolver_specs_by_target[target] = specs.
map(&:payload). group_by(&:first).
uniq. map { |vertex, spec_test_only_tuples| ResolverSpecification.new(vertex.payload, spec_test_only_tuples.map { |tuple| tuple[1] }.all?) }.
sort_by(&:name) sort_by(&:name)
end end
end end
...@@ -517,7 +550,6 @@ module Pod ...@@ -517,7 +550,6 @@ module Pod
dependency_nodes + dependency_nodes.flat_map do |item| dependency_nodes + dependency_nodes.flat_map do |item|
node_result = valid_dependencies_for_target_from_node(target, dependencies, item) node_result = valid_dependencies_for_target_from_node(target, dependencies, item)
node_result node_result
end end
end end
......
...@@ -672,84 +672,30 @@ module Pod ...@@ -672,84 +672,30 @@ module Pod
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
it 'handles test only pod targets' do it 'does include pod target if any spec is not used by tests only and is part of target definition' do
pod_target_one = stub(:name => 'Pod1', :dependent_targets => [], :test_dependent_targets => []) spec1 = Resolver::ResolverSpecification.new(stub, false)
pod_target_two = stub(:name => 'Pod2', :dependent_targets => [], :test_dependent_targets => []) spec2 = Resolver::ResolverSpecification.new(stub, true)
pod_target_three = stub(:name => 'Pod3', :dependent_targets => [pod_target_one, pod_target_two], :test_dependent_targets => [])
pod_target_four = stub(:name => 'Pod4', :dependent_targets => [], :test_dependent_targets => [pod_target_three])
all_pod_targets = [pod_target_one, pod_target_two, pod_target_three, pod_target_four]
@analyzer.send(:pod_target_test_only?, pod_target_one, all_pod_targets).should.be.false
@analyzer.send(:pod_target_test_only?, pod_target_two, all_pod_targets).should.be.false
@analyzer.send(:pod_target_test_only?, pod_target_three, all_pod_targets).should.be.true
@analyzer.send(:pod_target_test_only?, pod_target_four, all_pod_targets).should.be.false
end
it 'handles test only pod targets that depend on themselves as tests' do
pod_target_one = stub(:name => 'Pod1', :dependent_targets => [])
pod_target_one.stubs(:test_dependent_targets => [pod_target_one])
all_pod_targets = [pod_target_one]
@analyzer.send(:pod_target_test_only?, pod_target_one, all_pod_targets).should.be.false
end
it 'handles test only pod targets that depend on themselves as tests but are also dependent as sources' do
pod_target_one = stub(:name => 'Pod1', :dependent_targets => [])
pod_target_one.stubs(:test_dependent_targets => [pod_target_one])
pod_target_two = stub(:name => 'Pod2', :dependent_targets => [pod_target_one], :test_dependent_targets => [])
all_pod_targets = [pod_target_one, pod_target_two]
@analyzer.send(:pod_target_test_only?, pod_target_one, all_pod_targets).should.be.false
end
it 'includes pod target when declared in the target definition and is not test only' do
target_definition = stub
pod_target = stub(:name => 'Pod1', :dependent_targets => [], :test_dependent_targets => [], :target_definitions => [target_definition])
all_pod_targets = [pod_target]
@analyzer.stubs(:pod_target_test_only?).with(pod_target, all_pod_targets).returns(false)
@analyzer.send(:filter_pod_targets_for_target_definition, all_pod_targets, target_definition).should == [pod_target]
end
it 'includes pod target when declared in the pod target definition but has a test dependency on itself' do
target_definition = stub target_definition = stub
pod_target = stub(:name => 'Pod1', :dependent_targets => [], :target_definitions => [target_definition]) pod_target = stub(:name => 'Pod1', :target_definitions => [target_definition], :specs => [spec1.spec, spec2.spec])
pod_target.stubs(:test_dependent_targets => [pod_target]) resolver_specs_by_target = { target_definition => [spec1, spec2] }
all_pod_targets = [pod_target] @analyzer.send(:filter_pod_targets_for_target_definition, target_definition, [pod_target], resolver_specs_by_target).should == [pod_target]
@analyzer.send(:filter_pod_targets_for_target_definition, all_pod_targets, target_definition).should == [pod_target]
end end
it 'does not include pod target if declared within pod target definition and is a test only target' do it 'does not include pod target if its used by tests only' do
spec1 = Resolver::ResolverSpecification.new(stub, true)
spec2 = Resolver::ResolverSpecification.new(stub, true)
target_definition = stub target_definition = stub
pod_target = stub(:name => 'Pod1', :dependent_targets => [], :test_dependent_targets => [], :target_definitions => [target_definition]) pod_target = stub(:name => 'Pod1', :target_definitions => [target_definition], :specs => [spec1.spec, spec2.spec])
all_pod_targets = [pod_target] resolver_specs_by_target = { target_definition => [spec1, spec2] }
@analyzer.stubs(:pod_target_test_only?).with(pod_target, all_pod_targets).returns(true) @analyzer.send(:filter_pod_targets_for_target_definition, target_definition, [pod_target], resolver_specs_by_target).should.be.empty
@analyzer.send(:filter_pod_targets_for_target_definition, all_pod_targets, target_definition).should.be.empty
end end
it 'does not include pod target if not within target definition' do it 'does not include pod target if its not part of the target definition' do
spec = Resolver::ResolverSpecification.new(stub, false)
target_definition = stub target_definition = stub
pod_target = stub(:name => 'Pod1', :dependent_targets => [], :test_dependent_targets => [], :target_definitions => []) pod_target = stub(:name => 'Pod1', :target_definitions => [], :specs => [spec.spec])
all_pod_targets = [pod_target] resolver_specs_by_target = { target_definition => [spec] }
@analyzer.send(:filter_pod_targets_for_target_definition, all_pod_targets, target_definition).should.be.empty @analyzer.send(:filter_pod_targets_for_target_definition, target_definition, [pod_target], resolver_specs_by_target).should.be.empty
end
it 'handles complicated scenario of pod target dependencies' do
target_definition_one = stub
target_definition_two = stub
pod_target_one = stub(:name => 'Pod1', :dependent_targets => [], :test_dependent_targets => [], :target_definitions => [target_definition_one, target_definition_two])
pod_target_two = stub(:name => 'Pod2', :dependent_targets => [], :test_dependent_targets => [], :target_definitions => [target_definition_one])
pod_target_three = stub(:name => 'Pod3', :dependent_targets => [], :target_definitions => [target_definition_two])
pod_target_three.stubs(:test_dependent_targets => [pod_target_three])
pod_target_four = stub(:name => 'Pod4', :dependent_targets => [pod_target_one], :test_dependent_targets => [], :target_definitions => [target_definition_one])
pod_target_five = stub(:name => 'Pod5', :dependent_targets => [pod_target_one], :test_dependent_targets => [pod_target_three], :target_definitions => [target_definition_two])
all_pod_targets = [pod_target_one, pod_target_two, pod_target_three, pod_target_four, pod_target_five]
@analyzer.send(:filter_pod_targets_for_target_definition, all_pod_targets, target_definition_one).should == [
pod_target_one,
pod_target_two,
pod_target_four,
]
@analyzer.send(:filter_pod_targets_for_target_definition, all_pod_targets, target_definition_two).should == [
pod_target_one,
pod_target_five,
]
end end
describe 'extension targets' do describe 'extension targets' do
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment