Skip to content

Commit

Permalink
fix: unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
GMinucci committed Jan 20, 2025
1 parent ff7d4a9 commit 23c4c26
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 197 deletions.
13 changes: 6 additions & 7 deletions Sources/VariantsCore/Custom Types/Project/iOSProject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ class iOSProject: Project {
do {
try configFactory.createConfig(
with: namedTarget,
configuration: configuration,
variant: variant,
xcodeProj: configuration.xcodeproj,
configPath: Path(spec).absolute().parent(),
Expand Down Expand Up @@ -129,12 +128,12 @@ class iOSProject: Project {
// destination are set as '.project'
let configPath = Path(spec).absolute().parent()
do {
try configFactory.createConfig(with: target,
configuration: configuration,
variant: defaultVariant,
xcodeProj: configuration.xcodeproj,
configPath: configPath,
addToXcodeProj: true)
try configFactory.createConfig(
with: target,
variant: defaultVariant,
xcodeProj: configuration.xcodeproj,
configPath: configPath,
addToXcodeProj: true)
} catch {
Logger.shared.logFatal(item: error.localizedDescription)
}
Expand Down
11 changes: 3 additions & 8 deletions Sources/VariantsCore/Factory/iOS/VariantsFileFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,16 @@ class VariantsFileFactory {
/// and `Variants.ConfigurationValueKey` as keys for custom configuration values
/// - Parameters:
/// - configFilePath: Path to XCConfig file
/// - configuration: Base iOS configuration
/// - variant: Chosen variant, as seen in `variants.yml`
func updateVariantsFile(with configFilePath: Path, configuration: iOSConfiguration, variant: iOSVariant) {
func updateVariantsFile(with configFilePath: Path, variant: iOSVariant) {
do {
let path = try TemplateDirectory().path
guard let variantsGybTemplatePath = try? path.safeJoin(path: Path("ios/"))
else { return }

let allConfigurationValues = variant.combineCustomPropertiesWithGlobals(configuration: configuration)
let secrets = allConfigurationValues.projectSecretConfigurationValues
let configurationValues = allConfigurationValues.projectConfigurationValues

let context = [
"secrets": secrets,
"configurationValues": configurationValues
"secrets": variant.custom?.projectSecretConfigurationValues ?? [],
"configurationValues": variant.custom?.projectConfigurationValues ?? []
] as [String: Any]
let environment = Environment(loader: FileSystemLoader(paths: [variantsGybTemplatePath.absolute()]))
let content = try environment.renderTemplate(name: StaticPath.Template.variantsSwiftGybFileName,
Expand Down
16 changes: 7 additions & 9 deletions Sources/VariantsCore/Factory/iOS/XCConfigFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ protocol XCFactory {
func write(_ stringContent: String, toFile file: Path, force: Bool) -> (Bool, Path?)
func writeJSON<T>(_ encodableObject: T, toFile file: Path) -> (Bool, Path?) where T: Encodable
func createConfig(with target: NamedTarget,
configuration: iOSConfiguration,
variant: iOSVariant,
xcodeProj: String?,
configPath: Path,
Expand Down Expand Up @@ -65,7 +64,6 @@ class XCConfigFactory: XCFactory {
}

func createConfig(with target: NamedTarget,
configuration: iOSConfiguration,
variant: iOSVariant,
xcodeProj: String?,
configPath: Path,
Expand Down Expand Up @@ -93,7 +91,7 @@ class XCConfigFactory: XCFactory {

_ = write("", toFile: xcodeConfigPath, force: true)
logger.logInfo("Created file: ", item: "'\(xcconfigFileName)' at \(xcodeConfigPath.parent().abbreviate().description)")
populateConfig(with: target, configFile: xcodeConfigPath, configuration: configuration, variant: variant)
populateConfig(with: target, configFile: xcodeConfigPath, variant: variant)

/*
* If template files should be added to Xcode Project
Expand All @@ -112,14 +110,14 @@ class XCConfigFactory: XCFactory {
*/
let infoPath = target.value.source.info
let infoPlistPath = Path("\(configPath)/\(infoPath)")
updateInfoPlist(with: target.value, configFile: infoPlistPath, configuration: configuration, variant: variant)
updateInfoPlist(with: target.value, configFile: infoPlistPath, variant: variant)

/*
* Add custom properties whose values should be read from environment variables
* to `Variants.Secret` as encrypted secrets.
*/
let variantsFileFactory = VariantsFileFactory(logger: logger)
variantsFileFactory.updateVariantsFile(with: xcodeConfigPath, configuration: configuration, variant: variant)
variantsFileFactory.updateVariantsFile(with: xcodeConfigPath, variant: variant)
}

// MARK: - Private methods
Expand Down Expand Up @@ -159,9 +157,9 @@ class XCConfigFactory: XCFactory {
}
}

private func populateConfig(with target: NamedTarget, configFile: Path, configuration: iOSConfiguration, variant: iOSVariant) {
private func populateConfig(with target: NamedTarget, configFile: Path, variant: iOSVariant) {
logger.logInfo("Populating: ", item: "'\(configFile.lastComponent)'")
variant.getDefaultValues(configuration: configuration, target: target.value).forEach { (key, value) in
variant.getDefaultValues(for: target.value).forEach { (key, value) in
let stringContent = "\(key) = \(value)"
logger.logDebug("Item: ", item: stringContent, indentationLevel: 1, color: .purple)

Expand Down Expand Up @@ -198,7 +196,7 @@ class XCConfigFactory: XCFactory {
xcodeFactory.modify(mainTargetSettings, in: projectPath, target: target.value)
}

private func updateInfoPlist(with target: iOSTarget, configFile: Path, configuration: iOSConfiguration, variant: iOSVariant) {
private func updateInfoPlist(with target: iOSTarget, configFile: Path, variant: iOSVariant) {
let configFilePath = configFile.absolute().description
do {
// TODO: Add plutil as separate command?
Expand All @@ -217,7 +215,7 @@ class XCConfigFactory: XCFactory {
* Add custom configs to Info.plist so that it is accessible through Variants.swift
*/
try variant
.getDefaultValues(configuration: configuration, target: target)
.getDefaultValues(for: target)
.filter { !$0.key.starts(with: "V_") }
.forEach { (key, _) in
try Bash("plutil", arguments: "-remove", "\(key)", configFilePath).run()
Expand Down
10 changes: 7 additions & 3 deletions Sources/VariantsCore/Schemas/iOS/iOSConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,20 @@ public struct iOSConfiguration: Codable {

self.xcodeproj = try container.decode(String.self, forKey: .xcodeproj)
self.targets = try container.decode([String: iOSTarget].self, forKey: .targets)
self.custom = try? container.decode([CustomProperty].self, forKey: .custom)


let globalCustomProperties = try? container.decode([CustomProperty].self, forKey: .custom)
self.custom = globalCustomProperties

let globalPostSwitchScript = try container.decodeIfPresent(String.self, forKey: .postSwitchScript)
let globalSigning = try container.decodeIfPresent(iOSSigning.self, forKey: .signing)
let variantsDict = try container.decode([String: UnnamediOSVariant].self, forKey: .variants)

self.postSwitchScript = globalPostSwitchScript
self.signing = globalSigning
self.variants = try variantsDict
.map { try iOSVariant(from: $1, name: $0, globalSigning: globalSigning, globalPostSwitchScript: globalPostSwitchScript) }
.map {
try iOSVariant(from: $1, name: $0, globalCustomProperties: globalCustomProperties,
globalSigning: globalSigning, globalPostSwitchScript: globalPostSwitchScript) }
}
}

Expand Down
41 changes: 21 additions & 20 deletions Sources/VariantsCore/Schemas/iOS/iOSVariant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public struct iOSVariant: Variant {
let postSwitchScript: String?

private let bundleNamingOption: BundleNamingOption

public var title: String { name }

var configName: String {
Expand All @@ -38,8 +38,10 @@ public struct iOSVariant: Variant {
}

init(
name: String, versionName: String, versionNumber: Int, appIcon: String?, appName: String?, storeDestination: String?,
custom: [CustomProperty]?, idSuffix: String?, bundleID: String?, variantSigning: iOSSigning?, globalSigning: iOSSigning?,
name: String, versionName: String, versionNumber: Int, appIcon: String?, appName: String?,
storeDestination: String?, idSuffix: String?, bundleID: String?,
globalCustomProperties: [CustomProperty]?, variantCustomProperties: [CustomProperty]?,
globalSigning: iOSSigning?, variantSigning: iOSSigning?,
globalPostSwitchScript: String?, variantPostSwitchScript: String?)
throws {
self.name = name
Expand All @@ -49,7 +51,7 @@ public struct iOSVariant: Variant {
self.appName = appName
self.storeDestination = try Self.parseDestination(name: name, destination: storeDestination) ?? .appStore
self.signing = try Self.parseSigning(name: name, variantSigning: variantSigning, globalSigning: globalSigning)
self.custom = custom
self.custom = Self.parseCustomProperties(variantCustom: variantCustomProperties, globalCustom: globalCustomProperties)
self.bundleNamingOption = try Self.parseBundleConfiguration(name: name, idSuffix: idSuffix, bundleID: bundleID)
self.postSwitchScript = Self.parsePostSwitchScript(globalScript: globalPostSwitchScript,
variantScript: variantPostSwitchScript)
Expand All @@ -66,7 +68,7 @@ public struct iOSVariant: Variant {
}
}

func getDefaultValues(configuration: iOSConfiguration, target: iOSTarget) -> [(key: String, value: String)] {
func getDefaultValues(for target: iOSTarget) -> [(key: String, value: String)] {
var customDictionary: [String: String] = [
"V_APP_NAME": appName ?? target.name + configName,
"V_BUNDLE_ID": makeBundleID(for: target),
Expand All @@ -78,21 +80,11 @@ public struct iOSVariant: Variant {
if signing?.matchURL != nil, let exportMethod = signing?.exportMethod {
customDictionary["V_MATCH_PROFILE"] = "\(exportMethod.prefix) \(makeBundleID(for: target))"
}

let allCustomConfiguration = combineCustomPropertiesWithGlobals(configuration: configuration)
allCustomConfiguration.projectConfigurationValues.forEach {
customDictionary[$0.name] = $0.value
}
(custom?.projectConfigurationValues ?? []).forEach { customDictionary[$0.name] = $0.value }

return customDictionary.sorted(by: {$0.key < $1.key})
}

func combineCustomPropertiesWithGlobals(configuration: iOSConfiguration) -> [CustomProperty] {
let variantCustomProperties = custom ?? []
let globalMinusOverrideProperties = (configuration.custom ?? []).filter { !variantCustomProperties.contains($0) }
return globalMinusOverrideProperties + variantCustomProperties
}

private static func parseDestination(name: String, destination: String?) throws -> Destination? {
guard let destinationString = destination else { return nil }

Expand Down Expand Up @@ -123,7 +115,13 @@ public struct iOSVariant: Variant {
return nil
}
}


private static func parseCustomProperties(variantCustom: [CustomProperty]?, globalCustom: [CustomProperty]?) -> [CustomProperty] {
let variantCustomProperties = variantCustom ?? []
let globalMinusOverrideProperties = (globalCustom ?? []).filter { !variantCustomProperties.contains($0) }
return globalMinusOverrideProperties + variantCustomProperties
}

private static func parsePostSwitchScript(globalScript: String?, variantScript: String?) -> String? {
if let globalScript = globalScript, let variantScript = variantScript {
return "\(globalScript) && \(variantScript)"
Expand Down Expand Up @@ -214,19 +212,22 @@ extension UnnamediOSVariant {
}

extension iOSVariant {
init(from unnamediOSVariant: UnnamediOSVariant, name: String, globalSigning: iOSSigning?, globalPostSwitchScript: String?) throws {
init(from unnamediOSVariant: UnnamediOSVariant, name: String, globalCustomProperties: [CustomProperty]?,
globalSigning: iOSSigning?, globalPostSwitchScript: String?)
throws {
try self.init(
name: name,
versionName: unnamediOSVariant.versionName,
versionNumber: unnamediOSVariant.versionNumber,
appIcon: unnamediOSVariant.appIcon,
appName: unnamediOSVariant.appName,
storeDestination: unnamediOSVariant.storeDestination,
custom: unnamediOSVariant.custom,
idSuffix: unnamediOSVariant.idSuffix,
bundleID: unnamediOSVariant.bundleID,
variantSigning: unnamediOSVariant.signing,
globalCustomProperties: globalCustomProperties,
variantCustomProperties: unnamediOSVariant.custom,
globalSigning: globalSigning,
variantSigning: unnamediOSVariant.signing,
globalPostSwitchScript: globalPostSwitchScript,
variantPostSwitchScript: unnamediOSVariant.postSwitchScript)
}
Expand Down
7 changes: 4 additions & 3 deletions Tests/VariantsCoreTests/FastlaneParametersFactoryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,13 @@ class FastlaneParametersFactoryTests: XCTestCase {
versionNumber: 99,
appIcon: nil,
appName: nil,
storeDestination: "testFlight",
custom: nil,
storeDestination: "testflight",
idSuffix: "sample",
bundleID: nil,
variantSigning: nil,
globalCustomProperties: nil,
variantCustomProperties: nil,
globalSigning: iOSSigning(teamName: "", teamID: "", exportMethod: .appstore, matchURL: ""),
variantSigning: nil,
globalPostSwitchScript: "echo global",
variantPostSwitchScript: "echo variant")
else {
Expand Down
8 changes: 2 additions & 6 deletions Tests/VariantsCoreTests/Mocks/MockXCcodeConfigFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
// Created by Arthur Alves
//

// swiftlint:disable colon

import Foundation
import PathKit
@testable import VariantsCore
Expand All @@ -29,11 +27,11 @@ class MockXCcodeConfigFactory: XCFactory {
return (true, file)
}

func writeJSON<T>(_ encodableObject: T, toFile file: Path) -> (Bool, Path?) where T : Encodable {
func writeJSON<T>(_ encodableObject: T, toFile file: Path) -> (Bool, Path?) where T: Encodable {
writeJSONCache.append((encodableObject: encodableObject, file: file))
return (true, file)
}

func createConfig(with target: NamedTarget,
variant: iOSVariant,
xcodeProj: String?,
Expand All @@ -49,5 +47,3 @@ class MockXCcodeConfigFactory: XCFactory {
var xcconfigFileName: String = "variants.xcconfig"
var logger: Logger
}

// swiftlint:enable colon
14 changes: 7 additions & 7 deletions Tests/VariantsCoreTests/VariantsFileFactoryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ class VariantsFileFactoryTests: XCTestCase {
versionNumber: 99,
appIcon: nil,
appName: nil,
storeDestination: "testFlight",
custom: [
CustomProperty(name: "PROPERTY_A", value: "VALUE_A", destination: .project),
CustomProperty(name: "PROPERTY_B", value: "VALUE_B", destination: .project)
],
storeDestination: "testflight",
idSuffix: nil,
bundleID: nil,
variantSigning: nil,
globalCustomProperties: nil,
variantCustomProperties: [
CustomProperty(name: "PROPERTY_A", value: "VALUE_A", destination: .project),
CustomProperty(name: "PROPERTY_B", value: "VALUE_B", destination: .project)],
globalSigning: iOSSigning(teamName: "", teamID: "", exportMethod: .appstore, matchURL: ""),
variantSigning: nil,
globalPostSwitchScript: "echo global",
variantPostSwitchScript: "echo variant")

func testRender_noSecrets() {
guard let configFile = Bundle(for: type(of: self))
.path(forResource: "Resources/ios/sample", ofType: "xcconfig") else { return }
Expand Down
6 changes: 3 additions & 3 deletions Tests/VariantsCoreTests/XcodeProjFactoryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ class XcodeProjFactoryTests: XCTestCase {
let proj = XCConfigFactory(logger: Logger(verbose: true))
let target = iOSTarget(name: "", app_icon: "", bundleId: "", testTarget: "",
source: .init(path: "", info: "", config: ""))
guard let variant = try? iOSVariant(name: target.name, versionName: "", versionNumber: 0, appIcon: nil, appName: nil,
storeDestination: nil, custom: nil, idSuffix: "", bundleID: nil, variantSigning: nil,
guard let variant = try? iOSVariant(name: target.name, versionName: "", versionNumber: 0, appIcon: nil, appName: nil, storeDestination: nil,

Check failure on line 39 in Tests/VariantsCoreTests/XcodeProjFactoryTests.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Line should be 140 characters or less; currently it has 148 characters (line_length)
idSuffix: "", bundleID: nil, globalCustomProperties: nil, variantCustomProperties: nil,
globalSigning: iOSSigning(teamName: "", teamID: "", exportMethod: .appstore, matchURL: ""),
globalPostSwitchScript: nil, variantPostSwitchScript: nil)
variantSigning: nil, globalPostSwitchScript: nil, variantPostSwitchScript: nil)
else {
return XCTFail("Failed to initialize iOSVariant with provided parameters")
}
Expand Down
Loading

0 comments on commit 23c4c26

Please sign in to comment.