Deduplicate test specs correctly from pod variants and targets

parent 7395fa95
...@@ -30,6 +30,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -30,6 +30,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
##### Bug Fixes ##### Bug Fixes
* Deduplicate test specs correctly from pod variants and targets
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[#7036](https://github.com/CocoaPods/CocoaPods/pull/7036)
* Fix common paths sometimes calculating incorrectly * Fix common paths sometimes calculating incorrectly
[amorde](https://github.com/amorde) [amorde](https://github.com/amorde)
[#7028](https://github.com/CocoaPods/CocoaPods/pull/7028) [#7028](https://github.com/CocoaPods/CocoaPods/pull/7028)
......
...@@ -481,16 +481,19 @@ module Pod ...@@ -481,16 +481,19 @@ module Pod
distinct_targets = resolver_specs_by_target.each_with_object({}) do |dependency, hash| distinct_targets = resolver_specs_by_target.each_with_object({}) do |dependency, hash|
target_definition, dependent_specs = *dependency target_definition, dependent_specs = *dependency
dependent_specs.group_by(&:root).each do |root_spec, resolver_specs| dependent_specs.group_by(&:root).each do |root_spec, resolver_specs|
pod_variant = PodVariant.new(resolver_specs.map(&:spec), target_definition.platform, target_definition.uses_frameworks?) all_specs = resolver_specs.map(&:spec)
test_specs, specs = all_specs.partition(&:test_specification?)
pod_variant = PodVariant.new(specs, test_specs, target_definition.platform, target_definition.uses_frameworks?)
hash[root_spec] ||= {} hash[root_spec] ||= {}
(hash[root_spec][pod_variant] ||= []) << target_definition (hash[root_spec][pod_variant] ||= []) << target_definition
hash[root_spec].keys.find { |k| k == pod_variant }.test_specs.concat(test_specs).uniq!
end end
end end
pod_targets = distinct_targets.flat_map do |_root, target_definitions_by_variant| pod_targets = distinct_targets.flat_map do |_root, target_definitions_by_variant|
suffixes = PodVariantSet.new(target_definitions_by_variant.keys).scope_suffixes suffixes = PodVariantSet.new(target_definitions_by_variant.keys).scope_suffixes
target_definitions_by_variant.flat_map do |variant, target_definitions| target_definitions_by_variant.flat_map do |variant, target_definitions|
generate_pod_target(target_definitions, variant.specs, :scope_suffix => suffixes[variant]) generate_pod_target(target_definitions, variant.specs + variant.test_specs, :scope_suffix => suffixes[variant])
end end
end end
......
...@@ -7,6 +7,10 @@ module Pod ...@@ -7,6 +7,10 @@ module Pod
# #
attr_accessor :specs attr_accessor :specs
# @return [Array<Specification>] the test specs for the target
#
attr_accessor :test_specs
# @return [Platform] the platform # @return [Platform] the platform
# #
attr_accessor :platform attr_accessor :platform
...@@ -24,16 +28,21 @@ module Pod ...@@ -24,16 +28,21 @@ module Pod
# Initialize a new instance from its attributes. # Initialize a new instance from its attributes.
# #
# @param [Array<String>] specs @see #specs # @param [Array<Specification>] specs @see #specs
# @param [Platform] platform @see #platform # @param [Array<Specification>] test_specs @see #test_specs
# @param [Bool] requires_frameworks @see #requires_frameworks? # @param [Platform] platform @see #platform
# @param [Bool] requires_frameworks @see #requires_frameworks?
# #
def initialize(specs, platform, requires_frameworks = false) def initialize(specs, test_specs, platform, requires_frameworks = false)
self.specs = specs self.specs = specs
self.test_specs = test_specs
self.platform = platform self.platform = platform
self.requires_frameworks = requires_frameworks self.requires_frameworks = requires_frameworks
end end
# @note Test specs are intentionally not included as part of the equality for pod variants since a
# pod variant should not be affected by the number of test specs included.
#
# @return [Bool] whether the {PodVariant} is equal to another taking all # @return [Bool] whether the {PodVariant} is equal to another taking all
# all their attributes into account # all their attributes into account
# #
......
Subproject commit 1d4e3f9e138e88d73a0546d64979f70ed52b92e2 Subproject commit 50dcbc10e278fc58d5a95e24b11c97bbcc90d0d0
...@@ -14,46 +14,46 @@ module Pod ...@@ -14,46 +14,46 @@ module Pod
PodVariant = Pod::Installer::Analyzer::PodVariant.freeze PodVariant = Pod::Installer::Analyzer::PodVariant.freeze
it 'returns an empty scope if there is only one variant' do it 'returns an empty scope if there is only one variant' do
variants = PodVariantSet.new([PodVariant.new([@root_spec], Platform.ios)]) variants = PodVariantSet.new([PodVariant.new([@root_spec], [], Platform.ios)])
variants.scope_suffixes.values.should == [nil] variants.scope_suffixes.values.should == [nil]
end end
it 'returns scopes by built types if they qualify' do it 'returns scopes by built types if they qualify' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@root_spec], Platform.ios, true), PodVariant.new([@root_spec], [], Platform.ios, true),
PodVariant.new([@root_spec], Platform.ios, false), PodVariant.new([@root_spec], [], Platform.ios, false),
]) ])
variants.scope_suffixes.values.should == %w(framework library) variants.scope_suffixes.values.should == %w(framework library)
end end
it 'returns scopes by platform names if they qualify' do it 'returns scopes by platform names if they qualify' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@root_spec], Platform.ios), PodVariant.new([@root_spec], [], Platform.ios),
PodVariant.new([@root_spec], Platform.osx), PodVariant.new([@root_spec], [], Platform.osx),
]) ])
variants.scope_suffixes.values.should == %w(iOS macOS) variants.scope_suffixes.values.should == %w(iOS macOS)
end end
it 'returns scopes by versioned platform names if they qualify' do it 'returns scopes by versioned platform names if they qualify' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@root_spec], Platform.ios), PodVariant.new([@root_spec], [], Platform.ios),
PodVariant.new([@root_spec], Platform.new(:ios, '7.0')), PodVariant.new([@root_spec], [], Platform.new(:ios, '7.0')),
]) ])
variants.scope_suffixes.values.should == %w(iOS iOS7.0) variants.scope_suffixes.values.should == %w(iOS iOS7.0)
end end
it 'returns scopes by subspec names if they qualify' do it 'returns scopes by subspec names if they qualify' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@foo_subspec], Platform.ios), PodVariant.new([@foo_subspec], [], Platform.ios),
PodVariant.new([@bar_subspec], Platform.ios), PodVariant.new([@bar_subspec], [], Platform.ios),
]) ])
variants.scope_suffixes.values.should == %w(Foo Bar) variants.scope_suffixes.values.should == %w(Foo Bar)
end end
it 'returns scopes by subspec names if they qualify and handle partial root spec presence well' do it 'returns scopes by subspec names if they qualify and handle partial root spec presence well' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@foo_subspec], Platform.ios), PodVariant.new([@foo_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @bar_subspec], Platform.ios), PodVariant.new([@root_spec, @bar_subspec], [], Platform.ios),
]) ])
variants.scope_suffixes.values.should == %w(Foo .root-Bar) variants.scope_suffixes.values.should == %w(Foo .root-Bar)
end end
...@@ -61,36 +61,36 @@ module Pod ...@@ -61,36 +61,36 @@ module Pod
it 'allows to differentiate between an exclusive variant with a specific subspec and ' \ it 'allows to differentiate between an exclusive variant with a specific subspec and ' \
'an inclusive variant with the default subspecs plus a non-default subspec' do 'an inclusive variant with the default subspecs plus a non-default subspec' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@foo_subspec], Platform.ios), PodVariant.new([@foo_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec, @foo_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec, @foo_subspec], [], Platform.ios),
]) ])
variants.scope_suffixes.values.should == %w(Foo .default-Foo) variants.scope_suffixes.values.should == %w(Foo .default-Foo)
end end
it 'omits default specs' do it 'omits default specs' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@root_spec, @default_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec, @foo_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec, @foo_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec, @bar_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec, @bar_subspec], [], Platform.ios),
]) ])
variants.scope_suffixes.values.should == [nil, '.default-Foo', '.default-Bar'] variants.scope_suffixes.values.should == [nil, '.default-Foo', '.default-Bar']
end end
it 'omits common specs' do it 'omits common specs' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@root_spec, @default_subspec, @inner_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec, @inner_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec, @inner_subspec, @foo_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec, @inner_subspec, @foo_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec, @inner_subspec, @bar_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec, @inner_subspec, @bar_subspec], [], Platform.ios),
]) ])
variants.scope_suffixes.values.should == %w(.common .common-Foo .common-Bar) variants.scope_suffixes.values.should == %w(.common .common-Foo .common-Bar)
end end
it 'returns scopes by platform names and subspec names if they qualify' do it 'returns scopes by platform names and subspec names if they qualify' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@root_spec, @default_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec], Platform.osx), PodVariant.new([@root_spec, @default_subspec], [], Platform.osx),
PodVariant.new([@root_spec, @default_subspec, @foo_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec, @foo_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec, @bar_subspec], Platform.osx), PodVariant.new([@root_spec, @default_subspec, @bar_subspec], [], Platform.osx),
]) ])
variants.scope_suffixes.values.should == %w( variants.scope_suffixes.values.should == %w(
iOS iOS
...@@ -103,10 +103,10 @@ module Pod ...@@ -103,10 +103,10 @@ module Pod
it 'hashes scopes that are longer than 50 characters' do it 'hashes scopes that are longer than 50 characters' do
@bar_subspec.name = 'matryoshka/ThisIsAReallyLongSubspecName' @bar_subspec.name = 'matryoshka/ThisIsAReallyLongSubspecName'
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@root_spec, @default_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec], Platform.osx), PodVariant.new([@root_spec, @default_subspec], [], Platform.osx),
PodVariant.new([@root_spec, @default_subspec, @foo_subspec, @bar_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec, @foo_subspec, @bar_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec, @bar_subspec], Platform.osx), PodVariant.new([@root_spec, @default_subspec, @bar_subspec], [], Platform.osx),
]) ])
variants.scope_suffixes.values.should == %w( variants.scope_suffixes.values.should == %w(
iOS iOS
...@@ -118,12 +118,12 @@ module Pod ...@@ -118,12 +118,12 @@ module Pod
it 'returns scopes by versioned platform names and subspec names if they qualify' do it 'returns scopes by versioned platform names and subspec names if they qualify' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@root_spec, @default_subspec], Platform.new(:ios, '7.0')), PodVariant.new([@root_spec, @default_subspec], [], Platform.new(:ios, '7.0')),
PodVariant.new([@root_spec, @default_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec, @foo_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec, @foo_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec], Platform.osx), PodVariant.new([@root_spec, @default_subspec], [], Platform.osx),
PodVariant.new([@root_spec, @default_subspec, @foo_subspec], Platform.osx), PodVariant.new([@root_spec, @default_subspec, @foo_subspec], [], Platform.osx),
PodVariant.new([@root_spec, @default_subspec, @bar_subspec], Platform.osx), PodVariant.new([@root_spec, @default_subspec, @bar_subspec], [], Platform.osx),
]) ])
variants.scope_suffixes.values.should == %w( variants.scope_suffixes.values.should == %w(
iOS7.0 iOS7.0
...@@ -137,10 +137,10 @@ module Pod ...@@ -137,10 +137,10 @@ module Pod
it 'returns scopes by built types, versioned platform names and subspec names' do it 'returns scopes by built types, versioned platform names and subspec names' do
variants = PodVariantSet.new([ variants = PodVariantSet.new([
PodVariant.new([@root_spec, @default_subspec], Platform.new(:ios, '7.0')), PodVariant.new([@root_spec, @default_subspec], [], Platform.new(:ios, '7.0')),
PodVariant.new([@root_spec, @default_subspec], Platform.ios), PodVariant.new([@root_spec, @default_subspec], [], Platform.ios),
PodVariant.new([@root_spec, @default_subspec], Platform.osx, true), PodVariant.new([@root_spec, @default_subspec], [], Platform.osx, true),
PodVariant.new([@root_spec, @default_subspec, @foo_subspec], Platform.osx, true), PodVariant.new([@root_spec, @default_subspec, @foo_subspec], [], Platform.osx, true),
]) ])
variants.scope_suffixes.values.should == %w( variants.scope_suffixes.values.should == %w(
library-iOS7.0 library-iOS7.0
......
...@@ -6,18 +6,19 @@ module Pod ...@@ -6,18 +6,19 @@ module Pod
describe PodVariant do describe PodVariant do
before do before do
@specs = [stub('Spec'), stub('Spec/Foo')] @specs = [stub('Spec'), stub('Spec/Foo')]
@testspecs = [stub('Spec/Tests')]
@platform = Platform.ios @platform = Platform.ios
end end
it 'can be initialized with specs and platform' do it 'can be initialized with specs and platform' do
variant = PodVariant.new(@specs, @platform) variant = PodVariant.new(@specs, [], @platform)
variant.specs.should == @specs variant.specs.should == @specs
variant.platform.should == @platform variant.platform.should == @platform
variant.requires_frameworks.should == false variant.requires_frameworks.should == false
end end
it 'can be initialized with specs, platform and whether it requires frameworks' do it 'can be initialized with specs, platform and whether it requires frameworks' do
variant = PodVariant.new(@specs, @platform, true) variant = PodVariant.new(@specs, [], @platform, true)
variant.specs.should == @specs variant.specs.should == @specs
variant.platform.should == @platform variant.platform.should == @platform
variant.requires_frameworks.should == true variant.requires_frameworks.should == true
...@@ -25,27 +26,33 @@ module Pod ...@@ -25,27 +26,33 @@ module Pod
it 'can return the root spec' do it 'can return the root spec' do
spec = fixture_spec('banana-lib/BananaLib.podspec') spec = fixture_spec('banana-lib/BananaLib.podspec')
variant = PodVariant.new([spec], Platform.ios) variant = PodVariant.new([spec], [], Platform.ios)
variant.root_spec.should == spec variant.root_spec.should == spec
end end
it 'can be compared for equality with another variant with the same specs, platform, and whether it requires frameworks' do it 'can be compared for equality with another variant with the same specs, platform, and whether it requires frameworks' do
spec = PodVariant.new(@specs, @platform, false) spec = PodVariant.new(@specs, [], @platform, false)
spec.should == PodVariant.new(@specs, @platform, false) spec.should == PodVariant.new(@specs, [], @platform, false)
spec.should.not == PodVariant.new([@specs.first], @platform) spec.should.not == PodVariant.new([@specs.first], [], @platform)
spec.should.not == PodVariant.new(@specs, Platform.osx, false) spec.should.not == PodVariant.new(@specs, [], Platform.osx, false)
spec.should.not == PodVariant.new(@specs, @platform, true) spec.should.not == PodVariant.new(@specs, [], @platform, true)
end end
it 'can be used as hash keys' do it 'can be used as hash keys' do
k0 = PodVariant.new(@specs, @platform, false) k0 = PodVariant.new(@specs, [], @platform, false)
v0 = stub('Value at index 0') v0 = stub('Value at index 0')
k1 = PodVariant.new(@specs, @platform, true) k1 = PodVariant.new(@specs, [], @platform, true)
v1 = stub('Value at index 1') v1 = stub('Value at index 1')
hash = { k0 => v0, k1 => v1 } hash = { k0 => v0, k1 => v1 }
hash[k0].should == v0 hash[k0].should == v0
hash[k1].should == v1 hash[k1].should == v1
end end
it 'does not use testspecs for equality' do
k0 = PodVariant.new(@specs, @testspecs, @platform, false)
k1 = PodVariant.new(@specs, [], @platform, false)
k0.should == k1
end
end end
end end
end end
......
...@@ -245,6 +245,31 @@ module Pod ...@@ -245,6 +245,31 @@ module Pod
matryoshka/Outer/Inner matryoshka/Outer/Inner
) )
end end
it 'does not create multiple variants across different targets that require different set of testspecs' do
@podfile = Pod::Podfile.new do
source SpecHelper.test_repo_url
platform :ios, '8.0'
project 'SampleProject/SampleProject'
target 'TestRunner' do
pod 'CoconutLib', :testspecs => ['Tests']
end
target 'SampleProject' do
pod 'CoconutLib'
end
end
@analyzer = Pod::Installer::Analyzer.new(config.sandbox, @podfile, nil)
result = @analyzer.analyze
result.targets.count.should == 2
result.targets[0].pod_targets.count == 1
result.targets[0].pod_targets[0].name.should == 'CoconutLib'
result.targets[1].pod_targets.count == 1
result.targets[1].pod_targets[0].name.should == 'CoconutLib'
result.targets[0].pod_targets[0].should == result.targets[1].pod_targets[0]
end
end end
describe 'deduplication' do describe 'deduplication' do
......
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