Add app host support for test specs

parent 417503d9
...@@ -12,6 +12,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre` ...@@ -12,6 +12,10 @@ To install release candidates run `[sudo] gem install cocoapods --pre`
[Paul Beusterien](https://github.com/paulb777) [Paul Beusterien](https://github.com/paulb777)
[#7044](https://github.com/CocoaPods/CocoaPods/pull/7044) [#7044](https://github.com/CocoaPods/CocoaPods/pull/7044)
* Add app host support for test specs
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
[#6953](https://github.com/CocoaPods/CocoaPods/issues/6953)
##### Bug Fixes ##### Bug Fixes
* Fix framework and resources paths caching * Fix framework and resources paths caching
......
...@@ -66,6 +66,7 @@ module Pod ...@@ -66,6 +66,7 @@ module Pod
autoload :PrefixHeader, 'cocoapods/generator/prefix_header' autoload :PrefixHeader, 'cocoapods/generator/prefix_header'
autoload :UmbrellaHeader, 'cocoapods/generator/umbrella_header' autoload :UmbrellaHeader, 'cocoapods/generator/umbrella_header'
autoload :XCConfig, 'cocoapods/generator/xcconfig' autoload :XCConfig, 'cocoapods/generator/xcconfig'
autoload :AppTargetHelper, 'cocoapods/generator/app_target_helper'
end end
require 'cocoapods/core_overrides' require 'cocoapods/core_overrides'
......
module Pod
module Generator
# Stores the common logic for creating app targets within projects including
# generating standard import and main files for app hosts.
#
module AppTargetHelper
# Adds a single app target to the given project with the provided name.
#
# @param [Project] project
# the Xcodeproj to generate the target into.
#
# @param [Symbol] platform
# the platform of the target. Can be `:ios` or `:osx`, etc.
#
# @param [String] deployment_target
# the deployment target for the platform.
#
# @param [String] name
# The name to use for the target, defaults to 'App'.
#
# @return [PBXNativeTarget] the new target that was created.
#
def self.add_app_target(project, platform, deployment_target, name = 'App')
project.new_target(:application, name, platform, deployment_target)
end
# Creates and links an import file for the given pod target and into the given native target.
#
# @param [Project] project
# the Xcodeproj to generate the target into.
#
# @param [PBXNativeTarget] target
# the native target to link the generated import file into.
#
# @param [PodTarget] pod_target
# the pod target to use for when generating the contents of the import file.
#
# @param [Symbol] platform
# the platform of the target. Can be `:ios` or `:osx`, etc.
#
# @param [Boolean] use_frameworks
# whether to use frameworks or not when generating the contents of the import file.
#
# @param [String] name
# The name to use for the target, defaults to 'App'.
#
# @return [Array<PBXBuildFile>] the created build file references.
#
def self.add_app_project_import(project, target, pod_target, platform, use_frameworks, name = 'App')
source_file = AppTargetHelper.create_app_import_source_file(project, pod_target, platform, use_frameworks, name)
source_file_ref = project.new_group(name, name).new_file(source_file)
target.add_file_references([source_file_ref])
end
# Creates and links a default app host 'main.m' file.
#
# @param [Project] project
# the Xcodeproj to generate the target into.
#
# @param [PBXNativeTarget] target
# the native target to link the generated main file into.
#
# @param [Symbol] platform
# the platform of the target. Can be `:ios` or `:osx`, etc.
#
# @param [String] name
# The name to use for the target, defaults to 'App'.
#
# @return [Array<PBXBuildFile>] the created build file references.
#
def self.add_app_host_main_file(project, target, platform, name = 'App')
source_file = AppTargetHelper.create_app_host_main_file(project, platform, name)
source_file_ref = project.new_group(name, name).new_file(source_file)
target.add_file_references([source_file_ref])
end
# Adds the xctest framework search paths into the given target.
#
# @param [PBXNativeTarget] target
# the native target to add XCTest into.
#
# @return [void]
#
def self.add_xctest_search_paths(target)
target.build_configurations.each do |configuration|
search_paths = configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] ||= '$(inherited)'
search_paths << ' "$(PLATFORM_DIR)/Developer/Library/Frameworks"'
end
end
# Adds the provided swift version into the given target.
#
# @param [PBXNativeTarget] target
# the native target to add the swift version into.
#
# @param [String] swift_version
# the swift version to set to.
#
# @return [void]
#
def self.add_swift_version(target, swift_version)
target.build_configurations.each do |configuration|
configuration.build_settings['SWIFT_VERSION'] = swift_version
end
end
# Creates a default import file for the given pod target.
#
# @param [Project] project
# the Xcodeproj to generate the target into.
#
# @param [PodTarget] pod_target
# the pod target to use for when generating the contents of the import file.
#
# @param [Symbol] platform
# the platform of the target. Can be `:ios` or `:osx`, etc.
#
# @param [Boolean] use_frameworks
# whether to use frameworks or not when generating the contents of the import file.
#
# @param [String] name
# The name of the folder to use and save the generated main file.
#
# @return [Pathname] the new source file that was generated.
#
def self.create_app_import_source_file(project, pod_target, platform, use_frameworks, name = 'App')
language = pod_target.uses_swift? ? :swift : :objc
if language == :swift
source_file = project.path.dirname.+("#{name}/main.swift")
source_file.parent.mkpath
import_statement = use_frameworks && pod_target.should_build? ? "import #{pod_target.product_module_name}\n" : ''
source_file.open('w') { |f| f << import_statement }
else
source_file = project.path.dirname.+("#{name}/main.m")
source_file.parent.mkpath
import_statement = if use_frameworks && pod_target.should_build?
"@import #{pod_target.product_module_name};\n"
else
header_name = "#{pod_target.product_module_name}/#{pod_target.product_module_name}.h"
if pod_target.sandbox.public_headers.root.+(header_name).file?
"#import <#{header_name}>\n"
else
''
end
end
source_file.open('w') do |f|
f << "@import Foundation;\n"
f << "@import UIKit;\n" if platform == :ios || platform == :tvos
f << "@import Cocoa;\n" if platform == :osx
f << "#{import_statement}int main() {}\n"
end
end
source_file
end
# Creates a default app host 'main.m' file.
#
# @param [Project] project
# the Xcodeproj to generate the target into.
#
# @param [Symbol] platform
# the platform of the target. Can be `:ios` or `:osx`.
#
# @param [String] name
# The name of the folder to use and save the generated main file.
#
# @return [Pathname] the new source file that was generated.
#
def self.create_app_host_main_file(project, platform, name = 'App')
source_file = project.path.dirname.+("#{name}/main.m")
source_file.parent.mkpath
source_file.open('w') do |f|
case platform
when :ios, :tvos
f << IOS_APP_HOST_MAIN_CONTENTS
when :osx
f << MACOS_APP_APP_HOST_MAIN_CONTENTS
end
end
source_file
end
IOS_APP_HOST_MAIN_CONTENTS = <<EOS.freeze
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface CPTestAppHostAppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, strong) UIWindow *window;
@end
@implementation CPTestAppHostAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [UIViewController new];
[self.window makeKeyAndVisible];
return YES;
}
@end
int main(int argc, char *argv[])
{
@autoreleasepool
{
return UIApplicationMain(argc, argv, nil, NSStringFromClass([CPTestAppHostAppDelegate class]));
}
}
EOS
MACOS_APP_APP_HOST_MAIN_CONTENTS = <<EOS.freeze
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
return NSApplicationMain(argc, argv);
}
EOS
end
end
end
...@@ -5,9 +5,13 @@ module Pod ...@@ -5,9 +5,13 @@ module Pod
# framework. It states public attributes. # framework. It states public attributes.
# #
class InfoPlistFile class InfoPlistFile
# @return [Target] the target represented by this Info.plist. # @return [Version] version The version to use for when generating this Info.plist file.
# #
attr_reader :target attr_reader :version
# @return [Platform] The platform to use for when generating this Info.plist file.
#
attr_reader :platform
# @return [Symbol] the CFBundlePackageType of the target this Info.plist # @return [Symbol] the CFBundlePackageType of the target this Info.plist
# file is for. # file is for.
...@@ -16,12 +20,13 @@ module Pod ...@@ -16,12 +20,13 @@ module Pod
# Initialize a new instance # Initialize a new instance
# #
# @param [Target] target @see target # @param [Version] version @see version
# # @param [Platform] platform @see platform
# @param [Symbol] bundle_package_type @see bundle_package_type # @param [Symbol] bundle_package_type @see bundle_package_type
# #
def initialize(target, bundle_package_type: :fmwk) def initialize(version, platform, bundle_package_type = :fmwk)
@target = target @version = version
@platform = platform
@bundle_package_type = bundle_package_type @bundle_package_type = bundle_package_type
end end
...@@ -39,21 +44,6 @@ module Pod ...@@ -39,21 +44,6 @@ module Pod
end end
end end
# The version associated with the current target
#
# @note Will return 1.0.0 for the AggregateTarget
#
# @return [String]
#
def target_version
if target && target.respond_to?(:root_spec)
version = target.root_spec.version
[version.major, version.minor, version.patch].join('.')
else
'1.0.0'
end
end
# Generates the contents of the Info.plist # Generates the contents of the Info.plist
# #
# @return [String] # @return [String]
...@@ -108,7 +98,7 @@ module Pod ...@@ -108,7 +98,7 @@ module Pod
'CFBundleInfoDictionaryVersion' => '6.0', 'CFBundleInfoDictionaryVersion' => '6.0',
'CFBundleName' => '${PRODUCT_NAME}', 'CFBundleName' => '${PRODUCT_NAME}',
'CFBundlePackageType' => bundle_package_type.to_s.upcase, 'CFBundlePackageType' => bundle_package_type.to_s.upcase,
'CFBundleShortVersionString' => target_version, 'CFBundleShortVersionString' => version,
'CFBundleSignature' => '????', 'CFBundleSignature' => '????',
'CFBundleVersion' => '${CURRENT_PROJECT_VERSION}', 'CFBundleVersion' => '${CURRENT_PROJECT_VERSION}',
'NSPrincipalClass' => '', 'NSPrincipalClass' => '',
...@@ -117,6 +107,7 @@ module Pod ...@@ -117,6 +107,7 @@ module Pod
info['CFBundleExecutable'] = '${EXECUTABLE_NAME}' if bundle_package_type != :bndl info['CFBundleExecutable'] = '${EXECUTABLE_NAME}' if bundle_package_type != :bndl
info['CFBundleVersion'] = '1' if bundle_package_type == :bndl info['CFBundleVersion'] = '1' if bundle_package_type == :bndl
info['NSPrincipalClass'] = 'NSApplication' if bundle_package_type == :appl && platform == :osx
info info
end end
......
...@@ -287,11 +287,16 @@ module Pod ...@@ -287,11 +287,16 @@ module Pod
def add_pod_target_test_dependencies(pod_target, frameworks_group) def add_pod_target_test_dependencies(pod_target, frameworks_group)
test_dependent_targets = pod_target.all_test_dependent_targets test_dependent_targets = pod_target.all_test_dependent_targets
pod_target.test_native_targets.each do |test_native_target| pod_target.test_specs_by_native_target.each do |test_native_target, test_specs|
test_dependent_targets.reject(&:should_build?).each do |test_dependent_target| test_dependent_targets.reject(&:should_build?).each do |test_dependent_target|
add_resource_bundles_to_native_target(test_dependent_target, test_native_target) add_resource_bundles_to_native_target(test_dependent_target, test_native_target)
end end
add_dependent_targets_to_native_target(test_dependent_targets, test_native_target, false, pod_target.requires_frameworks?, frameworks_group) add_dependent_targets_to_native_target(test_dependent_targets, test_native_target, false, pod_target.requires_frameworks?, frameworks_group)
test_spec_consumers = test_specs.map { |test_spec| test_spec.consumer(pod_target.platform) }
if test_spec_consumers.any?(&:requires_app_host?)
app_host_target = project.targets.find { |t| t.name == pod_target.app_host_label(test_specs.first.test_type) }
test_native_target.add_dependency(app_host_target)
end
end end
end end
......
...@@ -17,7 +17,7 @@ module Pod ...@@ -17,7 +17,7 @@ module Pod
create_support_files_group create_support_files_group
create_xcconfig_file create_xcconfig_file
if target.requires_frameworks? if target.requires_frameworks?
create_info_plist_file create_info_plist_file(target.info_plist_path, native_target, target.version, target.platform)
create_module_map create_module_map
create_umbrella_header create_umbrella_header
end end
......
...@@ -19,14 +19,17 @@ module Pod ...@@ -19,14 +19,17 @@ module Pod
UI.message "- Installing target `#{target.name}` #{target.platform}" do UI.message "- Installing target `#{target.name}` #{target.platform}" do
add_target add_target
create_support_files_dir create_support_files_dir
add_test_targets if target.contains_test_specifications? if target.contains_test_specifications?
add_test_targets
add_test_app_host_targets
end
add_resources_bundle_targets add_resources_bundle_targets
add_files_to_build_phases add_files_to_build_phases
create_xcconfig_file create_xcconfig_file
create_test_xcconfig_files if target.contains_test_specifications? create_test_xcconfig_files if target.contains_test_specifications?
if target.requires_frameworks? if target.requires_frameworks?
unless target.static_framework? unless target.static_framework?
create_info_plist_file create_info_plist_file(target.info_plist_path, native_target, target.version, target.platform)
end end
create_module_map create_module_map
create_umbrella_header do |generator| create_umbrella_header do |generator|
...@@ -180,6 +183,42 @@ module Pod ...@@ -180,6 +183,42 @@ module Pod
end end
end end
# Adds the test app host targets for the library to the Pods project with the
# appropriate build configurations.
#
# @return [void]
#
def add_test_app_host_targets
target.test_specs.each do |test_spec|
next unless test_spec.consumer(target.platform).requires_app_host?
name = target.app_host_label(test_spec.test_type)
platform_name = target.platform.name
app_host_target = project.targets.find { |t| t.name == name }
if app_host_target.nil?
app_host_target = Pod::Generator::AppTargetHelper.add_app_target(project, platform_name, deployment_target, name)
app_host_target.build_configurations.each do |configuration|
configuration.build_settings.merge!(custom_build_settings)
configuration.build_settings['PRODUCT_NAME'] = name
configuration.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}'
end
Pod::Generator::AppTargetHelper.add_app_host_main_file(project, app_host_target, platform_name, name)
app_host_info_plist_path = project.path.dirname.+("#{name}/Info.plist")
create_info_plist_file(app_host_info_plist_path, app_host_target, '1.0.0', target.platform, :appl)
end
# Wire all test native targets with the app host.
native_test_target = target.native_target_for_spec(test_spec)
native_test_target.build_configurations.each do |configuration|
test_host = "$(BUILT_PRODUCTS_DIR)/#{name}.app/"
test_host << 'Contents/MacOS/' if target.platform == :osx
test_host << name.to_s
configuration.build_settings['TEST_HOST'] = test_host
end
target_attributes = project.root_object.attributes['TargetAttributes'] || {}
target_attributes[native_test_target.uuid.to_s] = { 'TestTargetID' => app_host_target.uuid.to_s }
project.root_object.attributes['TargetAttributes'] = target_attributes
end
end
# Adds the test targets for the library to the Pods project with the # Adds the test targets for the library to the Pods project with the
# appropriate build configurations. # appropriate build configurations.
# #
...@@ -267,7 +306,7 @@ module Pod ...@@ -267,7 +306,7 @@ module Pod
path = target.info_plist_path path = target.info_plist_path
path.dirname.mkdir unless path.dirname.exist? path.dirname.mkdir unless path.dirname.exist?
info_plist_path = path.dirname + "ResourceBundle-#{bundle_name}-#{path.basename}" info_plist_path = path.dirname + "ResourceBundle-#{bundle_name}-#{path.basename}"
generator = Generator::InfoPlistFile.new(target, :bundle_package_type => :bndl) generator = Generator::InfoPlistFile.new(target.version, target.platform, :bndl)
update_changed_file(generator, info_plist_path) update_changed_file(generator, info_plist_path)
add_file_to_support_group(info_plist_path) add_file_to_support_group(info_plist_path)
......
...@@ -136,12 +136,26 @@ module Pod ...@@ -136,12 +136,26 @@ module Pod
# Creates the Info.plist file which sets public framework attributes # Creates the Info.plist file which sets public framework attributes
# #
# @param [Pathname] path
# the path to save the generated Info.plist file.
#
# @param [PBXNativeTarget] native_target
# the native target to link the generated Info.plist file into.
#
# @param [Version] version
# the version to use for when generating this Info.plist file.
#
# @param [Platform] platform
# the platform to use for when generating this Info.plist file.
#
# @param [Symbol] bundle_package_type
# the CFBundlePackageType of the target this Info.plist file is for.
#
# @return [void] # @return [void]
# #
def create_info_plist_file def create_info_plist_file(path, native_target, version, platform, bundle_package_type = :fmwk)
path = target.info_plist_path
UI.message "- Generating Info.plist file at #{UI.path(path)}" do UI.message "- Generating Info.plist file at #{UI.path(path)}" do
generator = Generator::InfoPlistFile.new(target) generator = Generator::InfoPlistFile.new(version, platform, bundle_package_type)
update_changed_file(generator, path) update_changed_file(generator, path)
add_file_to_support_group(path) add_file_to_support_group(path)
......
...@@ -6,6 +6,8 @@ module Pod ...@@ -6,6 +6,8 @@ module Pod
# This class is used to represent both the targets and their libraries. # This class is used to represent both the targets and their libraries.
# #
class Target class Target
DEFAULT_VERSION = '1.0.0'.freeze
# @return [Sandbox] The sandbox where the Pods should be installed. # @return [Sandbox] The sandbox where the Pods should be installed.
# #
attr_reader :sandbox attr_reader :sandbox
...@@ -180,6 +182,12 @@ module Pod ...@@ -180,6 +182,12 @@ module Pod
support_files_dir + "#{label}-dummy.m" support_files_dir + "#{label}-dummy.m"
end end
# @return [String] The version associated with this target
#
def version
DEFAULT_VERSION
end
#-------------------------------------------------------------------------# #-------------------------------------------------------------------------#
private private
......
...@@ -185,16 +185,29 @@ module Pod ...@@ -185,16 +185,29 @@ module Pod
end end
end end
# @return [Hash{Array => Specification}] a hash where the keys are the test native targets and the value
# an array of all the test specs associated with this native target.
#
def test_specs_by_native_target
test_specs.group_by { |test_spec| native_target_for_spec(test_spec) }
end
# @return [Boolean] Whether the target has any tests specifications. # @return [Boolean] Whether the target has any tests specifications.
# #
def contains_test_specifications? def contains_test_specifications?
specs.any?(&:test_specification?) specs.any?(&:test_specification?)
end end
# @return [Array<Specification>] All of the test specs within this target.
#
def test_specs
specs.select(&:test_specification?)
end
# @return [Array<Symbol>] All of the test supported types within this target. # @return [Array<Symbol>] All of the test supported types within this target.
# #
def supported_test_types def supported_test_types
specs.select(&:test_specification?).map(&:test_type).uniq test_specs.map(&:test_type).uniq
end end
# Returns the framework paths associated with this target. By default all paths include the framework paths # Returns the framework paths associated with this target. By default all paths include the framework paths
...@@ -344,6 +357,15 @@ module Pod ...@@ -344,6 +357,15 @@ module Pod
"#{label}-#{test_type.capitalize}-Tests" "#{label}-#{test_type.capitalize}-Tests"
end end
# @param [Symbol] test_type
# The test type to use for producing the test label.
#
# @return [String] The label of the app host label to use given the platform and test type.
#
def app_host_label(test_type)
"AppHost-#{Platform.string_name(platform.symbolic_name)}-#{test_type.capitalize}-Tests"
end
# @param [Symbol] test_type # @param [Symbol] test_type
# The test type this embed frameworks script path is for. # The test type this embed frameworks script path is for.
# #
...@@ -497,6 +519,13 @@ module Pod ...@@ -497,6 +519,13 @@ module Pod
"${PODS_ROOT}/#{sandbox.pod_dir(pod_name).relative_path_from(sandbox.root)}" "${PODS_ROOT}/#{sandbox.pod_dir(pod_name).relative_path_from(sandbox.root)}"
end end
# @return [String] The version associated with this target
#
def version
version = root_spec.version
[version.major, version.minor, version.patch].join('.')
end
private private
# @param [TargetDefinition] target_definition # @param [TargetDefinition] target_definition
......
...@@ -439,71 +439,24 @@ module Pod ...@@ -439,71 +439,24 @@ module Pod
def create_app_project def create_app_project
app_project = Xcodeproj::Project.new(validation_dir + 'App.xcodeproj') app_project = Xcodeproj::Project.new(validation_dir + 'App.xcodeproj')
app_project.new_target(:application, 'App', consumer.platform_name, deployment_target) Pod::Generator::AppTargetHelper.add_app_target(app_project, consumer.platform_name, deployment_target)
app_project.save app_project.save
app_project.recreate_user_schemes app_project.recreate_user_schemes
end end
def add_app_project_import def add_app_project_import
app_project = Xcodeproj::Project.open(validation_dir + 'App.xcodeproj') app_project = Xcodeproj::Project.open(validation_dir + 'App.xcodeproj')
pod_target = @installer.pod_targets.find { |pt| pt.pod_name == spec.root.name }
source_file = write_app_import_source_file(pod_target)
source_file_ref = app_project.new_group('App', 'App').new_file(source_file)
app_target = app_project.targets.first app_target = app_project.targets.first
app_target.add_file_references([source_file_ref]) pod_target = @installer.pod_targets.find { |pt| pt.pod_name == spec.root.name }
add_swift_version(app_target) Pod::Generator::AppTargetHelper.add_app_project_import(app_project, app_target, pod_target, consumer.platform_name, use_frameworks)
add_xctest(app_target) if @installer.pod_targets.any? { |pt| pt.spec_consumers.any? { |c| c.frameworks.include?('XCTest') } } Pod::Generator::AppTargetHelper.add_swift_version(app_target, swift_version)
Pod::Generator::AppTargetHelper.add_xctest_search_paths(app_target) if @installer.pod_targets.any? { |pt| pt.spec_consumers.any? { |c| c.frameworks.include?('XCTest') } }
app_project.save app_project.save
Xcodeproj::XCScheme.share_scheme(app_project.path, 'App') Xcodeproj::XCScheme.share_scheme(app_project.path, 'App')
# Share the pods xcscheme only if it exists. For pre-built vendored pods there is no xcscheme generated. # Share the pods xcscheme only if it exists. For pre-built vendored pods there is no xcscheme generated.
Xcodeproj::XCScheme.share_scheme(@installer.pods_project.path, pod_target.label) if shares_pod_target_xcscheme?(pod_target) Xcodeproj::XCScheme.share_scheme(@installer.pods_project.path, pod_target.label) if shares_pod_target_xcscheme?(pod_target)
end end
def add_swift_version(app_target)
app_target.build_configurations.each do |configuration|
configuration.build_settings['SWIFT_VERSION'] = swift_version
end
end
def add_xctest(app_target)
app_target.build_configurations.each do |configuration|
search_paths = configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] ||= '$(inherited)'
search_paths << ' "$(PLATFORM_DIR)/Developer/Library/Frameworks"'
end
end
def write_app_import_source_file(pod_target)
language = pod_target.uses_swift? ? :swift : :objc
if language == :swift
source_file = validation_dir.+('App/main.swift')
source_file.parent.mkpath
import_statement = use_frameworks && pod_target.should_build? ? "import #{pod_target.product_module_name}\n" : ''
source_file.open('w') { |f| f << import_statement }
else
source_file = validation_dir.+('App/main.m')
source_file.parent.mkpath
import_statement = if use_frameworks && pod_target.should_build?
"@import #{pod_target.product_module_name};\n"
else
header_name = "#{pod_target.product_module_name}/#{pod_target.product_module_name}.h"
if pod_target.sandbox.public_headers.root.+(header_name).file?
"#import <#{header_name}>\n"
else
''
end
end
source_file.open('w') do |f|
f << "@import Foundation;\n"
f << "@import UIKit;\n" if consumer.platform_name == :ios || consumer.platform_name == :tvos
f << "@import Cocoa;\n" if consumer.platform_name == :osx
f << "#{import_statement}int main() {}\n"
end
end
source_file
end
# It creates a podfile in memory and builds a library containing the pod # It creates a podfile in memory and builds a library containing the pod
# for all available platforms with xcodebuild. # for all available platforms with xcodebuild.
# #
......
require File.expand_path('../../../spec_helper', __FILE__)
module Pod
module Generator
module AppTargetHelper
describe 'creating the import file' do
describe 'when linting as a framework' do
it 'creates a swift import' do
pod_target = stub(:uses_swift? => true, :should_build? => true, :product_module_name => 'ModuleName', :name => 'ModuleName')
project = stub(:path => Pathname(Dir.mktmpdir(['CocoaPods-Lint-', "-#{pod_target.name}"])) + 'App.xcodeproj')
file = AppTargetHelper.create_app_import_source_file(project, pod_target, :ios, true)
file.basename.to_s.should == 'main.swift'
file.read.should == <<-SWIFT.strip_heredoc
import ModuleName
SWIFT
end
it 'creates an objective-c import' do
pod_target = stub(:uses_swift? => false, :should_build? => true, :product_module_name => 'ModuleName', :name => 'ModuleName')
project = stub(:path => Pathname(Dir.mktmpdir(['CocoaPods-Lint-', "-#{pod_target.name}"])) + 'App.xcodeproj')
file = AppTargetHelper.create_app_import_source_file(project, pod_target, :ios, true)
file.basename.to_s.should == 'main.m'
file.read.should == <<-OBJC.strip_heredoc
@import Foundation;
@import UIKit;
@import ModuleName;
int main() {}
OBJC
end
it 'creates no import when the pod target has no source files' do
pod_target = stub(:uses_swift? => true, :should_build? => false, :name => 'ModuleName')
project = stub(:path => Pathname(Dir.mktmpdir(['CocoaPods-Lint-', "-#{pod_target.name}"])) + 'App.xcodeproj')
file = AppTargetHelper.create_app_import_source_file(project, pod_target, :ios, true)
file.basename.to_s.should == 'main.swift'
file.read.should == ''
end
end
describe 'when linting as a static lib' do
before do
@sandbox = config.sandbox
end
it 'creates an objective-c import when a plausible umbrella header is found' do
pod_target = stub(:uses_swift? => false, :should_build? => true, :product_module_name => 'ModuleName', :name => 'ModuleName', :sandbox => @sandbox)
project = stub(:path => Pathname(Dir.mktmpdir(['CocoaPods-Lint-', "-#{pod_target.name}"])) + 'App.xcodeproj')
header_name = "#{pod_target.product_module_name}/#{pod_target.product_module_name}.h"
umbrella = pod_target.sandbox.public_headers.root.+(header_name)
umbrella.dirname.mkpath
umbrella.open('w') {}
file = AppTargetHelper.create_app_import_source_file(project, pod_target, :ios, false)
file.basename.to_s.should == 'main.m'
file.read.should == <<-OBJC.strip_heredoc
@import Foundation;
@import UIKit;
#import <ModuleName/ModuleName.h>
int main() {}
OBJC
end
it 'does not create an objective-c import when no umbrella header is found' do
pod_target = stub(:uses_swift? => false, :should_build? => true, :product_module_name => 'ModuleName', :name => 'ModuleName', :sandbox => @sandbox)
project = stub(:path => Pathname(Dir.mktmpdir(['CocoaPods-Lint-', "-#{pod_target.name}"])) + 'App.xcodeproj')
file = AppTargetHelper.create_app_import_source_file(project, pod_target, :ios, false)
file.basename.to_s.should == 'main.m'
file.read.should == <<-OBJC.strip_heredoc
@import Foundation;
@import UIKit;
int main() {}
OBJC
end
end
end
describe 'creating an app host main file' do
it 'creates correct main file for iOS' do
pod_target = stub(:uses_swift? => false, :should_build? => true, :product_module_name => 'ModuleName', :name => 'ModuleName', :sandbox => @sandbox)
project = stub(:path => Pathname(Dir.mktmpdir(['CocoaPods-Lint-', "-#{pod_target.name}"])) + 'App.xcodeproj')
file = AppTargetHelper.create_app_host_main_file(project, :ios)
file.basename.to_s.should == 'main.m'
file.read.should == AppTargetHelper::IOS_APP_HOST_MAIN_CONTENTS
end
it 'creates correct main file for macOS' do
pod_target = stub(:uses_swift? => false, :should_build? => true, :product_module_name => 'ModuleName', :name => 'ModuleName', :sandbox => @sandbox)
project = stub(:path => Pathname(Dir.mktmpdir(['CocoaPods-Lint-', "-#{pod_target.name}"])) + 'App.xcodeproj')
file = AppTargetHelper.create_app_host_main_file(project, :osx)
file.basename.to_s.should == 'main.m'
file.read.should == AppTargetHelper::MACOS_APP_APP_HOST_MAIN_CONTENTS
end
end
end
end
end
...@@ -2,56 +2,13 @@ require File.expand_path('../../../spec_helper', __FILE__) ...@@ -2,56 +2,13 @@ require File.expand_path('../../../spec_helper', __FILE__)
module Pod module Pod
describe Generator::InfoPlistFile do describe Generator::InfoPlistFile do
describe '#target_version' do
it 'returns 1.0.0 for the aggregate target' do
generator = Generator::InfoPlistFile.new(fixture_aggregate_target)
generator.target_version.should == '1.0.0'
end
describe 'sanitization' do
before do
@root_spec = mock('RootSpec')
@platform = stub('Platform', :name => :ios)
pod_target = stub('PodTarget', :root_spec => @root_spec, :platform => @platform)
@generator = Generator::InfoPlistFile.new(pod_target)
end
it 'handles when the version is more than 3 numeric parts' do
version = Version.new('0.2.0.1')
@root_spec.stubs(:version).returns(version)
@generator.target_version.should == '0.2.0'
end
it 'handles when the version is less than 3 numeric parts' do
version = Version.new('0.2')
@root_spec.stubs(:version).returns(version)
@generator.target_version.should == '0.2.0'
end
it 'handles when the version is a pre-release' do
version = Version.new('1.0.0-beta.1')
@root_spec.stubs(:version).returns(version)
@generator.target_version.should == '1.0.0'
version = Version.new('1.0-beta.5')
@root_spec.stubs(:version).returns(version)
@generator.target_version.should == '1.0.0'
end
end
it 'returns the specification\'s version for the pod target' do
generator = Generator::InfoPlistFile.new(fixture_pod_target('orange-framework/OrangeFramework.podspec'))
generator.target_version.should == '0.1.0'
end
end
it 'replaces the version in the generated plist' do it 'replaces the version in the generated plist' do
generator = Generator::InfoPlistFile.new(fixture_pod_target('orange-framework/OrangeFramework.podspec')) generator = Generator::InfoPlistFile.new('0.1.0', Platform.new(:ios, '6.0'))
generator.generate.should.include "<key>CFBundleShortVersionString</key>\n <string>0.1.0</string>" generator.generate.should.include "<key>CFBundleShortVersionString</key>\n <string>0.1.0</string>"
end end
it 'generates a valid Info.plist file' do it 'generates a valid Info.plist file' do
generator = Generator::InfoPlistFile.new(fixture_pod_target('orange-framework/OrangeFramework.podspec')) generator = Generator::InfoPlistFile.new('1.0.0', Platform.new(:ios, '6.0'))
file = temporary_directory + 'Info.plist' file = temporary_directory + 'Info.plist'
generator.save_as(file) generator.save_as(file)
`plutil -lint #{file}` `plutil -lint #{file}`
...@@ -59,7 +16,7 @@ module Pod ...@@ -59,7 +16,7 @@ module Pod
end if Executable.which('plutil') end if Executable.which('plutil')
it 'generates a correct Info.plist file' do it 'generates a correct Info.plist file' do
generator = Generator::InfoPlistFile.new(mock('Target')) generator = Generator::InfoPlistFile.new('1.0.0', Platform.new(:ios, '6.0'))
file = temporary_directory + 'Info.plist' file = temporary_directory + 'Info.plist'
generator.save_as(file) generator.save_as(file)
Xcodeproj::Plist.read_from_path(file).should == { Xcodeproj::Plist.read_from_path(file).should == {
...@@ -74,10 +31,46 @@ module Pod ...@@ -74,10 +31,46 @@ module Pod
'CFBundleVersion' => '${CURRENT_PROJECT_VERSION}', 'CFBundleVersion' => '${CURRENT_PROJECT_VERSION}',
'NSPrincipalClass' => '', 'NSPrincipalClass' => '',
} }
it 'sets the package type' do
generator = Generator::InfoPlistFile.new('1.0.0', Platform.new(:ios, '6.0'), :appl)
file = temporary_directory + 'Info.plist'
generator.save_as(file)
Xcodeproj::Plist.read_from_path(file).should == {
'CFBundleDevelopmentRegion' => 'en',
'CFBundleExecutable' => '${EXECUTABLE_NAME}',
'CFBundleIdentifier' => '${PRODUCT_BUNDLE_IDENTIFIER}',
'CFBundleInfoDictionaryVersion' => '6.0',
'CFBundleName' => '${PRODUCT_NAME}',
'CFBundlePackageType' => 'APPL',
'CFBundleShortVersionString' => '1.0.0',
'CFBundleSignature' => '????',
'CFBundleVersion' => '${CURRENT_PROJECT_VERSION}',
'NSPrincipalClass' => '',
}
end
it 'adds NSPrincipalClass for OSX platform' do
generator = Generator::InfoPlistFile.new('1.0.0', Platform.new(:osx, '10.8'), :appl)
file = temporary_directory + 'Info.plist'
generator.save_as(file)
Xcodeproj::Plist.read_from_path(file).should == {
'CFBundleDevelopmentRegion' => 'en',
'CFBundleExecutable' => '${EXECUTABLE_NAME}',
'CFBundleIdentifier' => '${PRODUCT_BUNDLE_IDENTIFIER}',
'CFBundleInfoDictionaryVersion' => '6.0',
'CFBundleName' => '${PRODUCT_NAME}',
'CFBundlePackageType' => 'APPL',
'CFBundleShortVersionString' => '1.0.0',
'CFBundleSignature' => '????',
'CFBundleVersion' => '${CURRENT_PROJECT_VERSION}',
'NSPrincipalClass' => 'NSApplication',
}
end
end end
it 'properly formats serialized arrays' do it 'properly formats serialized arrays' do
generator = Generator::InfoPlistFile.new(mock('Target')) generator = Generator::InfoPlistFile.new('1.0.0', Platform.new(:ios, '6.0'))
generator.send(:to_plist, 'array' => %w(a b)).should == <<-PLIST generator.send(:to_plist, 'array' => %w(a b)).should == <<-PLIST
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
...@@ -94,16 +87,14 @@ module Pod ...@@ -94,16 +87,14 @@ module Pod
end end
it 'uses the specified bundle_package_type' do it 'uses the specified bundle_package_type' do
target = mock('Target') generator = Generator::InfoPlistFile.new('1.0.0', Platform.new(:ios, '6.0'), :bndl)
generator = Generator::InfoPlistFile.new(target, :bundle_package_type => :bndl)
file = temporary_directory + 'Info.plist' file = temporary_directory + 'Info.plist'
generator.save_as(file) generator.save_as(file)
Xcodeproj::Plist.read_from_path(file)['CFBundlePackageType'].should == 'BNDL' Xcodeproj::Plist.read_from_path(file)['CFBundlePackageType'].should == 'BNDL'
end end
it 'does not include a CFBundleExecutable for bundles' do it 'does not include a CFBundleExecutable for bundles' do
target = mock('Target') generator = Generator::InfoPlistFile.new('1.0.0', Platform.new(:ios, '6.0'), :bndl)
generator = Generator::InfoPlistFile.new(target, :bundle_package_type => :bndl)
file = temporary_directory + 'Info.plist' file = temporary_directory + 'Info.plist'
generator.save_as(file) generator.save_as(file)
Xcodeproj::Plist.read_from_path(file).should.not.key('CFBundleExecutable') Xcodeproj::Plist.read_from_path(file).should.not.key('CFBundleExecutable')
......
...@@ -74,7 +74,7 @@ module Pod ...@@ -74,7 +74,7 @@ module Pod
it "adds the user's build configurations to the target" do it "adds the user's build configurations to the target" do
@pod_target.user_build_configurations.merge!('AppStore' => :release, 'Test' => :debug) @pod_target.user_build_configurations.merge!('AppStore' => :release, 'Test' => :debug)
@installer.install! @installer.install!
@project.targets.first.build_configurations.map(&:name).sort.should == %w( AppStore Debug Release Test ) @project.targets.first.build_configurations.map(&:name).sort.should == %w(AppStore Debug Release Test)
end end
it 'it creates different hash instances for the build settings of various build configurations' do it 'it creates different hash instances for the build settings of various build configurations' do
...@@ -274,6 +274,50 @@ module Pod ...@@ -274,6 +274,50 @@ module Pod
bc.build_settings['CONFIGURATION_BUILD_DIR'].should.be.nil bc.build_settings['CONFIGURATION_BUILD_DIR'].should.be.nil
end end
end end
describe 'app host generation' do
before do
@coconut_spec.test_specs.first.requires_app_host = true
end
it 'creates and links app host with an iOS test native target' do
@installer.install!
@project.targets.count.should == 3
app_host_target = @project.targets[2]
app_host_target.name.should == 'AppHost-iOS-Unit-Tests'
app_host_target.symbol_type.should == :application
native_test_target = @project.targets[1]
native_test_target.build_configurations.each do |bc|
bc.build_settings['TEST_HOST'].should == '$(BUILT_PRODUCTS_DIR)/AppHost-iOS-Unit-Tests.app/AppHost-iOS-Unit-Tests'
end
@project.root_object.attributes['TargetAttributes'].should == {
native_test_target.uuid.to_s => {
'TestTargetID' => app_host_target.uuid.to_s,
},
}
end
it 'creates and links app host with an OSX test native target' do
@installer2.install!
@project.targets.count.should == 3
app_host_target = @project.targets[2]
app_host_target.name.should == 'AppHost-macOS-Unit-Tests'
app_host_target.symbol_type.should == :application
app_host_target.build_configurations.each do |bc|
bc.build_settings['PRODUCT_NAME'].should == 'AppHost-macOS-Unit-Tests'
bc.build_settings['PRODUCT_BUNDLE_IDENTIFIER'].should == 'org.cocoapods.${PRODUCT_NAME:rfc1034identifier}'
end
native_test_target = @project.targets[1]
native_test_target.build_configurations.each do |bc|
bc.build_settings['TEST_HOST'].should == '$(BUILT_PRODUCTS_DIR)/AppHost-macOS-Unit-Tests.app/Contents/MacOS/AppHost-macOS-Unit-Tests'
end
@project.root_object.attributes['TargetAttributes'].should == {
native_test_target.uuid.to_s => {
'TestTargetID' => app_host_target.uuid.to_s,
},
}
end
end
end end
describe 'test other files under sources' do describe 'test other files under sources' do
......
...@@ -269,7 +269,7 @@ module Pod ...@@ -269,7 +269,7 @@ module Pod
it 'adds all test dependent targets to test native targets' do it 'adds all test dependent targets to test native targets' do
mock_native_target = mock('CoconutLib') mock_native_target = mock('CoconutLib')
mock_test_native_target = mock('CoconutLib-Unit-Tests') mock_test_native_target = mock('CoconutLib-Unit-Tests', :symbol_type => :unit_test_bundle)
dependent_native_target = mock('DependentNativeTarget') dependent_native_target = mock('DependentNativeTarget')
test_dependent_native_target = mock('TestDependentNativeTarget') test_dependent_native_target = mock('TestDependentNativeTarget')
...@@ -302,6 +302,7 @@ module Pod ...@@ -302,6 +302,7 @@ module Pod
@target.stubs(:pod_targets).returns([]) @target.stubs(:pod_targets).returns([])
@generator.expects(:pod_targets).returns([@pod_target]) @generator.expects(:pod_targets).returns([@pod_target])
mock_native_target = mock('CoconutLib') mock_native_target = mock('CoconutLib')
mock_test_native_target = mock('CoconutLib-Unit-Tests', :symbol_type => :unit_test_bundle)
dependent_native_target = mock('DependentNativeTarget') dependent_native_target = mock('DependentNativeTarget')
dependent_target = mock('dependent-target', :dependent_targets => []) dependent_target = mock('dependent-target', :dependent_targets => [])
...@@ -309,18 +310,20 @@ module Pod ...@@ -309,18 +310,20 @@ module Pod
dependent_target.stubs(:native_target).returns(dependent_native_target) dependent_target.stubs(:native_target).returns(dependent_native_target)
@pod_target.stubs(:native_target).returns(mock_native_target) @pod_target.stubs(:native_target).returns(mock_native_target)
@pod_target.stubs(:test_native_targets).returns([]) @pod_target.stubs(:test_native_targets).returns([mock_test_native_target])
@pod_target.stubs(:dependent_targets).returns([dependent_target]) @pod_target.stubs(:dependent_targets).returns([dependent_target])
@pod_target.stubs(:test_dependent_targets).returns([]) @pod_target.stubs(:test_dependent_targets).returns([])
@pod_target.stubs(:should_build? => true) @pod_target.stubs(:should_build? => true)
mock_native_target.expects(:add_dependency).with(dependent_native_target) mock_native_target.expects(:add_dependency).with(dependent_native_target)
mock_test_native_target.expects(:add_dependency).with(dependent_native_target)
mock_test_native_target.expects(:add_dependency).with(mock_native_target)
@generator.send(:set_target_dependencies) @generator.send(:set_target_dependencies)
end end
it 'adds test dependencies to test native targets for a pod target that should not be built' do it 'adds test dependencies to test native targets for a pod target that should not be built' do
mock_test_native_target = mock('CoconutLib-Unit-Tests') mock_test_native_target = mock('CoconutLib-Unit-Tests', :symbol_type => :unit_test_bundle)
test_dependent_native_target = mock('TestDependentNativeTarget') test_dependent_native_target = mock('TestDependentNativeTarget')
test_dependent_target = mock('dependent-test-target', :should_build? => true, :native_target => test_dependent_native_target) test_dependent_target = mock('dependent-test-target', :should_build? => true, :native_target => test_dependent_native_target)
test_dependent_target.expects(:should_build?).returns(true) test_dependent_target.expects(:should_build?).returns(true)
...@@ -335,7 +338,7 @@ module Pod ...@@ -335,7 +338,7 @@ module Pod
end end
it 'sets resource bundles for not build pods as target dependencies of the test target' do it 'sets resource bundles for not build pods as target dependencies of the test target' do
mock_test_native_target = mock('CoconutLib-Unit-Tests') mock_test_native_target = mock('CoconutLib-Unit-Tests', :symbol_type => :unit_test_bundle)
@pod_target.stubs(:test_native_targets).returns([mock_test_native_target]) @pod_target.stubs(:test_native_targets).returns([mock_test_native_target])
@pod_target.stubs(:test_dependent_targets).returns([]) @pod_target.stubs(:test_dependent_targets).returns([])
...@@ -347,6 +350,26 @@ module Pod ...@@ -347,6 +350,26 @@ module Pod
@generator.send(:set_target_dependencies) @generator.send(:set_target_dependencies)
end end
it 'sets the app host dependency target to the test native target if test spec requires app host' do
mock_app_host_target = mock(:name => 'AppHost-iOS-Unit-Tests')
@generator.project.stubs(:targets).returns([mock_app_host_target])
mock_test_native_target = mock('CoconutLib-Unit-Tests', :symbol_type => :unit_test_bundle)
test_dependent_native_target = mock('TestDependentNativeTarget')
test_dependent_target = mock('dependent-test-target', :should_build? => true, :native_target => test_dependent_native_target)
test_dependent_target.expects(:should_build?).returns(true)
@pod_target.test_specs.first.requires_app_host = true
@pod_target.stubs(:test_native_targets).returns([mock_test_native_target])
@pod_target.stubs(:all_test_dependent_targets).returns([test_dependent_target])
@pod_target.stubs(:should_build? => false)
mock_test_native_target.expects(:add_dependency).with(test_dependent_native_target)
mock_test_native_target.expects(:add_dependency).with(mock_app_host_target)
@generator.send(:set_target_dependencies)
end
end end
#--------------------------------------# #--------------------------------------#
......
...@@ -111,6 +111,30 @@ module Pod ...@@ -111,6 +111,30 @@ module Pod
end end
end end
describe 'target version' do
it 'handles when the version is more than 3 numeric parts' do
version = Version.new('0.2.0.1')
@pod_target.root_spec.stubs(:version).returns(version)
@pod_target.version.should == '0.2.0'
end
it 'handles when the version is less than 3 numeric parts' do
version = Version.new('0.2')
@pod_target.root_spec.stubs(:version).returns(version)
@pod_target.version.should == '0.2.0'
end
it 'handles when the version is a pre-release' do
version = Version.new('1.0.0-beta.1')
@pod_target.root_spec.stubs(:version).returns(version)
@pod_target.version.should == '1.0.0'
version = Version.new('1.0-beta.5')
@pod_target.root_spec.stubs(:version).returns(version)
@pod_target.version.should == '1.0.0'
end
end
describe 'Support files' do describe 'Support files' do
it 'returns the absolute path of the xcconfig file' do it 'returns the absolute path of the xcconfig file' do
@pod_target.xcconfig_path('Release').to_s.should.include?( @pod_target.xcconfig_path('Release').to_s.should.include?(
...@@ -315,7 +339,7 @@ module Pod ...@@ -315,7 +339,7 @@ module Pod
@test_spec_target_definition = Podfile::TargetDefinition.new('Pods', nil) @test_spec_target_definition = Podfile::TargetDefinition.new('Pods', nil)
@test_spec_target_definition.abstract = false @test_spec_target_definition.abstract = false
@test_pod_target = PodTarget.new([@coconut_spec, *@coconut_spec.recursive_subspecs], [@test_spec_target_definition], config.sandbox) @test_pod_target = PodTarget.new([@coconut_spec, *@coconut_spec.recursive_subspecs], [@test_spec_target_definition], config.sandbox)
@test_pod_target.stubs(:platform).returns(:ios) @test_pod_target.stubs(:platform).returns(Platform.new(:ios, '6.0'))
end end
it 'returns that it has test specifications' do it 'returns that it has test specifications' do
...@@ -330,6 +354,10 @@ module Pod ...@@ -330,6 +354,10 @@ module Pod
@test_pod_target.test_target_label(:unit).should == 'CoconutLib-Unit-Tests' @test_pod_target.test_target_label(:unit).should == 'CoconutLib-Unit-Tests'
end end
it 'returns app host label based on test type' do
@test_pod_target.app_host_label(:unit).should == 'AppHost-iOS-Unit-Tests'
end
it 'returns the correct native target based on the consumer provided' do it 'returns the correct native target based on the consumer provided' do
@test_pod_target.stubs(:native_target).returns(stub(:name => 'CoconutLib', :symbol_type => :dynamic_library, :product_reference => stub(:name => 'libCoconutLib.a'))) @test_pod_target.stubs(:native_target).returns(stub(:name => 'CoconutLib', :symbol_type => :dynamic_library, :product_reference => stub(:name => 'libCoconutLib.a')))
@test_pod_target.stubs(:test_native_targets).returns([stub(:name => 'CoconutLib-Unit-Tests', :symbol_type => :unit_test_bundle, :product_reference => stub(:name => 'CoconutLib-Unit-Tests'))]) @test_pod_target.stubs(:test_native_targets).returns([stub(:name => 'CoconutLib-Unit-Tests', :symbol_type => :unit_test_bundle, :product_reference => stub(:name => 'CoconutLib-Unit-Tests'))])
......
...@@ -581,81 +581,6 @@ module Pod ...@@ -581,81 +581,6 @@ module Pod
Xcodeproj::Project.schemes(project.path).should == %w(App) Xcodeproj::Project.schemes(project.path).should == %w(App)
end end
describe 'creating the importing file' do
describe 'when linting as a framework' do
before do
@validator.stubs(:use_frameworks).returns(true)
end
it 'creates a swift import' do
pod_target = stub(:uses_swift? => true, :should_build? => true, :product_module_name => 'ModuleName')
file = @validator.send(:write_app_import_source_file, pod_target)
file.basename.to_s.should == 'main.swift'
file.read.should == <<-SWIFT.strip_heredoc
import ModuleName
SWIFT
end
it 'creates an objective-c import' do
pod_target = stub(:uses_swift? => false, :should_build? => true, :product_module_name => 'ModuleName')
file = @validator.send(:write_app_import_source_file, pod_target)
file.basename.to_s.should == 'main.m'
file.read.should == <<-OBJC.strip_heredoc
@import Foundation;
@import UIKit;
@import ModuleName;
int main() {}
OBJC
end
it 'creates no import when the pod target has no source files' do
pod_target = stub(:uses_swift? => true, :should_build? => false)
file = @validator.send(:write_app_import_source_file, pod_target)
file.basename.to_s.should == 'main.swift'
file.read.should == ''
end
end
describe 'when linting as a static lib' do
before do
@validator.stubs(:use_frameworks).returns(false)
@sandbox = config.sandbox
end
it 'creates an objective-c import when a plausible umbrella header is found' do
pod_target = stub(:uses_swift? => false, :should_build? => true, :product_module_name => 'ModuleName', :sandbox => @sandbox)
header_name = "#{pod_target.product_module_name}/#{pod_target.product_module_name}.h"
umbrella = pod_target.sandbox.public_headers.root.+(header_name)
umbrella.dirname.mkpath
umbrella.open('w') {}
file = @validator.send(:write_app_import_source_file, pod_target)
file.basename.to_s.should == 'main.m'
file.read.should == <<-OBJC.strip_heredoc
@import Foundation;
@import UIKit;
#import <ModuleName/ModuleName.h>
int main() {}
OBJC
end
it 'does not create an objective-c import when no umbrella header is found' do
pod_target = stub(:uses_swift? => false, :should_build? => true, :product_module_name => 'ModuleName', :sandbox => @sandbox)
file = @validator.send(:write_app_import_source_file, pod_target)
file.basename.to_s.should == 'main.m'
file.read.should == <<-OBJC.strip_heredoc
@import Foundation;
@import UIKit;
int main() {}
OBJC
end
end
end
it 'adds the importing file to the app target' do it 'adds the importing file to the app target' do
@validator.stubs(:use_frameworks).returns(true) @validator.stubs(:use_frameworks).returns(true)
@validator.send(:create_app_project) @validator.send(:create_app_project)
......
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