This is an automated email from the ASF dual-hosted git repository. erisu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/cordova-ios.git
The following commit(s) were added to refs/heads/master by this push: new 3fc73751 feat(spm): Support plugins as Swift packages (#1515) 3fc73751 is described below commit 3fc737518f73aabcf2b9f3a0ff83952c8f7e64be Author: Darryl Pogue <dar...@dpogue.ca> AuthorDate: Mon Jun 2 22:31:35 2025 -0700 feat(spm): Support plugins as Swift packages (#1515) * feat(spm): Add CordovaPlugins SPM to template * feat(spm): Update Package.swift on plugin add/remove * feat(spm): Copy plugins and rewrite Cordova dependency * feat(spm): Move CordovaPlugins into the packages dir This helps keep the top level project directory a bit cleaner by hiding our CordovaPlugins SPM accumulator package inside the packages directory. * feat(spm): Handle plugins with npm namespaces * feat(spm): Support linked cordova-ios * feat(spm): support nospm flag for plugin pods * feat: add nospm flag for pod, add package attribute in platform tag * feat: use plugin.xml for check podspec import * fix: skip pod installation correctly * feat: use isSwiftPacakge method to choose necessary pod tags * fix: cocoapod lib install condition * feat: add test code for cocoapod nospm attribute * test: update unit tests code * feat: improve test code --------- Co-authored-by: jcesarmobile <jcesarmob...@gmail.com> Co-authored-by: knaito-asial <81949829+knaito-as...@users.noreply.github.com> --- lib/Api.js | 73 ++++--- lib/SwiftPackage.js | 114 +++++++++++ lib/create.js | 3 +- lib/plugman/pluginHandlers.js | 21 ++ lib/prepare.js | 2 +- templates/project/App.xcodeproj/project.pbxproj | 20 +- .../packages/cordova-ios-plugins/Package.swift | 37 ++++ .../Sources/CordovaPlugins/CordovaPlugins.swift | 21 ++ tests/spec/coverage.json | 4 +- tests/spec/unit/Api.spec.js | 52 +++++ tests/spec/unit/Plugman/pluginHandler.spec.js | 57 +++--- tests/spec/unit/SwiftPackage.spec.js | 218 +++++++++++++++++++++ .../ios-config-xml/App.xcodeproj/project.pbxproj | 20 +- .../ios-config-xml/CordovaPlugins/Package.swift | 37 ++++ .../Sources/CordovaPlugins/CordovaPlugins.swift | 21 ++ .../App.xcodeproj/project.pbxproj | 20 +- .../project.xcworkspace/contents.xcworkspacedata | 25 +++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../App.xcworkspace/contents.xcworkspacedata | 25 +++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/xcschemes/App.xcscheme | 109 +++++++++++ .../ios-packageswift-config-xml/App/.gitignore | 5 + .../ios-packageswift-config-xml/App/App-Info.plist | 63 ++++++ .../ios-packageswift-config-xml/App/AppDelegate.h | 29 +++ .../App/AppDelegate.swift | 29 +++ .../AppIcon.appiconset/Contents.json | 20 ++ .../Assets.xcassets/AppIcon.appiconset/icon.png | Bin 0 -> 31816 bytes .../BackgroundColor.colorset/Contents.json | 15 ++ .../App/Assets.xcassets/Contents.json | 6 + .../LaunchStoryboard.imageset/Contents.json | 168 ++++++++++++++++ .../Contents.json | 15 ++ .../Contents.json | 15 ++ .../App/Base.lproj/CDVLaunchScreen.storyboard | 65 ++++++ .../App/Base.lproj/Main.storyboard | 66 +++++++ .../App/Bridging-Header.h | 25 +++ .../App/Entitlements-Debug.plist | 24 +++ .../App/Entitlements-Release.plist | 24 +++ .../App/MainViewController.h | 29 +++ .../ios-packageswift-config-xml/App/Plugins/README | 20 ++ .../App/PrivacyInfo.xcprivacy | 32 +++ .../App/Resources/README | 20 ++ .../App/SceneDelegate.swift | 25 +++ .../App/ViewController.swift | 27 +++ .../ios-packageswift-config-xml/App/config.xml | 82 ++++++++ .../CordovaPlugins/Package.swift | 37 ++++ .../Sources/CordovaPlugins/CordovaPlugins.swift | 21 ++ .../cordova/defaults.xml | 59 ++++++ .../packages/cordova-ios-plugins/Package.swift | 40 ++++ .../packages/cordova-ios/Package.swift | 47 +++++ .../platform_www/.gitkeep | 0 .../ios-packageswift-config-xml/www/.gitkeep | 0 .../Package.swift | 47 +++++ .../package.json | 12 ++ .../plugin.xml | 43 ++++ .../src/ios/PackagePodPlugin.swift | 46 +++++ .../Package.swift | 46 +++++ .../org.test.plugins.swiftpackageplugin/plugin.xml | 33 ++++ .../src/ios/PackagePlugin.swift | 27 +++ tests/spec/unit/fixtures/test-Package.swift | 37 ++++ 59 files changed, 2132 insertions(+), 62 deletions(-) diff --git a/lib/Api.js b/lib/Api.js index c131f1b8..9153cce8 100644 --- a/lib/Api.js +++ b/lib/Api.js @@ -34,6 +34,12 @@ const { PluginManager } = require('cordova-common'); +// check the value is true or 'true' or 'TRUE' or 1 +const _isTrue = (value) => { + return (value === true) || + (typeof value === 'string' && value.toLowerCase() === 'true') || value === 1; +}; + function setupEvents (externalEventEmitter) { if (externalEventEmitter) { // This will make the platform internal events visible outside @@ -226,6 +232,7 @@ class Api { */ addPlugin (plugin, installOptions) { const xcodeproj = projectFile.parse(this.locations); + const { SwiftPackage, isSwiftPackagePlugin } = require('./SwiftPackage'); installOptions = installOptions || {}; installOptions.variables = installOptions.variables || {}; @@ -237,7 +244,13 @@ class Api { return PluginManager.get(this.platform, this.locations, xcodeproj) .addPlugin(plugin, installOptions) .then(() => { - if (plugin != null) { + if (plugin != null && isSwiftPackagePlugin(plugin)) { + const spm = new SwiftPackage(this.locations.root); + spm.addPlugin(plugin, installOptions); + } + }) + .then(() => { + if (plugin != null && !isSwiftPackagePlugin(plugin)) { const headerTags = plugin.getHeaderFiles(this.platform); const bridgingHeaders = headerTags.filter(obj => obj.type === 'BridgingHeader'); if (bridgingHeaders.length > 0) { @@ -279,11 +292,18 @@ class Api { */ removePlugin (plugin, uninstallOptions) { const xcodeproj = projectFile.parse(this.locations); + const { SwiftPackage, isSwiftPackagePlugin } = require('./SwiftPackage'); return PluginManager.get(this.platform, this.locations, xcodeproj) .removePlugin(plugin, uninstallOptions) .then(() => { - if (plugin != null) { + if (plugin != null && isSwiftPackagePlugin(plugin)) { + const spm = new SwiftPackage(this.locations.root); + spm.removePlugin(plugin); + } + }) + .then(() => { + if (plugin != null && !isSwiftPackagePlugin(plugin)) { const headerTags = plugin.getHeaderFiles(this.platform); const bridgingHeaders = headerTags.filter(obj => obj.type === 'BridgingHeader'); if (bridgingHeaders.length > 0) { @@ -322,6 +342,7 @@ class Api { if (!podSpecs.length) { return; } + const { isSwiftPackagePlugin } = require('./SwiftPackage'); const project_dir = this.locations.root; const project_name = this.locations.xcodeCordovaProj.split(path.sep).pop(); @@ -370,20 +391,21 @@ class Api { } }); } - - // libraries if (obj.libraries) { + const isSPM = isSwiftPackagePlugin(plugin); Object.keys(obj.libraries).forEach(key => { let podJson = Object.assign({}, obj.libraries[key]); - podJson = replacePodSpecVariables(podJson, installOptions); - const val = podsjsonFile.getLibrary(key); - if (val) { - events.emit('warn', `${plugin.id} depends on ${podJson.name}, which may conflict with another plugin. ${podJson.name}@${val.spec} is already installed and was not overwritten.`); - podsjsonFile.incrementLibrary(key); - } else { - podJson.count = 1; - podsjsonFile.setJsonLibrary(key, podJson); - podfileFile.addSpec(podJson.name, podJson); + if (!isSPM || (isSPM && !_isTrue(podJson.nospm))) { + podJson = replacePodSpecVariables(podJson, installOptions); + const val = podsjsonFile.getLibrary(key); + if (val) { + events.emit('warn', `${plugin.id} depends on ${podJson.name}, which may conflict with another plugin. ${podJson.name}@${val.spec} is already installed and was not overwritten.`); + podsjsonFile.incrementLibrary(key); + } else { + podJson.count = 1; + podsjsonFile.setJsonLibrary(key, podJson); + podfileFile.addSpec(podJson.name, podJson); + } } }); } @@ -415,6 +437,8 @@ class Api { */ removePodSpecs (plugin, podSpecs, uninstallOptions) { + const { isSwiftPackagePlugin } = require('./SwiftPackage'); + const project_dir = this.locations.root; const project_name = this.locations.xcodeCordovaProj.split(path.sep).pop(); @@ -462,18 +486,21 @@ class Api { } }); // libraries + const isSPM = isSwiftPackagePlugin(plugin); Object.keys(obj.libraries).forEach(key => { let podJson = Object.assign({}, obj.libraries[key]); - podJson = replacePodSpecVariables(podJson, uninstallOptions); - const val = podsjsonFile.getLibrary(key); - if (val) { - podsjsonFile.decrementLibrary(key); - } else { - const message = util.format('plugin \"%s\" podspec \"%s\" does not seem to be in pods.json, nothing to remove. Will attempt to remove from Podfile.', plugin.id, podJson.name); /* eslint no-useless-escape : 0 */ - events.emit('verbose', message); - } - if (!val || val.count === 0) { - podfileFile.removeSpec(podJson.name); + if (!isSPM || (isSPM && !_isTrue(podJson.nospm))) { + podJson = replacePodSpecVariables(podJson, uninstallOptions); + const val = podsjsonFile.getLibrary(key); + if (val) { + podsjsonFile.decrementLibrary(key); + } else { + const message = util.format('plugin \"%s\" podspec \"%s\" does not seem to be in pods.json, nothing to remove. Will attempt to remove from Podfile.', plugin.id, podJson.name); /* eslint no-useless-escape : 0 */ + events.emit('verbose', message); + } + if (!val || val.count === 0) { + podfileFile.removeSpec(podJson.name); + } } }); }); diff --git a/lib/SwiftPackage.js b/lib/SwiftPackage.js new file mode 100644 index 00000000..a4323ad9 --- /dev/null +++ b/lib/SwiftPackage.js @@ -0,0 +1,114 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +const fs = require('node:fs'); +const path = require('node:path'); +const { CordovaError } = require('cordova-common'); + +const ROOT = path.join(__dirname, '..'); + +class SwiftPackage { + constructor (projectRoot) { + this.root = projectRoot; + this.path = path.join(this.root, 'packages', 'cordova-ios-plugins', 'Package.swift'); + + if (!fs.existsSync(this.path)) { + throw new CordovaError('Package.swift is not found.'); + } + } + + _pluginReference (plugin, pluginPath) { + return ` +package.dependencies.append(.package(name: "${plugin.id}", path: "${pluginPath.replaceAll(path.sep, path.posix.sep)}")) +package.targets.first?.dependencies.append(.product(name: "${plugin.id}", package: "${plugin.id}")) +`; + } + + addPlugin (plugin, opts = {}) { + let pluginPath = path.relative(path.dirname(this.path), path.join(this.root, 'packages', plugin.id)); + if (opts.link) { + pluginPath = path.relative(path.dirname(this.path), plugin.dir); + } else { + // Copy the plugin into the packages directory + const localPluginPath = path.join(this.root, 'packages', plugin.id); + fs.cpSync(plugin.dir, localPluginPath, { recursive: true }); + + const pkgSwiftPath = path.join(localPluginPath, 'Package.swift'); + + let cordovaPath = path.relative(localPluginPath, path.join(this.root, 'packages', 'cordova-ios')); + if (!fs.existsSync(path.join(localPluginPath, cordovaPath))) { + cordovaPath = path.relative(localPluginPath, ROOT); + } + + const pkg_fd = fs.openSync(pkgSwiftPath, 'r+'); + let packageContent = fs.readFileSync(pkg_fd, 'utf8'); + + // Note: May match unintended packages, e.g. 'cordova-ios-plugin', + // due to flexible patterns. Strict filtering would risk valid + // exclusions. + packageContent = packageContent.replace(/package\(.+cordova-ios.+\)/gm, `package(name: "cordova-ios", path: "${cordovaPath.replaceAll(path.sep, path.posix.sep)}")`); + + fs.ftruncateSync(pkg_fd); + fs.writeSync(pkg_fd, packageContent, 0, 'utf8'); + fs.closeSync(pkg_fd); + } + + const fd = fs.openSync(this.path, 'a'); + fs.writeFileSync(fd, this._pluginReference(plugin, pluginPath), 'utf8'); + fs.closeSync(fd); + } + + removePlugin (plugin) { + const fd = fs.openSync(this.path, 'r+'); + + if (fs.existsSync(path.join(this.root, 'packages', plugin.id))) { + fs.rmSync(path.join(this.root, 'packages', plugin.id), { recursive: true, force: true }); + } + + let packageContent = fs.readFileSync(fd, 'utf8'); + + // We don't know if it was originally linked or not, so try to remove both + const pluginPath = path.relative(path.dirname(this.path), path.join(this.root, 'packages', plugin.id)); + const pluginLink = path.relative(path.dirname(this.path), plugin.dir); + packageContent = packageContent.replace(this._pluginReference(plugin, pluginPath), ''); + packageContent = packageContent.replace(this._pluginReference(plugin, pluginLink), ''); + + fs.ftruncateSync(fd); + fs.writeSync(fd, packageContent, 0, 'utf8'); + fs.closeSync(fd); + } +} + +// Use this as a hidden property on the plugin so that we can cache the result +// of the Swift Package check for the lifetime of that PluginInfo object, +// without caching it based on plugin name. +const _isSwiftPackage = Symbol('isSwiftPackage'); + +function isSwiftPackagePlugin (plugin) { + if (!plugin[_isSwiftPackage]) { + plugin[_isSwiftPackage] = plugin.getPlatforms().some((platform) => { + return platform.name === 'ios' && !!platform.package; + }); + } + + return plugin[_isSwiftPackage]; +} + +module.exports.SwiftPackage = SwiftPackage; +module.exports.isSwiftPackagePlugin = isSwiftPackagePlugin; diff --git a/lib/create.js b/lib/create.js index 9aab4ee3..5ae41cf0 100755 --- a/lib/create.js +++ b/lib/create.js @@ -114,7 +114,8 @@ class ProjectCreator { fs.cpSync(defaultXmlPath, configXmlPath); const config = new ConfigParser(configXmlPath); - xmlHelpers.mergeXml(this.options.rootConfig.doc.getroot(), config.doc.getroot(), 'ios', /* clobber= */true); + const src = this.options.rootConfig.doc.getroot(); + xmlHelpers.mergeXml(src, config.doc.getroot(), 'ios', /* clobber= */true); config.write(); } diff --git a/lib/plugman/pluginHandlers.js b/lib/plugman/pluginHandlers.js index 572fba4e..3ce239a7 100644 --- a/lib/plugman/pluginHandlers.js +++ b/lib/plugman/pluginHandlers.js @@ -20,6 +20,7 @@ const path = require('node:path'); const util = require('node:util'); const events = require('cordova-common').events; const CordovaError = require('cordova-common').CordovaError; +const { isSwiftPackagePlugin } = require('../SwiftPackage'); // These frameworks are required by cordova-ios by default. We should never add/remove them. const keep_these_frameworks = [ @@ -31,22 +32,32 @@ const keep_these_frameworks = [ const handlers = { 'source-file': { install: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + installHelper('source-file', obj, plugin.dir, project.projectDir, plugin.id, options, project); }, uninstall: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + uninstallHelper('source-file', obj, project.projectDir, plugin.id, options, project); } }, 'header-file': { install: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + installHelper('header-file', obj, plugin.dir, project.projectDir, plugin.id, options, project); }, uninstall: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + uninstallHelper('header-file', obj, project.projectDir, plugin.id, options, project); } }, 'resource-file': { install: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + const src = obj.src; let target = obj.target; const srcFile = path.resolve(plugin.dir, src); @@ -67,6 +78,8 @@ const handlers = { copyFile(plugin.dir, src, project.projectDir, destFile, link); }, uninstall: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + const src = obj.src; let target = obj.target; @@ -81,6 +94,8 @@ const handlers = { }, framework: { // CB-5238 custom frameworks only install: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + const src = obj.src; const custom = !!(obj.custom); // convert to boolean (if truthy/falsy) const embed = !!(obj.embed); // convert to boolean (if truthy/falsy) @@ -129,6 +144,8 @@ const handlers = { events.emit('verbose', util.format('Custom framework added to project. %s -> %s', src, JSON.stringify(opt))); }, uninstall: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + const src = obj.src; if (!obj.custom) { // CB-9825 cocoapod integration for plugins @@ -167,6 +184,8 @@ const handlers = { }, asset: { install: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + if (!obj.src) { throw new CordovaError(generateAttributeError('src', 'asset', plugin.id)); } @@ -178,6 +197,8 @@ const handlers = { if (options && options.usePlatformWww) copyFile(plugin.dir, obj.src, project.platformWww, obj.target); }, uninstall: function (obj, plugin, project, options) { + if (isSwiftPackagePlugin(plugin)) return; + const target = obj.target; if (!target) { diff --git a/lib/prepare.js b/lib/prepare.js index 10e1e06d..58466ed0 100644 --- a/lib/prepare.js +++ b/lib/prepare.js @@ -154,8 +154,8 @@ function updateConfigFile (sourceConfig, configMunger, locations) { const config = new ConfigParser(locations.configXml); xmlHelpers.mergeXml(sourceConfig.doc.getroot(), config.doc.getroot(), 'ios', /* clobber= */true); - config.write(); + return config; } diff --git a/templates/project/App.xcodeproj/project.pbxproj b/templates/project/App.xcodeproj/project.pbxproj index b10423b7..29ec0061 100755 --- a/templates/project/App.xcodeproj/project.pbxproj +++ b/templates/project/App.xcodeproj/project.pbxproj @@ -35,6 +35,7 @@ 90CBB5282C06968500B805A2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90CBB5272C06968500B805A2 /* AppDelegate.swift */; }; 90CBB52A2C06968500B805A2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90CBB5292C06968500B805A2 /* SceneDelegate.swift */; }; 90CBB52C2C06968500B805A2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90CBB52B2C06968500B805A2 /* ViewController.swift */; }; + 90D82ABD2CF19AEA001383CF /* CordovaPlugins in Frameworks */ = {isa = PBXBuildFile; productRef = 90D82ABC2CF19AEA001383CF /* CordovaPlugins */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -81,6 +82,7 @@ buildActionMask = 2147483647; files = ( 90A914592CA3D370003DB979 /* Cordova in Frameworks */, + 90D82ABD2CF19AEA001383CF /* CordovaPlugins in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -191,6 +193,7 @@ name = App; packageProductDependencies = ( 90A914582CA3D370003DB979 /* Cordova */, + 90D82ABC2CF19AEA001383CF /* CordovaPlugins */, ); productName = App; productReference = 90BD9B6C2C06907D000DEBAB /* App.app */; @@ -222,6 +225,7 @@ mainGroup = 90BD9B632C06907D000DEBAB /* CustomTemplate */; packageReferences = ( 90A914572CA3D370003DB979 /* XCLocalSwiftPackageReference "../../../cordova-ios" */, + 90D82ABB2CF19AEA001383CF /* XCLocalSwiftPackageReference "CordovaPlugins" */, ); productRefGroup = 90BD9B6D2C06907D000DEBAB /* Products */; projectDirPath = ""; @@ -317,8 +321,8 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; "DEPLOYMENT_LOCATION[sdk=iphonesimulator*]" = YES; - "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; "DEPLOYMENT_LOCATION[sdk=macosx*]" = YES; + "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; DSTROOT = "$(SRCROOT)/build"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -338,8 +342,8 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; "INSTALL_PATH[sdk=iphonesimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; "INSTALL_PATH[sdk=macosx*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; + "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; @@ -391,8 +395,8 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; "DEPLOYMENT_LOCATION[sdk=iphonesimulator*]" = YES; - "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; "DEPLOYMENT_LOCATION[sdk=macosx*]" = YES; + "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; DSTROOT = "$(SRCROOT)/build"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -406,8 +410,8 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; "INSTALL_PATH[sdk=iphonesimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; "INSTALL_PATH[sdk=macosx*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; + "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; @@ -525,6 +529,10 @@ isa = XCLocalSwiftPackageReference; relativePath = "../../../cordova-ios"; }; + 90D82ABB2CF19AEA001383CF /* XCLocalSwiftPackageReference "packages/cordova-ios-plugins" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = "packages/cordova-ios-plugins"; + }; /* End XCLocalSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -532,6 +540,10 @@ isa = XCSwiftPackageProductDependency; productName = Cordova; }; + 90D82ABC2CF19AEA001383CF /* CordovaPlugins */ = { + isa = XCSwiftPackageProductDependency; + productName = CordovaPlugins; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 90BD9B642C06907D000DEBAB /* Project object */; diff --git a/templates/project/packages/cordova-ios-plugins/Package.swift b/templates/project/packages/cordova-ios-plugins/Package.swift new file mode 100644 index 00000000..705e2778 --- /dev/null +++ b/templates/project/packages/cordova-ios-plugins/Package.swift @@ -0,0 +1,37 @@ +// swift-tools-version:5.5 + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import PackageDescription + +let package = Package( + name: "CordovaPlugins", + platforms: [ + .iOS(.v13), + .macCatalyst(.v13) + ], + products: [ + .library(name: "CordovaPlugins", targets: ["CordovaPlugins"]) + ], + targets: [ + .target(name: "CordovaPlugins") + ] +) + diff --git a/templates/project/packages/cordova-ios-plugins/Sources/CordovaPlugins/CordovaPlugins.swift b/templates/project/packages/cordova-ios-plugins/Sources/CordovaPlugins/CordovaPlugins.swift new file mode 100644 index 00000000..92baa917 --- /dev/null +++ b/templates/project/packages/cordova-ios-plugins/Sources/CordovaPlugins/CordovaPlugins.swift @@ -0,0 +1,21 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +// We need something here so that the empty package will compile successfully +public let isCordovaApp = true diff --git a/tests/spec/coverage.json b/tests/spec/coverage.json index f70d3440..c74f863e 100644 --- a/tests/spec/coverage.json +++ b/tests/spec/coverage.json @@ -1,8 +1,8 @@ { "spec_dir": "tests/spec", "spec_files": [ - "unit/**/*[sS]pec.js", - "createAndBuild.spec.js" + "unit/**/*[sS]pec.js", + "createAndBuild.spec.js" ], "stopSpecOnExpectationFailure": false, "random": false diff --git a/tests/spec/unit/Api.spec.js b/tests/spec/unit/Api.spec.js index ac638584..d2498d06 100644 --- a/tests/spec/unit/Api.spec.js +++ b/tests/spec/unit/Api.spec.js @@ -36,6 +36,7 @@ if (process.platform === 'darwin') { const projectFile = require('../../../lib/projectFile'); const BridgingHeader_mod = require('../../../lib/BridgingHeader.js'); +const SwiftPackage_mod = require('../../../lib/SwiftPackage.js'); const Podfile_mod = require('../../../lib/Podfile'); const PodsJson_mod = require('../../../lib/PodsJson'); const FIXTURES = path.join(__dirname, 'fixtures'); @@ -108,6 +109,7 @@ describe('Platform Api', () => { describe('addPlugin', () => { const my_plugin = { + getPlatforms () { return [{ name: 'ios' }]; }, getHeaderFiles: function () { return []; }, getFrameworks: function () { return []; }, getPodSpecs: function () { return []; } @@ -117,6 +119,7 @@ describe('Platform Api', () => { addPlugin: function () { return Promise.resolve(); } }); spyOn(BridgingHeader_mod, 'BridgingHeader'); + spyOn(SwiftPackage_mod, 'SwiftPackage'); spyOn(Podfile_mod, 'Podfile'); spyOn(PodsJson_mod, 'PodsJson'); }); @@ -145,6 +148,30 @@ describe('Platform Api', () => { }); }); }); + + describe('adding plugin with Swift package', () => { + let swiftPackage_mock; + const swift_plugin = { + id: 'swift_plugin', + getPlatforms () { return [{ name: 'ios', package: 'swift' }]; }, + getHeaderFiles: function () { return []; }, + getFrameworks: function () { return []; }, + getPodSpecs: function () { return []; } + }; + + beforeEach(() => { + swiftPackage_mock = jasmine.createSpyObj('swiftpackage mock', ['addPlugin']); + SwiftPackage_mod.SwiftPackage.and.returnValue(swiftPackage_mock); + }); + + it('should add the plugin reference to Package.swift', () => { + return api.addPlugin(swift_plugin) + .then(() => { + expect(swiftPackage_mock.addPlugin).toHaveBeenCalledWith(swift_plugin, jasmine.any(Object)); + }); + }); + }); + describe('adding pods since the plugin contained <podspecs>', () => { let podsjson_mock; let podfile_mock; @@ -301,6 +328,7 @@ describe('Platform Api', () => { }); describe('removePlugin', () => { const my_plugin = { + getPlatforms () { return [{ name: 'ios' }]; }, getHeaderFiles: function () { return []; }, getFrameworks: function () {}, getPodSpecs: function () { return []; } @@ -309,9 +337,33 @@ describe('Platform Api', () => { spyOn(PluginManager, 'get').and.returnValue({ removePlugin: function () { return Promise.resolve(); } }); + spyOn(SwiftPackage_mod, 'SwiftPackage'); spyOn(Podfile_mod, 'Podfile'); spyOn(PodsJson_mod, 'PodsJson'); }); + + describe('removing plugin with Swift package', () => { + let swiftPackage_mock; + const swift_plugin = { + id: 'swift_plugin', + getPlatforms () { return [{ name: 'ios', package: 'swift' }]; }, + getHeaderFiles: function () { return []; }, + getFrameworks: function () { return []; }, + getPodSpecs: function () { return []; } + }; + + beforeEach(() => { + swiftPackage_mock = jasmine.createSpyObj('swiftpackage mock', ['removePlugin']); + SwiftPackage_mod.SwiftPackage.and.returnValue(swiftPackage_mock); + }); + + it('should remove the plugin reference from Package.swift', () => { + return api.removePlugin(swift_plugin) + .then(() => { + expect(swiftPackage_mock.removePlugin).toHaveBeenCalledWith(swift_plugin); + }); + }); + }); describe('removing pods since the plugin contained <podspecs>', () => { let podsjson_mock; let podfile_mock; diff --git a/tests/spec/unit/Plugman/pluginHandler.spec.js b/tests/spec/unit/Plugman/pluginHandler.spec.js index 368f5f5a..e8ee1d0c 100644 --- a/tests/spec/unit/Plugman/pluginHandler.spec.js +++ b/tests/spec/unit/Plugman/pluginHandler.spec.js @@ -39,6 +39,7 @@ const faultyplugin = path.join(FIXTURES, 'org.test.plugins.faultyplugin'); const dummyplugin = path.join(FIXTURES, 'org.test.plugins.dummyplugin'); const weblessplugin = path.join(FIXTURES, 'org.test.plugins.weblessplugin'); const embedlinkplugin = path.join(FIXTURES, 'org.test.plugins.embedlinkplugin'); +const swiftpackageplugin = path.join(FIXTURES, 'org.test.plugins.swiftpackageplugin'); const dummyPluginInfo = new PluginInfo(dummyplugin); const dummy_id = dummyPluginInfo.id; @@ -60,16 +61,12 @@ const weblessPluginInfo = new PluginInfo(weblessplugin); const embedlinkPluginInfo = new PluginInfo(embedlinkplugin); const embed_link_interaction_frameworks = embedlinkPluginInfo.getFrameworks('ios'); +const swiftpackagePluginInfo = new PluginInfo(swiftpackageplugin); + function copyArray (arr) { return Array.prototype.slice.call(arr, 0); } -function slashJoin () { - // In some places we need to use forward slash instead of path.join(). - // See CB-7311. - return Array.prototype.join.call(arguments, '/'); -} - describe('ios plugin handler', () => { let dummyProject; @@ -114,13 +111,13 @@ describe('ios plugin handler', () => { const source = copyArray(valid_source).filter(s => s.targetDir === undefined); install(source[0], dummyPluginInfo, dummyProject); expect(dummyProject.xcode.addSourceFile) - .toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.m'), {}); + .toHaveBeenCalledWith(path.posix.join('Plugins', dummy_id, 'DummyPluginCommand.m'), {}); }); it('Test 004 : should call into xcodeproj\'s addSourceFile appropriately when element has a target-dir', () => { const source = copyArray(valid_source).filter(s => s.targetDir !== undefined); install(source[0], dummyPluginInfo, dummyProject); expect(dummyProject.xcode.addSourceFile) - .toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.m'), {}); + .toHaveBeenCalledWith(path.posix.join('Plugins', dummy_id, 'targetDir', 'TargetDirTest.m'), {}); }); it('Test 005 : should cp the file to the right target location when element has no target-dir', () => { const source = copyArray(valid_source).filter(s => s.targetDir === undefined); @@ -141,6 +138,13 @@ describe('ios plugin handler', () => { expect(dummyProject.xcode.addFramework) .toHaveBeenCalledWith(path.join('App', 'Plugins', dummy_id, 'SourceWithFramework.m'), { weak: false }); }); + + it('should not add source files for SPM plugins', () => { + const source = copyArray(swiftpackagePluginInfo.getSourceFiles('ios')); + install(source[0], swiftpackagePluginInfo, dummyProject); + + expect(dummyProject.xcode.addSourceFile).not.toHaveBeenCalled(); + }); }); describe('of <header-file> elements', () => { @@ -169,13 +173,13 @@ describe('ios plugin handler', () => { const headers = copyArray(valid_headers).filter(s => s.targetDir === undefined); install(headers[0], dummyPluginInfo, dummyProject); expect(dummyProject.xcode.addHeaderFile) - .toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.h')); + .toHaveBeenCalledWith(path.posix.join('Plugins', dummy_id, 'DummyPluginCommand.h')); }); it('Test 011 : should call into xcodeproj\'s addHeaderFile appropriately when element a target-dir', () => { const headers = copyArray(valid_headers).filter(s => s.targetDir !== undefined); install(headers[0], dummyPluginInfo, dummyProject); expect(dummyProject.xcode.addHeaderFile) - .toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.h')); + .toHaveBeenCalledWith(path.posix.join('Plugins', dummy_id, 'targetDir', 'TargetDirTest.h')); }); it('Test 012 : should cp the file to the right target location when element has no target-dir', () => { const headers = copyArray(valid_headers).filter(s => s.targetDir === undefined); @@ -407,17 +411,17 @@ describe('ios plugin handler', () => { }).xcode; // from org.test.plugins.dummyplugin - expect(xcode.hasFile(slashJoin('DummyPlugin.bundle'))).toEqual(jasmine.any(Object)); - expect(xcode.hasFile(slashJoin('org.test.plugins.dummyplugin', 'DummyPluginCommand.h'))).toEqual(jasmine.any(Object)); - expect(xcode.hasFile(slashJoin('org.test.plugins.dummyplugin', 'DummyPluginCommand.m'))).toEqual(jasmine.any(Object)); - expect(xcode.hasFile(slashJoin('org.test.plugins.dummyplugin', 'targetDir', 'TargetDirTest.h'))).toEqual(jasmine.any(Object)); - expect(xcode.hasFile(slashJoin('org.test.plugins.dummyplugin', 'targetDir', 'TargetDirTest.m'))).toEqual(jasmine.any(Object)); + expect(xcode.hasFile(path.posix.join('DummyPlugin.bundle'))).toEqual(jasmine.any(Object)); + expect(xcode.hasFile(path.posix.join('org.test.plugins.dummyplugin', 'DummyPluginCommand.h'))).toEqual(jasmine.any(Object)); + expect(xcode.hasFile(path.posix.join('org.test.plugins.dummyplugin', 'DummyPluginCommand.m'))).toEqual(jasmine.any(Object)); + expect(xcode.hasFile(path.posix.join('org.test.plugins.dummyplugin', 'targetDir', 'TargetDirTest.h'))).toEqual(jasmine.any(Object)); + expect(xcode.hasFile(path.posix.join('org.test.plugins.dummyplugin', 'targetDir', 'TargetDirTest.m'))).toEqual(jasmine.any(Object)); expect(xcode.hasFile('usr/lib/libsqlite3.dylib')).toEqual(jasmine.any(Object)); - expect(xcode.hasFile(slashJoin('App', 'Plugins', 'org.test.plugins.dummyplugin', 'Custom.framework'))).toEqual(jasmine.any(Object)); + expect(xcode.hasFile(path.posix.join('App', 'Plugins', 'org.test.plugins.dummyplugin', 'Custom.framework'))).toEqual(jasmine.any(Object)); // from org.test.plugins.weblessplugin - expect(xcode.hasFile(slashJoin('WeblessPluginViewController.xib'))).toEqual(jasmine.any(Object)); - expect(xcode.hasFile(slashJoin('org.test.plugins.weblessplugin', 'WeblessPluginCommand.h'))).toEqual(jasmine.any(Object)); - expect(xcode.hasFile(slashJoin('org.test.plugins.weblessplugin', 'WeblessPluginCommand.m'))).toEqual(jasmine.any(Object)); + expect(xcode.hasFile(path.posix.join('WeblessPluginViewController.xib'))).toEqual(jasmine.any(Object)); + expect(xcode.hasFile(path.posix.join('org.test.plugins.weblessplugin', 'WeblessPluginCommand.h'))).toEqual(jasmine.any(Object)); + expect(xcode.hasFile(path.posix.join('org.test.plugins.weblessplugin', 'WeblessPluginCommand.m'))).toEqual(jasmine.any(Object)); expect(xcode.hasFile('usr/lib/libsqlite3.dylib')).toEqual(jasmine.any(Object)); }); }); @@ -434,12 +438,12 @@ describe('ios plugin handler', () => { it('Test 029 : should call into xcodeproj\'s removeSourceFile appropriately when element has no target-dir', () => { const source = copyArray(valid_source).filter(s => s.targetDir === undefined); uninstall(source[0], dummyPluginInfo, dummyProject); - expect(dummyProject.xcode.removeSourceFile).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.m')); + expect(dummyProject.xcode.removeSourceFile).toHaveBeenCalledWith(path.posix.join('Plugins', dummy_id, 'DummyPluginCommand.m')); }); it('Test 030 : should call into xcodeproj\'s removeSourceFile appropriately when element a target-dir', () => { const source = copyArray(valid_source).filter(s => s.targetDir !== undefined); uninstall(source[0], dummyPluginInfo, dummyProject); - expect(dummyProject.xcode.removeSourceFile).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.m')); + expect(dummyProject.xcode.removeSourceFile).toHaveBeenCalledWith(path.posix.join('Plugins', dummy_id, 'targetDir', 'TargetDirTest.m')); }); it('Test 031 : should rm the file from the right target location when element has no target-dir', () => { const source = copyArray(valid_source).filter(s => s.targetDir === undefined); @@ -458,6 +462,13 @@ describe('ios plugin handler', () => { uninstall(source[0], dummyPluginInfo, dummyProject); expect(dummyProject.xcode.removeFramework).toHaveBeenCalledWith(path.join('App', 'Plugins', dummy_id, 'SourceWithFramework.m')); }); + + it('should not remove source files for SPM plugins', () => { + const source = copyArray(swiftpackagePluginInfo.getSourceFiles('ios')); + uninstall(source[0], swiftpackagePluginInfo, dummyProject); + + expect(dummyProject.xcode.removeSourceFile).not.toHaveBeenCalled(); + }); }); describe('of <header-file> elements', () => { @@ -469,12 +480,12 @@ describe('ios plugin handler', () => { it('Test 034 : should call into xcodeproj\'s removeHeaderFile appropriately when element has no target-dir', () => { const headers = copyArray(valid_headers).filter(s => s.targetDir === undefined); uninstall(headers[0], dummyPluginInfo, dummyProject); - expect(dummyProject.xcode.removeHeaderFile).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.h')); + expect(dummyProject.xcode.removeHeaderFile).toHaveBeenCalledWith(path.posix.join('Plugins', dummy_id, 'DummyPluginCommand.h')); }); it('Test 035 : should call into xcodeproj\'s removeHeaderFile appropriately when element a target-dir', () => { const headers = copyArray(valid_headers).filter(s => s.targetDir !== undefined); uninstall(headers[0], dummyPluginInfo, dummyProject); - expect(dummyProject.xcode.removeHeaderFile).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.h')); + expect(dummyProject.xcode.removeHeaderFile).toHaveBeenCalledWith(path.posix.join('Plugins', dummy_id, 'targetDir', 'TargetDirTest.h')); }); it('Test 036 : should rm the file from the right target location', () => { const headers = copyArray(valid_headers).filter(s => s.targetDir !== undefined); diff --git a/tests/spec/unit/SwiftPackage.spec.js b/tests/spec/unit/SwiftPackage.spec.js new file mode 100644 index 00000000..4e966cb4 --- /dev/null +++ b/tests/spec/unit/SwiftPackage.spec.js @@ -0,0 +1,218 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +const fs = require('node:fs'); +const path = require('node:path'); +const tmp = require('tmp'); +const SwiftPackage = require('../../../lib/SwiftPackage.js').SwiftPackage; +const Api = require('../../../lib/Api'); +const EventEmitter = require('node:events').EventEmitter; +const ConfigParser = require('cordova-common').ConfigParser; +const PluginInfo = require('cordova-common').PluginInfo; +const Podfile_mod = require('../../../lib/Podfile'); +const PodsJson_mod = require('../../../lib/PodsJson'); + +tmp.setGracefulCleanup(); + +const fixturePackage = fs.readFileSync(path.join(__dirname, 'fixtures', 'test-Package.swift'), 'utf-8'); + +describe('SwiftPackage', () => { + let tmpDir; + beforeEach(() => { + tmpDir = tmp.dirSync(); + }); + + afterEach(() => { + fs.rmSync(tmpDir.name, { recursive: true, force: true }); + }); + + it('should error if Package.swift file does not exist', () => { + expect(() => { + const _ = new SwiftPackage(tmpDir.name); + expect(_).not.toEqual(null); // To avoid ESLINT error "Do not use 'new' for side effects" + }).toThrow(); + }); + + it('should skip cocoapod library if nospm is true', () => { + const PROJ_NAME = 'dummyProj'; + const FIXTURES = path.join(__dirname, 'fixtures'); + const iosProjectFixture = path.join(FIXTURES, 'ios-packageswift-config-xml'); + const iosProject = path.join(FIXTURES, PROJ_NAME); + fs.cpSync(iosProject, tmpDir.name, { recursive: true }); + const iosProjectTest = tmpDir.name; + const iosPlatformTest = path.join(iosProjectTest, 'platforms', 'ios'); + fs.cpSync(iosProjectFixture, iosPlatformTest, { recursive: true }); + const cocoapod_swift_plugin = path.join(FIXTURES, 'org.test.plugins.swiftpackagecocoapodplugin'); + spyOn(Podfile_mod.Podfile.prototype, 'install').and.returnValue(Promise.resolve()); + spyOn(PodsJson_mod.PodsJson.prototype, 'setSwiftVersionForCocoaPodsLibraries').and.stub(); + const api = new Api('ios', iosPlatformTest, new EventEmitter()); + const project = { + root: iosProjectTest, + projectConfig: new ConfigParser(path.join(iosProjectTest, 'config.xml')), + locations: { + plugins: path.join(iosProjectTest, 'plugins'), + www: path.join(iosProjectTest, 'www') + } + }; + return api.prepare(project, {}) + .then(() => { + return api.addPlugin(new PluginInfo(cocoapod_swift_plugin), {}); + }) + .then(() => { + const podFilePath = path.join(iosPlatformTest, 'Podfile'); + const podFile = fs.readFileSync(podFilePath, 'utf8'); + expect(podFile).toContain('pod \'DummyObjCPodAlpha\''); + expect(podFile).not.toContain('pod \'DummyObjCPodBeta\''); + expect(podFile).toContain('pod \'DummyObjCPodGamma\''); + }); + }); + + describe('addPlugin', () => { + const my_plugin = { + id: 'my-plugin', + dir: path.join(__dirname, 'fixtures', 'org.test.plugins.swiftpackageplugin') + }; + + const namespaced_plugin = { + id: '@username/my-plugin', + dir: path.join(__dirname, 'fixtures', 'org.test.plugins.swiftpackageplugin') + }; + + let pkg; + beforeEach(() => { + fs.mkdirSync(path.join(tmpDir.name, 'packages', 'cordova-ios-plugins'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir.name, 'packages', 'cordova-ios-plugins', 'Package.swift'), fixturePackage, 'utf8'); + + pkg = new SwiftPackage(tmpDir.name); + }); + + it('should add plugin references to the package file', () => { + pkg.addPlugin(my_plugin); + + const pkgPath = path.join(tmpDir.name, 'packages', 'cordova-ios-plugins', 'Package.swift'); + const content = fs.readFileSync(pkgPath, 'utf8'); + expect(content).toContain('.package(name: "my-plugin", path: "../my-plugin")'); + expect(content).toContain('.product(name: "my-plugin", package: "my-plugin")'); + }); + + it('should copy the plugin into the packages directory', () => { + pkg.addPlugin(my_plugin); + + expect(fs.existsSync(path.join(tmpDir.name, 'packages', 'my-plugin'))).toBeTruthy(); + }); + + it('should update the CordovaLib dependency (copied)', () => { + fs.mkdirSync(path.join(tmpDir.name, 'packages', 'cordova-ios'), { recursive: true }); + + pkg.addPlugin(my_plugin); + + const pkgPath = path.join(tmpDir.name, 'packages', 'my-plugin', 'Package.swift'); + const content = fs.readFileSync(pkgPath, 'utf8'); + + const relativePath = path.posix.join('..', 'cordova-ios'); + + expect(content).toContain(`package(name: "cordova-ios", path: "${relativePath}"`); + expect(content).not.toContain('github.com/apache/cordova-ios'); + }); + + it('should update the CordovaLib dependency (linked)', () => { + pkg.addPlugin(my_plugin); + + const pkgPath = path.join(tmpDir.name, 'packages', 'my-plugin', 'Package.swift'); + const content = fs.readFileSync(pkgPath, 'utf8'); + + // Because we don't have the full project here, it behaves as if linked + const packageLoc = path.dirname(require.resolve('../../../package.json')); + const relativeLink = path.relative(path.dirname(pkgPath), packageLoc).replaceAll(path.sep, path.posix.sep); + + expect(content).toContain(`package(name: "cordova-ios", path: "${relativeLink}"`); + expect(content).not.toContain('github.com/apache/cordova-ios'); + }); + + it('should add namespaced plugin references to the package file', () => { + pkg.addPlugin(namespaced_plugin); + + const pkgPath = path.join(tmpDir.name, 'packages', 'cordova-ios-plugins', 'Package.swift'); + const content = fs.readFileSync(pkgPath, 'utf8'); + expect(content).toContain('.package(name: "@username/my-plugin", path: "../@username/my-plugin")'); + expect(content).toContain('.product(name: "@username/my-plugin", package: "@username/my-plugin")'); + }); + + it('should copy the namespaced plugin into the packages directory', () => { + pkg.addPlugin(namespaced_plugin); + + expect(fs.existsSync(path.join(tmpDir.name, 'packages', '@username', 'my-plugin'))).toBeTruthy(); + }); + + it('should add plugin references to the package file when linked', () => { + pkg.addPlugin(my_plugin, { link: true }); + + const pkgPath = path.join(tmpDir.name, 'packages', 'cordova-ios-plugins', 'Package.swift'); + const content = fs.readFileSync(pkgPath, 'utf8'); + + expect(content).toContain('.package(name: "my-plugin", path: "'); + expect(content).not.toContain('.package(name: "my-plugin", path: "../my-plugin")'); + expect(content).toContain('.product(name: "my-plugin", package: "my-plugin")'); + }); + + it('should copy a linked plugin into the packages directory', () => { + pkg.addPlugin(my_plugin, { link: true }); + + expect(fs.existsSync(path.join(tmpDir.name, 'packages', 'my-plugin'))).toBeFalsy(); + }); + }); + + describe('removePlugin', () => { + const my_plugin = { + id: 'my-plugin', + dir: path.join(__dirname, 'fixtures', 'org.test.plugins.swiftpackageplugin') + }; + + let pkg; + beforeEach(() => { + fs.mkdirSync(path.join(tmpDir.name, 'packages', 'cordova-ios-plugins'), { recursive: true }); + const pkgPath = path.join(tmpDir.name, 'packages', 'cordova-ios-plugins', 'Package.swift'); + fs.writeFileSync(pkgPath, fixturePackage, 'utf8'); + + pkg = new SwiftPackage(tmpDir.name); + fs.writeFileSync(pkgPath, fixturePackage + pkg._pluginReference(my_plugin, '../my-plugin'), 'utf8'); + }); + + it('should remove plugin references to the package file', () => { + pkg.removePlugin(my_plugin); + + const pkgPath = path.join(tmpDir.name, 'packages', 'cordova-ios-plugins', 'Package.swift'); + const content = fs.readFileSync(pkgPath, 'utf8'); + + expect(content).not.toContain('.package(name: "my-plugin"'); + expect(content).not.toContain('.product(name: "my-plugin", package: "my-plugin")'); + }); + + it('should remove the plugin from the packages directory', () => { + fs.mkdirSync(path.join(tmpDir.name, 'packages', 'my-plugin'), { recursive: true }); + fs.writeFileSync(path.join(tmpDir.name, 'packages', 'my-plugin', 'test.txt'), 'Test', 'utf-8'); + + expect(fs.existsSync(path.join(tmpDir.name, 'packages', 'my-plugin'))).toBeTruthy(); + + pkg.removePlugin(my_plugin); + + expect(fs.existsSync(path.join(tmpDir.name, 'packages', 'my-plugin'))).toBeFalsy(); + }); + }); +}); diff --git a/tests/spec/unit/fixtures/ios-config-xml/App.xcodeproj/project.pbxproj b/tests/spec/unit/fixtures/ios-config-xml/App.xcodeproj/project.pbxproj index 597e416f..da8158b2 100755 --- a/tests/spec/unit/fixtures/ios-config-xml/App.xcodeproj/project.pbxproj +++ b/tests/spec/unit/fixtures/ios-config-xml/App.xcodeproj/project.pbxproj @@ -35,6 +35,7 @@ 90CBB5282C06968500B805A2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90CBB5272C06968500B805A2 /* AppDelegate.swift */; }; 90CBB52A2C06968500B805A2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90CBB5292C06968500B805A2 /* SceneDelegate.swift */; }; 90CBB52C2C06968500B805A2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90CBB52B2C06968500B805A2 /* ViewController.swift */; }; + 90D82ABD2CF19AEA001383CF /* CordovaPlugins in Frameworks */ = {isa = PBXBuildFile; productRef = 90D82ABC2CF19AEA001383CF /* CordovaPlugins */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -80,6 +81,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 90D82ABD2CF19AEA001383CF /* CordovaPlugins in Frameworks */, 90A914592CA3D370003DB979 /* CordovaLib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -191,6 +193,7 @@ name = App; packageProductDependencies = ( 90A914582CA3D370003DB979 /* CordovaLib */, + 90D82ABC2CF19AEA001383CF /* CordovaPlugins */, ); productName = App; productReference = 90BD9B6C2C06907D000DEBAB /* App.app */; @@ -222,6 +225,7 @@ mainGroup = 90BD9B632C06907D000DEBAB /* CustomTemplate */; packageReferences = ( 90A914572CA3D370003DB979 /* XCLocalSwiftPackageReference "../../../cordova-ios" */, + 90D82ABB2CF19AEA001383CF /* XCLocalSwiftPackageReference "CordovaPlugins" */, ); productRefGroup = 90BD9B6D2C06907D000DEBAB /* Products */; projectDirPath = ""; @@ -317,8 +321,8 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; "DEPLOYMENT_LOCATION[sdk=iphonesimulator*]" = YES; - "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; "DEPLOYMENT_LOCATION[sdk=macosx*]" = YES; + "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; DSTROOT = "$(SRCROOT)/build"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -338,8 +342,8 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; "INSTALL_PATH[sdk=iphonesimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; "INSTALL_PATH[sdk=macosx*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; + "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; @@ -391,8 +395,8 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; "DEPLOYMENT_LOCATION[sdk=iphonesimulator*]" = YES; - "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; "DEPLOYMENT_LOCATION[sdk=macosx*]" = YES; + "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; DSTROOT = "$(SRCROOT)/build"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -406,8 +410,8 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; "INSTALL_PATH[sdk=iphonesimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; "INSTALL_PATH[sdk=macosx*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; + "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; @@ -525,6 +529,10 @@ isa = XCLocalSwiftPackageReference; relativePath = "../../../../../../cordova-ios"; }; + 90D82ABB2CF19AEA001383CF /* XCLocalSwiftPackageReference "CordovaPlugins" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = CordovaPlugins; + }; /* End XCLocalSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -532,6 +540,10 @@ isa = XCSwiftPackageProductDependency; productName = CordovaLib; }; + 90D82ABC2CF19AEA001383CF /* CordovaPlugins */ = { + isa = XCSwiftPackageProductDependency; + productName = CordovaPlugins; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 90BD9B642C06907D000DEBAB /* Project object */; diff --git a/tests/spec/unit/fixtures/ios-config-xml/CordovaPlugins/Package.swift b/tests/spec/unit/fixtures/ios-config-xml/CordovaPlugins/Package.swift new file mode 100644 index 00000000..705e2778 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-config-xml/CordovaPlugins/Package.swift @@ -0,0 +1,37 @@ +// swift-tools-version:5.5 + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import PackageDescription + +let package = Package( + name: "CordovaPlugins", + platforms: [ + .iOS(.v13), + .macCatalyst(.v13) + ], + products: [ + .library(name: "CordovaPlugins", targets: ["CordovaPlugins"]) + ], + targets: [ + .target(name: "CordovaPlugins") + ] +) + diff --git a/tests/spec/unit/fixtures/ios-config-xml/CordovaPlugins/Sources/CordovaPlugins/CordovaPlugins.swift b/tests/spec/unit/fixtures/ios-config-xml/CordovaPlugins/Sources/CordovaPlugins/CordovaPlugins.swift new file mode 100644 index 00000000..92baa917 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-config-xml/CordovaPlugins/Sources/CordovaPlugins/CordovaPlugins.swift @@ -0,0 +1,21 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +// We need something here so that the empty package will compile successfully +public let isCordovaApp = true diff --git a/tests/spec/unit/fixtures/ios-config-xml/App.xcodeproj/project.pbxproj b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcodeproj/project.pbxproj similarity index 97% copy from tests/spec/unit/fixtures/ios-config-xml/App.xcodeproj/project.pbxproj copy to tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcodeproj/project.pbxproj index 597e416f..da8158b2 100755 --- a/tests/spec/unit/fixtures/ios-config-xml/App.xcodeproj/project.pbxproj +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcodeproj/project.pbxproj @@ -35,6 +35,7 @@ 90CBB5282C06968500B805A2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90CBB5272C06968500B805A2 /* AppDelegate.swift */; }; 90CBB52A2C06968500B805A2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90CBB5292C06968500B805A2 /* SceneDelegate.swift */; }; 90CBB52C2C06968500B805A2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90CBB52B2C06968500B805A2 /* ViewController.swift */; }; + 90D82ABD2CF19AEA001383CF /* CordovaPlugins in Frameworks */ = {isa = PBXBuildFile; productRef = 90D82ABC2CF19AEA001383CF /* CordovaPlugins */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -80,6 +81,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 90D82ABD2CF19AEA001383CF /* CordovaPlugins in Frameworks */, 90A914592CA3D370003DB979 /* CordovaLib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -191,6 +193,7 @@ name = App; packageProductDependencies = ( 90A914582CA3D370003DB979 /* CordovaLib */, + 90D82ABC2CF19AEA001383CF /* CordovaPlugins */, ); productName = App; productReference = 90BD9B6C2C06907D000DEBAB /* App.app */; @@ -222,6 +225,7 @@ mainGroup = 90BD9B632C06907D000DEBAB /* CustomTemplate */; packageReferences = ( 90A914572CA3D370003DB979 /* XCLocalSwiftPackageReference "../../../cordova-ios" */, + 90D82ABB2CF19AEA001383CF /* XCLocalSwiftPackageReference "CordovaPlugins" */, ); productRefGroup = 90BD9B6D2C06907D000DEBAB /* Products */; projectDirPath = ""; @@ -317,8 +321,8 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; "DEPLOYMENT_LOCATION[sdk=iphonesimulator*]" = YES; - "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; "DEPLOYMENT_LOCATION[sdk=macosx*]" = YES; + "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; DSTROOT = "$(SRCROOT)/build"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -338,8 +342,8 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; "INSTALL_PATH[sdk=iphonesimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; "INSTALL_PATH[sdk=macosx*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; + "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; @@ -391,8 +395,8 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; "DEPLOYMENT_LOCATION[sdk=iphonesimulator*]" = YES; - "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; "DEPLOYMENT_LOCATION[sdk=macosx*]" = YES; + "DEPLOYMENT_LOCATION[sdk=xrsimulator*]" = YES; DSTROOT = "$(SRCROOT)/build"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -406,8 +410,8 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; "INSTALL_PATH[sdk=iphonesimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; - "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; "INSTALL_PATH[sdk=macosx*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; + "INSTALL_PATH[sdk=xrsimulator*]" = "$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; @@ -525,6 +529,10 @@ isa = XCLocalSwiftPackageReference; relativePath = "../../../../../../cordova-ios"; }; + 90D82ABB2CF19AEA001383CF /* XCLocalSwiftPackageReference "CordovaPlugins" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = CordovaPlugins; + }; /* End XCLocalSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -532,6 +540,10 @@ isa = XCSwiftPackageProductDependency; productName = CordovaLib; }; + 90D82ABC2CF19AEA001383CF /* CordovaPlugins */ = { + isa = XCSwiftPackageProductDependency; + productName = CordovaPlugins; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 90BD9B642C06907D000DEBAB /* Project object */; diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..21fc716e --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<Workspace + version = "1.0"> + <FileRef + location = "self:"> + </FileRef> +</Workspace> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,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"> +<plist version="1.0"> +<dict> + <key>IDEDidComputeMac32BitWarning</key> + <true/> +</dict> +</plist> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcworkspace/contents.xcworkspacedata b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..4bae5d8d --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<Workspace + version = "1.0"> + <FileRef + location = "group:App.xcodeproj"> + </FileRef> +</Workspace> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,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"> +<plist version="1.0"> +<dict> + <key>IDEDidComputeMac32BitWarning</key> + <true/> +</dict> +</plist> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcworkspace/xcshareddata/xcschemes/App.xcscheme b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcworkspace/xcshareddata/xcschemes/App.xcscheme new file mode 100644 index 00000000..2df61af2 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App.xcworkspace/xcshareddata/xcschemes/App.xcscheme @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<Scheme + LastUpgradeVersion = "0730" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "1D6058900D05DD3D006BFB54" + BuildableName = "App.app" + BlueprintName = "App" + ReferencedContainer = "container:App.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES"> + <Testables> + </Testables> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "1D6058900D05DD3D006BFB54" + BuildableName = "App.app" + BlueprintName = "App" + ReferencedContainer = "container:App.xcodeproj"> + </BuildableReference> + </MacroExpansion> + <AdditionalOptions> + </AdditionalOptions> + </TestAction> + <LaunchAction + buildConfiguration = "Debug" + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + debugServiceExtension = "internal" + allowLocationSimulation = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "1D6058900D05DD3D006BFB54" + BuildableName = "App.app" + BlueprintName = "App" + ReferencedContainer = "container:App.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + buildConfiguration = "Release" + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + debugDocumentVersioning = "YES"> + <BuildableProductRunnable + runnableDebuggingMode = "0"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "1D6058900D05DD3D006BFB54" + BuildableName = "App.app" + BlueprintName = "App" + ReferencedContainer = "container:App.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/.gitignore b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/.gitignore new file mode 100644 index 00000000..cc76483f --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/.gitignore @@ -0,0 +1,5 @@ +*.mode1v3 +*.perspectivev3 +*.pbxuser +.DS_Store +build/ diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/App-Info.plist b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/App-Info.plist new file mode 100644 index 00000000..96685af8 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/App-Info.plist @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>UTImportedTypeDeclarations</key> + <array> + <dict> + <key>UTTypeConformsTo</key> + <array> + <string>public.data</string> + </array> + <key>UTTypeDescription</key> + <string>WebAssembly</string> + <key>UTTypeIdentifier</key> + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> + <key>UTTypeTagSpecification</key> + <dict> + <key>public.filename-extension</key> + <string>wasm</string> + <key>public.mime-type</key> + <string>application/wasm</string> + </dict> + </dict> + </array> + <key>UIApplicationSceneManifest</key> + <dict> + <key>UIApplicationSupportsMultipleScenes</key> + <false/> + <key>UISceneConfigurations</key> + <dict> + <key>UIWindowSceneSessionRoleApplication</key> + <array> + <dict> + <key>UISceneConfigurationName</key> + <string>Default Configuration</string> + <key>UISceneDelegateClassName</key> + <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string> + <key>UISceneStoryboardFile</key> + <string>Main</string> + </dict> + </array> + </dict> + </dict> +</dict> +</plist> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/AppDelegate.h b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/AppDelegate.h new file mode 100644 index 00000000..62a77631 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/AppDelegate.h @@ -0,0 +1,29 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +#import <Cordova/CDVAppDelegate.h> + +#ifndef __CORDOVA_SILENCE_HEADER_DEPRECATIONS + #warning It is unsafe to rely on the AppDelegate class as an extension point. \ + Update your code to extend CDVAppDelegate instead -- \ + This code will stop working in Cordova iOS 9! +#endif + +@interface AppDelegate : CDVAppDelegate +@end diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/AppDelegate.swift b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/AppDelegate.swift new file mode 100644 index 00000000..e6ef28ff --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/AppDelegate.swift @@ -0,0 +1,29 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import UIKit + +@main +@_objcImplementation +extension AppDelegate { + open override func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } +} + diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/AppIcon.appiconset/Contents.json b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..2c8c083a --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "filename" : "icon.png", + "idiom" : "universal", + "platform": "ios", + "size" : "1024x1024" + }, + { + "filename" : "icon.png", + "idiom" : "universal", + "platform": "watchos", + "size" : "1024x1024" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/AppIcon.appiconset/icon.png b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/AppIcon.appiconset/icon.png new file mode 100644 index 00000000..b9250b12 Binary files /dev/null and b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/AppIcon.appiconset/icon.png differ diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/BackgroundColor.colorset/Contents.json b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/BackgroundColor.colorset/Contents.json new file mode 100644 index 00000000..462830f8 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/BackgroundColor.colorset/Contents.json @@ -0,0 +1,15 @@ +{ + "colors" : [ + { + "color" : { + "platform" : "ios", + "reference" : "systemBackgroundColor" + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/Contents.json b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/LaunchStoryboard.imageset/Contents.json b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/LaunchStoryboard.imageset/Contents.json new file mode 100644 index 00000000..eab1cd11 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/LaunchStoryboard.imageset/Contents.json @@ -0,0 +1,168 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + }, + { + "idiom" : "universal", + "scale" : "1x", + "height-class" : "compact" + }, + { + "idiom" : "universal", + "scale" : "2x", + "height-class" : "compact" + }, + { + "idiom" : "universal", + "scale" : "3x", + "height-class" : "compact" + }, + { + "idiom" : "universal", + "scale" : "1x", + "width-class" : "compact" + }, + { + "idiom" : "universal", + "scale" : "2x", + "width-class" : "compact" + }, + { + "idiom" : "universal", + "scale" : "3x", + "width-class" : "compact" + }, + { + "idiom" : "universal", + "width-class" : "compact", + "height-class" : "compact", + "scale" : "1x" + }, + { + "idiom" : "universal", + "width-class" : "compact", + "height-class" : "compact", + "scale" : "2x" + }, + { + "idiom" : "universal", + "width-class" : "compact", + "height-class" : "compact", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "scale" : "1x" + }, + { + "idiom" : "iphone", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "scale" : "1x", + "height-class" : "compact" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "height-class" : "compact" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "height-class" : "compact" + }, + { + "idiom" : "iphone", + "scale" : "1x", + "width-class" : "compact" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "width-class" : "compact" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "width-class" : "compact" + }, + { + "idiom" : "iphone", + "width-class" : "compact", + "height-class" : "compact", + "scale" : "1x" + }, + { + "idiom" : "iphone", + "width-class" : "compact", + "height-class" : "compact", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "width-class" : "compact", + "height-class" : "compact", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "height-class" : "compact" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "height-class" : "compact" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "width-class" : "compact" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "width-class" : "compact" + }, + { + "idiom" : "ipad", + "width-class" : "compact", + "height-class" : "compact", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "width-class" : "compact", + "height-class" : "compact", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/SplashScreenBackgroundColor.colorset/Contents.json b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/SplashScreenBackgroundColor.colorset/Contents.json new file mode 100644 index 00000000..462830f8 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/SplashScreenBackgroundColor.colorset/Contents.json @@ -0,0 +1,15 @@ +{ + "colors" : [ + { + "color" : { + "platform" : "ios", + "reference" : "systemBackgroundColor" + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/StatusBarBackgroundColor.colorset/Contents.json b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/StatusBarBackgroundColor.colorset/Contents.json new file mode 100644 index 00000000..462830f8 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Assets.xcassets/StatusBarBackgroundColor.colorset/Contents.json @@ -0,0 +1,15 @@ +{ + "colors" : [ + { + "color" : { + "platform" : "ios", + "reference" : "systemBackgroundColor" + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Base.lproj/CDVLaunchScreen.storyboard b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Base.lproj/CDVLaunchScreen.storyboard new file mode 100644 index 00000000..be89abe1 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Base.lproj/CDVLaunchScreen.storyboard @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> + <device id="retina6_1" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/> + <capability name="Named colors" minToolsVersion="9.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <scenes> + <!--View Controller--> + <scene sceneID="EHf-IW-A2E"> + <objects> + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> + <layoutGuides> + <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/> + <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/> + </layoutGuides> + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> + <rect key="frame" x="0.0" y="0.0" width="414" height="896"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LaunchStoryboard" translatesAutoresizingMaskIntoConstraints="NO" id="2ns-9I-Qjs"> + <rect key="frame" x="0.0" y="0.0" width="414" height="896"/> + </imageView> + </subviews> + <color key="backgroundColor" name="SplashScreenBackgroundColor"/> + <constraints> + <constraint firstAttribute="trailing" secondItem="2ns-9I-Qjs" secondAttribute="trailing" id="FZL-3Z-NFz"/> + <constraint firstItem="2ns-9I-Qjs" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="L9l-pw-wXj"/> + <constraint firstItem="2ns-9I-Qjs" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="oGN-hc-Uzj"/> + <constraint firstItem="2ns-9I-Qjs" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="rS9-Wd-zY4"/> + </constraints> + </view> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="53" y="375"/> + </scene> + </scenes> + <resources> + <image name="LaunchStoryboard" width="1366" height="1366"/> + <namedColor name="SplashScreenBackgroundColor"> + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </namedColor> + </resources> +</document> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Base.lproj/Main.storyboard b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Base.lproj/Main.storyboard new file mode 100644 index 00000000..3372d5d2 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Base.lproj/Main.storyboard @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r"> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/> + <capability name="Named colors" minToolsVersion="9.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <scenes> + <!--View Controller--> + <scene sceneID="tne-QT-ifu"> + <objects> + <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="$(PRODUCT_MODULE_NAME)" customModuleProvider="target" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="8bC-Xf-vdC"> + <rect key="frame" x="0.0" y="0.0" width="393" height="852"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" name="BackgroundColor"/> + </view> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="color" keyPath="backgroundColor"> + <color key="value" name="BackgroundColor"/> + </userDefinedRuntimeAttribute> + <userDefinedRuntimeAttribute type="color" keyPath="splashBackgroundColor"> + <color key="value" name="SplashScreenBackgroundColor"/> + </userDefinedRuntimeAttribute> + <userDefinedRuntimeAttribute type="boolean" keyPath="showSplashScreen" value="YES"/> + <userDefinedRuntimeAttribute type="color" keyPath="statusBarBackgroundColor"> + <color key="value" name="StatusBarBackgroundColor"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> + </objects> + </scene> + </scenes> + <resources> + <namedColor name="BackgroundColor"> + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </namedColor> + <namedColor name="SplashScreenBackgroundColor"> + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </namedColor> + <namedColor name="StatusBarBackgroundColor"> + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </namedColor> + </resources> +</document> + diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Bridging-Header.h b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Bridging-Header.h new file mode 100644 index 00000000..9dec5295 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Bridging-Header.h @@ -0,0 +1,25 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import <Cordova/Cordova.h> + +#define __CORDOVA_SILENCE_HEADER_DEPRECATIONS +#import "AppDelegate.h" +#import "MainViewController.h" +#undef __CORDOVA_SILENCE_HEADER_DEPRECATIONS diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Entitlements-Debug.plist b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Entitlements-Debug.plist new file mode 100644 index 00000000..1ed4ae5b --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Entitlements-Debug.plist @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<plist version="1.0"> + <dict> + </dict> +</plist> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Entitlements-Release.plist b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Entitlements-Release.plist new file mode 100644 index 00000000..1ed4ae5b --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Entitlements-Release.plist @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<plist version="1.0"> + <dict> + </dict> +</plist> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/MainViewController.h b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/MainViewController.h new file mode 100644 index 00000000..ddb37c4a --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/MainViewController.h @@ -0,0 +1,29 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +#import <Cordova/CDVViewController.h> + +#ifndef __CORDOVA_SILENCE_HEADER_DEPRECATIONS + #warning It is unsafe to rely on the MainViewController class as an extension point. \ + Update your code to extend CDVViewController instead -- \ + This code will stop working in Cordova iOS 9! +#endif + +@interface MainViewController : CDVViewController +@end diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Plugins/README b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Plugins/README new file mode 100644 index 00000000..87df09f2 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Plugins/README @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +Put the .h and .m files of your plugin here. The .js files of your plugin belong in the www folder. diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/PrivacyInfo.xcprivacy b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..4b2e70fd --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/PrivacyInfo.xcprivacy @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>NSPrivacyTracking</key> + <false/> + <key>NSPrivacyCollectedDataTypes</key> + <array/> + <key>NSPrivacyAccessedAPITypes</key> + <array/> + <key>NSPrivacyTrackingDomains</key> + <array/> +</dict> +</plist> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Resources/README b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Resources/README new file mode 100644 index 00000000..1872c8e9 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/Resources/README @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +Put resource files to embed in the app bundle here. diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/SceneDelegate.swift b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/SceneDelegate.swift new file mode 100644 index 00000000..83fd3110 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/SceneDelegate.swift @@ -0,0 +1,25 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? +} + diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/ViewController.swift b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/ViewController.swift new file mode 100644 index 00000000..87837032 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/ViewController.swift @@ -0,0 +1,27 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import Cordova + +@_objcImplementation +extension MainViewController { +} + +class ViewController: MainViewController { +} diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/config.xml b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/config.xml new file mode 100644 index 00000000..31a7c387 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/App/config.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<widget id="sample.app" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> + <name>SampleApp</name> + + <description> + A sample Apache Cordova application that responds to the deviceready event. + </description> + + <author href="http://cordova.io" email="d...@cordova.apache.org"> + Apache Cordova Team + </author> + + <content src="index.html" /> + + <!-- AllowList docs: https://cordova.apache.org/docs/en/latest/ --> + <access origin="*" /> + <!-- Grant certain URLs the ability to launch external applications. This + behaviour is set to match that of Cordova versions before 3.6.0, and + should be reviewed before launching an application in production. It + may be changed in the future. --> + <allow-intent href="http://*/*" /> + <allow-intent href="https://*/*" /> + <allow-intent href="tel:*" /> + <allow-intent href="sms:*" /> + <allow-intent href="mailto:*" /> + <allow-intent href="geo:*" /> + <allow-intent href="itms:*" /> + <allow-intent href="itms-apps:*" /> + + <!-- Preferences for iOS --> + <preference name="AllowInlineMediaPlayback" value="false" /> + <preference name="DisallowOverscroll" value="false" /> + <preference name="EnableViewportScale" value="false" /> + <preference name="MediaTypesRequiringUserActionForPlayback" value="false" /> + <preference name="SuppressesIncrementalRendering" value="false" /> + <preference name="SuppressesLongPressGesture" value="false" /> + <preference name="Suppresses3DTouchGesture" value="false" /> + + <feature name="CDVWebViewEngine"> + <param name="ios-package" value="CDVWebViewEngine" /> + </feature> + <feature name="LaunchScreen"> + <param name="ios-package" value="CDVLaunchScreen"/> + </feature> + <feature name="LocalStorage"> + <param name="ios-package" value="CDVLocalStorage"/> + </feature> + <feature name="Console"> + <param name="ios-package" value="CDVLogger"/> + <param name="onload" value="true"/> + </feature> + <feature name="HandleOpenUrl"> + <param name="ios-package" value="CDVHandleOpenURL"/> + <param name="onload" value="true"/> + </feature> + <feature name="IntentAndNavigationFilter"> + <param name="ios-package" value="CDVIntentAndNavigationFilter"/> + <param name="onload" value="true"/> + </feature> + <feature name="GestureHandler"> + <param name="ios-package" value="CDVGestureHandler"/> + <param name="onload" value="true"/> + </feature> +</widget> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/CordovaPlugins/Package.swift b/tests/spec/unit/fixtures/ios-packageswift-config-xml/CordovaPlugins/Package.swift new file mode 100644 index 00000000..705e2778 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/CordovaPlugins/Package.swift @@ -0,0 +1,37 @@ +// swift-tools-version:5.5 + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import PackageDescription + +let package = Package( + name: "CordovaPlugins", + platforms: [ + .iOS(.v13), + .macCatalyst(.v13) + ], + products: [ + .library(name: "CordovaPlugins", targets: ["CordovaPlugins"]) + ], + targets: [ + .target(name: "CordovaPlugins") + ] +) + diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/CordovaPlugins/Sources/CordovaPlugins/CordovaPlugins.swift b/tests/spec/unit/fixtures/ios-packageswift-config-xml/CordovaPlugins/Sources/CordovaPlugins/CordovaPlugins.swift new file mode 100644 index 00000000..92baa917 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/CordovaPlugins/Sources/CordovaPlugins/CordovaPlugins.swift @@ -0,0 +1,21 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +// We need something here so that the empty package will compile successfully +public let isCordovaApp = true diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/cordova/defaults.xml b/tests/spec/unit/fixtures/ios-packageswift-config-xml/cordova/defaults.xml new file mode 100644 index 00000000..1a7287d2 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/cordova/defaults.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<widget xmlns = "http://www.w3.org/ns/widgets" + id = "io.cordova.helloCordova" + version = "2.0.0"> + + <!-- Preferences for iOS --> + <preference name="AllowInlineMediaPlayback" value="false" /> + <preference name="DisallowOverscroll" value="false" /> + <preference name="EnableViewportScale" value="false" /> + <preference name="MediaTypesRequiringUserActionForPlayback" value="none" /> + <preference name="SuppressesIncrementalRendering" value="false" /> + <preference name="SuppressesLongPressGesture" value="false" /> + <preference name="Suppresses3DTouchGesture" value="false" /> + + <feature name="CDVWebViewEngine"> + <param name="ios-package" value="CDVWebViewEngine" /> + </feature> + <feature name="LaunchScreen"> + <param name="ios-package" value="CDVLaunchScreen"/> + </feature> + <feature name="LocalStorage"> + <param name="ios-package" value="CDVLocalStorage"/> + </feature> + <feature name="Console"> + <param name="ios-package" value="CDVLogger"/> + <param name="onload" value="true"/> + </feature> + <feature name="HandleOpenUrl"> + <param name="ios-package" value="CDVHandleOpenURL"/> + <param name="onload" value="true"/> + </feature> + <feature name="IntentAndNavigationFilter"> + <param name="ios-package" value="CDVIntentAndNavigationFilter"/> + <param name="onload" value="true"/> + </feature> + <feature name="GestureHandler"> + <param name="ios-package" value="CDVGestureHandler"/> + <param name="onload" value="true"/> + </feature> + +</widget> diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/packages/cordova-ios-plugins/Package.swift b/tests/spec/unit/fixtures/ios-packageswift-config-xml/packages/cordova-ios-plugins/Package.swift new file mode 100644 index 00000000..8f306e98 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/packages/cordova-ios-plugins/Package.swift @@ -0,0 +1,40 @@ +// swift-tools-version:5.5 + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import PackageDescription + +let package = Package( + name: "CordovaPlugins", + platforms: [ + .iOS(.v13), + .macCatalyst(.v13) + ], + products: [ + .library(name: "CordovaPlugins", targets: ["CordovaPlugins"]) + ], + targets: [ + .target(name: "CordovaPlugins") + ] +) + + +package.dependencies.append(.package(name: "org.test.plugins.swiftpackagecocoapodplugin", path: "../org.test.plugins.swiftpackagecocoapodplugin")) +package.targets.first?.dependencies.append(.product(name: "org.test.plugins.swiftpackagecocoapodplugin", package: "org.test.plugins.swiftpackagecocoapodplugin")) diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/packages/cordova-ios/Package.swift b/tests/spec/unit/fixtures/ios-packageswift-config-xml/packages/cordova-ios/Package.swift new file mode 100644 index 00000000..6571d093 --- /dev/null +++ b/tests/spec/unit/fixtures/ios-packageswift-config-xml/packages/cordova-ios/Package.swift @@ -0,0 +1,47 @@ +// swift-tools-version:5.5 + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +import PackageDescription + +let package = Package( + name: "Cordova", + platforms: [ + .iOS(.v13), + .macCatalyst(.v13) + ], + products: [ + .library(name: "Cordova", targets: ["Cordova"]) + ], + dependencies: [], + targets: [ + .target( + name: "Cordova", + path: "CordovaLib/", + exclude: ["Info.plist"], + resources: [ + .copy("PrivacyInfo.xcprivacy") + ], + cSettings: [ + .headerSearchPath("Classes/Private") + ] + ) + ] +) diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/platform_www/.gitkeep b/tests/spec/unit/fixtures/ios-packageswift-config-xml/platform_www/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/tests/spec/unit/fixtures/ios-packageswift-config-xml/www/.gitkeep b/tests/spec/unit/fixtures/ios-packageswift-config-xml/www/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/Package.swift b/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/Package.swift new file mode 100644 index 00000000..094dfbf4 --- /dev/null +++ b/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/Package.swift @@ -0,0 +1,47 @@ +// swift-tools-version:5.5 + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import PackageDescription + +let package = Package( + name: "org.test.plugins.swiftpackagecocoapodplugin", + platforms: [ + .iOS(.v13), + .macCatalyst(.v13) + ], + products: [ + .library(name: "org.test.plugins.swiftpackagecocoapodplugin", targets: ["PackagePodPlugin"]) + ], + dependencies: [ + .package(url: "https://github.com/apache/cordova-ios.git", branch: "master") + ], + targets: [ + .target( + name: "PackagePodPlugin", + dependencies: [ + .product(name: "Cordova", package: "cordova-ios") + ], + path: "src/ios" + ) + ] +) + + diff --git a/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/package.json b/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/package.json new file mode 100644 index 00000000..e06ed48b --- /dev/null +++ b/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/package.json @@ -0,0 +1,12 @@ +{ + "name": "org.test.plugins.swiftpackagecocoapodplugin", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "Apache License, Version 2.0" + } \ No newline at end of file diff --git a/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/plugin.xml b/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/plugin.xml new file mode 100644 index 00000000..1a1511da --- /dev/null +++ b/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/plugin.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0" id="org.test.plugins.swiftpackagecocoapodplugin" version="1.0.0"> + <name>Swift Package CocoaPod Plugin</name> + + <!-- ios --> + <platform name="ios" package="swift"> + <config-file parent="/*" target="config.xml"> + <feature name="PackagePodPlugin"> + <param name="ios-package" value="PackagePodPlugin" /> + <param name="onload" value="true" /> + </feature> + </config-file> + <source-file src="src/ios/PackagePodPlugin.swift" /> + <podspec> + <config> + <source url="https://cdn.cocoapods.org/"/> + </config> + <pods use-frameworks="true"> + <pod name="DummyObjCPodAlpha" spec="1.0.0" nospm="false" /> + <pod name="DummyObjCPodBeta" spec="1.0.0" nospm="true" /> + <pod name="DummyObjCPodGamma" spec="1.0.0"/> + </pods> + </podspec> + </platform> +</plugin> diff --git a/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/src/ios/PackagePodPlugin.swift b/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/src/ios/PackagePodPlugin.swift new file mode 100644 index 00000000..7bf201c8 --- /dev/null +++ b/tests/spec/unit/fixtures/org.test.plugins.swiftpackagecocoapodplugin/src/ios/PackagePodPlugin.swift @@ -0,0 +1,46 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + + +/*********************************************** + This Swift file is intentionally commented out. + + The purpose of this plugin is to test the new `nospm="true"` attribute in the <pod> element of plugin.xml, + which controls whether a CocoaPods library should be included when the plugin is installed as a Swift Package. + + While the plugin is structured as a Swift Package, it currently cannot function as a valid Cordova plugin + because the Cordova framework itself (specifically CDVPlugin and related classes) is not yet accessible + from within Swift Packages. Attempting to compile this file results in a build error due to the unresolved + `import Cordova` statement. + + To allow testing of CocoaPods integration without triggering build failures related to Swift Package usage, + the contents of this file are commented out. + + Once Cordova fully supports being used as a Swift Package dependency, this file can be uncommented + and used to implement plugin functionality. +***********************************************/ + +import Cordova + +@objc(PackagePodPlugin) +class PackagePodPlugin : CDVPlugin { + override func pluginInitialize() { + NSLog("Initialized Swift Package Pod Plugin"); + } +} diff --git a/tests/spec/unit/fixtures/org.test.plugins.swiftpackageplugin/Package.swift b/tests/spec/unit/fixtures/org.test.plugins.swiftpackageplugin/Package.swift new file mode 100644 index 00000000..0e8e0f82 --- /dev/null +++ b/tests/spec/unit/fixtures/org.test.plugins.swiftpackageplugin/Package.swift @@ -0,0 +1,46 @@ +// swift-tools-version:5.5 + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import PackageDescription + +let package = Package( + name: "PackagePlugin", + platforms: [ + .iOS(.v13), + .macCatalyst(.v13) + ], + products: [ + .library(name: "PackagePlugin", targets: ["PackagePlugin"]) + ], + dependencies: [ + .package(url: "https://github.com/apache/cordova-ios.git", branch: "master") + ], + targets: [ + .target( + name: "PackagePlugin", + dependencies: [ + .product(name: "Cordova", package: "cordova-ios") + ], + path: "src/ios" + ) + ] +) + diff --git a/tests/spec/unit/fixtures/org.test.plugins.swiftpackageplugin/plugin.xml b/tests/spec/unit/fixtures/org.test.plugins.swiftpackageplugin/plugin.xml new file mode 100644 index 00000000..08ddec80 --- /dev/null +++ b/tests/spec/unit/fixtures/org.test.plugins.swiftpackageplugin/plugin.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0" id="org.test.plugins.swiftpackageplugin" version="1.0.0"> + <name>Swift Package Plugin</name> + + <!-- ios --> + <platform name="ios" package="swift"> + <config-file parent="/*" target="config.xml"> + <feature name="PackagePlugin"> + <param name="ios-package" value="PackagePlugin" /> + </feature> + </config-file> + + <source-file src="src/ios/PackagePlugin.swift" /> + </platform> +</plugin> diff --git a/tests/spec/unit/fixtures/org.test.plugins.swiftpackageplugin/src/ios/PackagePlugin.swift b/tests/spec/unit/fixtures/org.test.plugins.swiftpackageplugin/src/ios/PackagePlugin.swift new file mode 100644 index 00000000..311031da --- /dev/null +++ b/tests/spec/unit/fixtures/org.test.plugins.swiftpackageplugin/src/ios/PackagePlugin.swift @@ -0,0 +1,27 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import Cordova + +@objc +class PackagePlugin : CDVPlugin { + override func pluginInitialize() { + NSLog("Initialized Swift Package Plugin"); + } +} diff --git a/tests/spec/unit/fixtures/test-Package.swift b/tests/spec/unit/fixtures/test-Package.swift new file mode 100644 index 00000000..705e2778 --- /dev/null +++ b/tests/spec/unit/fixtures/test-Package.swift @@ -0,0 +1,37 @@ +// swift-tools-version:5.5 + +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +import PackageDescription + +let package = Package( + name: "CordovaPlugins", + platforms: [ + .iOS(.v13), + .macCatalyst(.v13) + ], + products: [ + .library(name: "CordovaPlugins", targets: ["CordovaPlugins"]) + ], + targets: [ + .target(name: "CordovaPlugins") + ] +) + --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cordova.apache.org For additional commands, e-mail: commits-h...@cordova.apache.org