diff --git a/AppleEvents/AppleEventUtils.swift b/AppleEvents/AppleEventUtils.swift new file mode 100644 index 000000000..d608fc5ca --- /dev/null +++ b/AppleEvents/AppleEventUtils.swift @@ -0,0 +1,33 @@ +// +// AppleEventUtils.swift +// EvergreenTests +// +// Created by Olof Hellman on 1/7/18. +// Copyright © 2018 Olof Hellman. All rights reserved. +// + +import Foundation + +/* + @function FourCharCode() + @brief FourCharCode values like OSType, DescType or AEKeyword are really just + 4 byte values commonly represented as values like 'odoc' where each byte is + represented as its ASCII character. This function turns a swift string into + its FourCharCode equivalent, as swift doesn't recognize FourCharCode types + natively just yet. With this extension, one can use + "odoc".FourCharCode() + where one would really want to use 'odoc' +*/ +extension String { + func FourCharCode() -> FourCharCode { + var sum: UInt32 = 0 + guard ( self.count == 4) else { + print ("error: FourCharCode() expected a 4 character string") + return 0 + } + for scalar in self.unicodeScalars { + sum = (sum * 256) + scalar.value + } + return (sum) + } +} diff --git a/AppleEvents/NSAppleEventDescriptor+UserRecordFields.swift b/AppleEvents/NSAppleEventDescriptor+UserRecordFields.swift new file mode 100644 index 000000000..0a34a1091 --- /dev/null +++ b/AppleEvents/NSAppleEventDescriptor+UserRecordFields.swift @@ -0,0 +1,54 @@ +// +// NSAppleEventDescriptor+UserRecordFields.swift +// EvergreenTests +// +// Created by Olof Hellman on 1/7/18. +// Copyright © 2018 Olof Hellman. All rights reserved. +// + +import Foundation + +/* + @function usrfDictionary() + @brief When an apple event record contains key-value pairs for which the keys are + not associated with FourCharCode keys, the keys and values appear in a + "user record fields" AEList, in which the odd items are the keys and the + even items are the values. This function unpacks user record fields and + returns an analogous Swift dictionary +*/ +extension NSAppleEventDescriptor { + public func usrfDictionary() -> [String:NSAppleEventDescriptor] { + guard self.isRecordDescriptor else { + print ("error: usrfDictionary() expected input to be a record") + return [:] + } + guard let usrfList = self.forKeyword("usrf".FourCharCode()) else { + print ("error: usrfDictionary() couldn't find usrf") + return [:] + } + let listCount = usrfList.numberOfItems + guard (listCount%2 == 0) else { + print ("error: usrfDictionary() expected even number of items in usrf") + return [:] + } + var usrfDictionary:[String:NSAppleEventDescriptor] = [:] + var processedItems = 0 + while (processedItems < listCount) { + processedItems = processedItems + 2 + guard let nthlabel = usrfList.atIndex(processedItems-1) else { + print("usrfDictionary() couldn't get item \(processedItems+1) in usrf list") + continue + } + guard let nthvalue = usrfList.atIndex(processedItems) else { + print("usrfDictionary() couldn't get item \(processedItems+2) in usrf list") + continue + } + guard let nthLabelString = nthlabel.stringValue else { + print("usrfDictionary() expected label to be a String") + continue + } + usrfDictionary[nthLabelString] = nthvalue + } + return usrfDictionary; + } +} diff --git a/Evergreen.xcodeproj/project.pbxproj b/Evergreen.xcodeproj/project.pbxproj index c33ea1d93..5aeac4da6 100644 --- a/Evergreen.xcodeproj/project.pbxproj +++ b/Evergreen.xcodeproj/project.pbxproj @@ -124,6 +124,14 @@ 84FB9A2F1EDCD6C4003D53B9 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; }; 84FB9A301EDCD6C4003D53B9 /* Sparkle.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */; }; + D5558FD32002245C0066386B /* ScriptingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD22002245C0066386B /* ScriptingTests.swift */; }; + D5558FD5200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD4200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift */; }; + D5558FD9200228D30066386B /* AppleEventUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD7200228B80066386B /* AppleEventUtils.swift */; }; + D5907CA0200232A1005947E5 /* testGenericScript.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5907C9D20023249005947E5 /* testGenericScript.applescript */; }; + D5907CA1200232A1005947E5 /* testGetURL.applescript in Sources */ = {isa = PBXBuildFile; fileRef = D5558FD1200223F60066386B /* testGetURL.applescript */; }; + D5907CA2200232AD005947E5 /* testGenericScript.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5907C9D20023249005947E5 /* testGenericScript.applescript */; }; + D5907CA3200232AF005947E5 /* testGetURL.applescript in CopyFiles */ = {isa = PBXBuildFile; fileRef = D5558FD1200223F60066386B /* testGetURL.applescript */; }; + D5D1751220020B980047B29D /* Evergreen.sdef in Resources */ = {isa = PBXBuildFile; fileRef = D5D175012002039D0047B29D /* Evergreen.sdef */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -411,6 +419,17 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + D5907C9B20022EC7005947E5 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = TestScripts; + dstSubfolderSpec = 7; + files = ( + D5907CA2200232AD005947E5 /* testGenericScript.applescript in CopyFiles */, + D5907CA3200232AF005947E5 /* testGetURL.applescript in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -527,6 +546,17 @@ 84F2D5391FC2308B00998D64 /* UnreadFeed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnreadFeed.swift; sourceTree = ""; }; 84FB9A2D1EDCD6B8003D53B9 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Frameworks/Vendor/Sparkle.framework; sourceTree = SOURCE_ROOT; }; 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaviconURLFinder.swift; sourceTree = ""; }; + D5558FD1200223F60066386B /* testGetURL.applescript */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.applescript; path = testGetURL.applescript; sourceTree = ""; }; + D5558FD22002245C0066386B /* ScriptingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ScriptingTests.swift; path = EvergreenTests/ScriptingTests/ScriptingTests.swift; sourceTree = SOURCE_ROOT; }; + D5558FD4200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "NSAppleEventDescriptor+UserRecordFields.swift"; path = "AppleEvents/NSAppleEventDescriptor+UserRecordFields.swift"; sourceTree = SOURCE_ROOT; }; + D5558FD7200228B80066386B /* AppleEventUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppleEventUtils.swift; sourceTree = ""; }; + D5907C9D20023249005947E5 /* testGenericScript.applescript */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.applescript; path = testGenericScript.applescript; sourceTree = ""; }; + D5907CDC2002F0BE005947E5 /* Evergreen_project_release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project_release.xcconfig; sourceTree = ""; }; + D5907CDD2002F0BE005947E5 /* Evergreen_project_debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project_debug.xcconfig; sourceTree = ""; }; + D5907CDE2002F0BE005947E5 /* Evergreen_project.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_project.xcconfig; sourceTree = ""; }; + D5907CDF2002F0F9005947E5 /* EvergreenTests_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = EvergreenTests_target.xcconfig; sourceTree = ""; }; + D5907CE02002F0FA005947E5 /* Evergreen_target.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Evergreen_target.xcconfig; sourceTree = ""; }; + D5D175012002039D0047B29D /* Evergreen.sdef */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = Evergreen.sdef; path = ../Resources/Evergreen.sdef; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -828,6 +858,7 @@ 849A97991ED9EFB6007D329B /* Resources */ = { isa = PBXGroup; children = ( + D5D175012002039D0047B29D /* Evergreen.sdef */, 849C646C1ED37A5D003D8FC0 /* Info.plist */, 84EB380F1FBA8B9F000D2111 /* KeyboardShortcuts */, ); @@ -872,9 +903,11 @@ 848F6AE31FC29CFA002D422E /* Favicons */, 845213211FCA5B10003B6E93 /* Images */, 849A97961ED9EFAA007D329B /* Extensions */, + D5558FD6200227E60066386B /* AppleEvents */, 849A97991ED9EFB6007D329B /* Resources */, 84FB9A2C1EDCD6A4003D53B9 /* Frameworks */, 849C64741ED37A5D003D8FC0 /* EvergreenTests */, + D5907CDA2002F084005947E5 /* xcconfig */, 849C64611ED37A5D003D8FC0 /* Products */, 846E77301F6EF5D600A165E2 /* Account.xcodeproj */, 846E77161F6EF5D000A165E2 /* Database.xcodeproj */, @@ -902,6 +935,7 @@ 849C64741ED37A5D003D8FC0 /* EvergreenTests */ = { isa = PBXGroup; children = ( + D5558FC020021C290066386B /* ScriptingTests */, 849C64751ED37A5D003D8FC0 /* EvergreenTests.swift */, 849C64771ED37A5D003D8FC0 /* Info.plist */, ); @@ -1035,6 +1069,45 @@ path = Evergreen/Extensions; sourceTree = ""; }; + D5558FC020021C290066386B /* ScriptingTests */ = { + isa = PBXGroup; + children = ( + D5558FCF20021C590066386B /* scripts */, + D5558FD22002245C0066386B /* ScriptingTests.swift */, + ); + path = ScriptingTests; + sourceTree = ""; + }; + D5558FCF20021C590066386B /* scripts */ = { + isa = PBXGroup; + children = ( + D5907C9D20023249005947E5 /* testGenericScript.applescript */, + D5558FD1200223F60066386B /* testGetURL.applescript */, + ); + path = scripts; + sourceTree = ""; + }; + D5558FD6200227E60066386B /* AppleEvents */ = { + isa = PBXGroup; + children = ( + D5558FD7200228B80066386B /* AppleEventUtils.swift */, + D5558FD4200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift */, + ); + path = AppleEvents; + sourceTree = ""; + }; + D5907CDA2002F084005947E5 /* xcconfig */ = { + isa = PBXGroup; + children = ( + D5907CDD2002F0BE005947E5 /* Evergreen_project_debug.xcconfig */, + D5907CDC2002F0BE005947E5 /* Evergreen_project_release.xcconfig */, + D5907CDE2002F0BE005947E5 /* Evergreen_project.xcconfig */, + D5907CE02002F0FA005947E5 /* Evergreen_target.xcconfig */, + D5907CDF2002F0F9005947E5 /* EvergreenTests_target.xcconfig */, + ); + path = xcconfig; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1075,6 +1148,7 @@ 849C646D1ED37A5D003D8FC0 /* Sources */, 849C646E1ED37A5D003D8FC0 /* Frameworks */, 849C646F1ED37A5D003D8FC0 /* Resources */, + D5907C9B20022EC7005947E5 /* CopyFiles */, ); buildRules = ( ); @@ -1374,6 +1448,7 @@ 849A97B21ED9FA69007D329B /* MainWindow.storyboard in Resources */, 849A979C1ED9EFEB007D329B /* styleSheet.css in Resources */, 849A97A61ED9F94D007D329B /* Preferences.storyboard in Resources */, + D5D1751220020B980047B29D /* Evergreen.sdef in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1489,7 +1564,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D5558FD5200225680066386B /* NSAppleEventDescriptor+UserRecordFields.swift in Sources */, + D5558FD9200228D30066386B /* AppleEventUtils.swift in Sources */, + D5907CA1200232A1005947E5 /* testGetURL.applescript in Sources */, 849C64761ED37A5D003D8FC0 /* EvergreenTests.swift in Sources */, + D5558FD32002245C0066386B /* ScriptingTests.swift in Sources */, + D5907CA0200232A1005947E5 /* testGenericScript.applescript in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1613,179 +1693,45 @@ /* Begin XCBuildConfiguration section */ 849C64781ED37A5D003D8FC0 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D5907CDD2002F0BE005947E5 /* Evergreen_project_debug.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = M8L2WTLA8W; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_SWIFT3_OBJC_INFERENCE = Off; - SWIFT_VERSION = 4.0; }; name = Debug; }; 849C64791ED37A5D003D8FC0 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D5907CDC2002F0BE005947E5 /* Evergreen_project_release.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = M8L2WTLA8W; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_SWIFT3_OBJC_INFERENCE = Off; - SWIFT_VERSION = 4.0; }; name = Release; }; 849C647B1ED37A5D003D8FC0 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D5907CE02002F0FA005947E5 /* Evergreen_target.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Developer ID Application"; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = M8L2WTLA8W; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Frameworks/Vendor", - ); - INFOPLIST_FILE = Evergreen/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - OTHER_SWIFT_FLAGS = "-DDEBUG"; - PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Evergreen; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Debug; }; 849C647C1ED37A5D003D8FC0 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D5907CE02002F0FA005947E5 /* Evergreen_target.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Developer ID Application"; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = M8L2WTLA8W; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Frameworks/Vendor", - ); - INFOPLIST_FILE = Evergreen/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - OTHER_SWIFT_FLAGS = "-DRELEASE"; - PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Evergreen; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; }; name = Release; }; 849C647E1ED37A5D003D8FC0 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D5907CDF2002F0F9005947E5 /* EvergreenTests_target.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 9C84TZ7Q6Z; - INFOPLIST_FILE = EvergreenTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.EvergreenTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Evergreen.app/Contents/MacOS/Evergreen"; }; name = Debug; }; 849C647F1ED37A5D003D8FC0 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D5907CDF2002F0F9005947E5 /* EvergreenTests_target.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 9C84TZ7Q6Z; - INFOPLIST_FILE = EvergreenTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.EvergreenTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Evergreen.app/Contents/MacOS/Evergreen"; }; name = Release; }; diff --git a/Evergreen/Info.plist b/Evergreen/Info.plist index e2653665c..33ce922ac 100644 --- a/Evergreen/Info.plist +++ b/Evergreen/Info.plist @@ -37,5 +37,9 @@ NSAllowsArbitraryLoads + NSAppleScriptEnabled + + OSAScriptingDefinition + Evergreen.sdef diff --git a/Evergreen/Resources/Evergreen.sdef b/Evergreen/Resources/Evergreen.sdef new file mode 100644 index 000000000..3cb46db91 --- /dev/null +++ b/Evergreen/Resources/Evergreen.sdef @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + diff --git a/EvergreenTests/ScriptingTests/ScriptingTests.swift b/EvergreenTests/ScriptingTests/ScriptingTests.swift new file mode 100644 index 000000000..2846f064a --- /dev/null +++ b/EvergreenTests/ScriptingTests/ScriptingTests.swift @@ -0,0 +1,81 @@ +// +// ScriptingTests.swift +// EvergreenTests +// +// Created by Olof Hellman on 1/7/18. +// Copyright © 2018 Olof Hellman. All rights reserved. +// + +import XCTest + +class ScriptingTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + /* + @function doIndividualScript + @param filename -- name of a .applescript (sans extention) in the test bundle's + Resources/TestScripts directory + @brief given a file, loads the script and runs it. Expects a result from running + the script of the form + {test_result:true, script_result:} + if the test_result is false or is missing, the test fails + @return the value of script_result, if any + */ + func doIndividualScript(filename:String) -> NSAppleEventDescriptor? { + var errorDict: NSDictionary? = nil + let testBundle = Bundle(for: type(of: self)) + let url = testBundle.url(forResource:filename, withExtension:"applescript", subdirectory:"TestScripts") + guard let testScriptUrl = url else { + XCTFail("Failed Getting script URL") + return nil + } + + guard let testScript = NSAppleScript(contentsOf: testScriptUrl, error: &errorDict) else { + XCTFail("Failed initializing NSAppleScript") + print ("error is \(String(describing: errorDict))") + return nil + } + + let scriptResult = testScript.executeAndReturnError(&errorDict) + if (errorDict != nil) { + XCTFail("Failed executing script") + print ("error is \(String(describing: errorDict))") + return nil + } + + let usrfDictionary = scriptResult.usrfDictionary() + guard let testResult = usrfDictionary["test_result"] else { + XCTFail("test script didn't return test result in usrf") + return nil + } + + XCTAssert(testResult.booleanValue == true, "test_result should be true") + + return usrfDictionary["script_result"] + } + + /* + @function testGenericScript + @brief An example of how a script can be run as part of an XCTest + the applescript returns + {test_result:true, script_result:"Geoducks!"} + doIndividualScript() verifies the test_result portion + this code verifies the script_result portion + */ + func testGenericScript() { + let scriptResult = doIndividualScript(filename: "testGenericScript") + XCTAssert( scriptResult?.stringValue == "Geoducks!") + } + + func testGetUrlScript() { + _ = doIndividualScript(filename: "testGetURL") + } + +} diff --git a/EvergreenTests/ScriptingTests/scripts/testGenericScript.applescript b/EvergreenTests/ScriptingTests/scripts/testGenericScript.applescript new file mode 100644 index 000000000..2092312ba --- /dev/null +++ b/EvergreenTests/ScriptingTests/scripts/testGenericScript.applescript @@ -0,0 +1,13 @@ + +-- Evergreen scripting unit tests expect a dictionary to be returned from a script +-- containing either +-- {test_result:true} +-- to indicate success or +-- {test_result:false} +-- to indicate failure +-- Data can be passed back to unit test code by including a script_result field +-- for example this script returns "Geoducks!" as the result +-- this can be used as part of XCTest verification +-- see the testGenericScript() function in the ScriptingTests XCTestCase + +return {test_result:true, script_result:"Geoducks!"} diff --git a/EvergreenTests/ScriptingTests/scripts/testGetURL.applescript b/EvergreenTests/ScriptingTests/scripts/testGetURL.applescript new file mode 100644 index 000000000..b0f0fe9ef --- /dev/null +++ b/EvergreenTests/ScriptingTests/scripts/testGetURL.applescript @@ -0,0 +1,19 @@ +try + tell application "Evergreen" + open location "http://scripting.com/rss" + end tell +on error message + return {test_result:false, script_result:message} +end + +-- open location is not expected to return a value +-- trying to access result should trigger an error, and that indicates a successful test + +try + set getURLResult to the result + set testResult to false +on error message + set testResult to true +end try + +return {test_result:testResult} diff --git a/xcconfig/EvergreenTests_target.xcconfig b/xcconfig/EvergreenTests_target.xcconfig new file mode 100644 index 000000000..d218c329f --- /dev/null +++ b/xcconfig/EvergreenTests_target.xcconfig @@ -0,0 +1,16 @@ +DEVELOPMENT_TEAM = 9C84TZ7Q6Z +CODE_SIGN_STYLE = Automatic + +// See the notes in Evergreen_target.xcconfig on why the +// DeveloperSettings.xcconfig is #included here + +#include "../../SharedXcodeSettings/DeveloperSettings.xcconfig" + +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +COMBINE_HIDPI_IMAGES = YES +BUNDLE_LOADER = $(TEST_HOST) +LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks +INFOPLIST_FILE = EvergreenTests/Info.plist +PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.EvergreenTests +PRODUCT_NAME = $(TARGET_NAME) +TEST_HOST = $(BUILT_PRODUCTS_DIR)/Evergreen.app/Contents/MacOS/Evergreen diff --git a/xcconfig/Evergreen_project.xcconfig b/xcconfig/Evergreen_project.xcconfig new file mode 100644 index 000000000..21c28c3fd --- /dev/null +++ b/xcconfig/Evergreen_project.xcconfig @@ -0,0 +1,38 @@ +SDKROOT = macosx +COPY_PHASE_STRIP = NO +MACOSX_DEPLOYMENT_TARGET = 10.13 +ALWAYS_SEARCH_USER_PATHS = NO +GCC_NO_COMMON_BLOCKS = YES +GCC_C_LANGUAGE_STANDARD = gnu99 +CLANG_CXX_LANGUAGE_STANDARD = gnu++0x +CLANG_CXX_LIBRARY = libc++ +CLANG_ENABLE_MODULES = YES +CLANG_ENABLE_OBJC_ARC = YES +ENABLE_STRICT_OBJC_MSGSEND = YES +CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES +CLANG_WARN_DOCUMENTATION_COMMENTS = YES +CLANG_WARN_EMPTY_BODY = YES +CLANG_WARN_BOOL_CONVERSION = YES +CLANG_WARN_CONSTANT_CONVERSION = YES +GCC_WARN_64_TO_32_BIT_CONVERSION = YES +CLANG_WARN_ENUM_CONVERSION = YES +CLANG_WARN_INT_CONVERSION = YES +CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES +CLANG_WARN_INFINITE_RECURSION = YES +GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE +CLANG_WARN_UNREACHABLE_CODE = YES +GCC_WARN_UNUSED_FUNCTION = YES +GCC_WARN_UNUSED_VARIABLE = YES +CLANG_WARN_RANGE_LOOP_ANALYSIS = YES +CLANG_WARN_SUSPICIOUS_MOVE = YES +CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_OBJC_LITERAL_CONVERSION = YES +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR +CLANG_ANALYZER_NONNULL = YES +SWIFT_SWIFT3_OBJC_INFERENCE = Off +SWIFT_VERSION = 4.0 diff --git a/xcconfig/Evergreen_project_debug.xcconfig b/xcconfig/Evergreen_project_debug.xcconfig new file mode 100644 index 000000000..52c790f32 --- /dev/null +++ b/xcconfig/Evergreen_project_debug.xcconfig @@ -0,0 +1,13 @@ +#include "./Evergreen_project.xcconfig" + +ONLY_ACTIVE_ARCH = YES +DEBUG_INFORMATION_FORMAT = dwarf +ENABLE_TESTABILITY = YES +GCC_DYNAMIC_NO_PIC = NO +GCC_OPTIMIZATION_LEVEL = 0 +GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 $(inherited) +OTHER_SWIFT_FLAGS = -DDEBUG +SWIFT_OPTIMIZATION_LEVEL = -Onone +SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG +MTL_ENABLE_DEBUG_INFO = YES + diff --git a/xcconfig/Evergreen_project_release.xcconfig b/xcconfig/Evergreen_project_release.xcconfig new file mode 100644 index 000000000..958363ef2 --- /dev/null +++ b/xcconfig/Evergreen_project_release.xcconfig @@ -0,0 +1,8 @@ +#include "./Evergreen_project.xcconfig" + +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym +ENABLE_NS_ASSERTIONS = NO +OTHER_SWIFT_FLAGS = -DRELEASE +SWIFT_OPTIMIZATION_LEVEL = -Owholemodule +MTL_ENABLE_DEBUG_INFO = NO + diff --git a/xcconfig/Evergreen_target.xcconfig b/xcconfig/Evergreen_target.xcconfig new file mode 100644 index 000000000..edd30621f --- /dev/null +++ b/xcconfig/Evergreen_target.xcconfig @@ -0,0 +1,38 @@ +CODE_SIGN_IDENTITY = Developer ID Application +DEVELOPMENT_TEAM = M8L2WTLA8W +CODE_SIGN_STYLE = Manual +PROVISIONING_PROFILE_SPECIFIER = + +// developers can locally override the Xcode settings for code signing +// by creating a DeveloperSettings.xcconfig file locally at the appropriate path +// This allows a pristine project to have code signing set up with the appropriate +// developer ID and certificates, and for dev to be able to have local settings +// without needing to check in anything into source control +// +// As an example, make a ../../SharedXcodeSettings/DeveloperSettings.xcconfig file and +// give it the contents +// +// CODE_SIGN_IDENTITY = Mac Developer +// DEVELOPMENT_TEAM = +// CODE_SIGN_STYLE = Automatic +// PROVISIONING_PROFILE_SPECIFIER = +// +// And you should be able to build without code signing errors and without modifying +// the Evergreen Xcode project. +// +// Example: if your Evergreen Xcode project file is at +// /Users/Shared/git/Evergreen/Evergreen.xcodeproj +// create your DeveloperSettings.xcconfig file at +// /Users/Shared/git/SharedXcodeSettings/DeveloperSettings.xcconfig +// + +#include "../../SharedXcodeSettings/DeveloperSettings.xcconfig" + +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +COMBINE_HIDPI_IMAGES = YES +LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks +INFOPLIST_FILE = Evergreen/Info.plist +PRODUCT_BUNDLE_IDENTIFIER = com.ranchero.Evergreen +PRODUCT_NAME = $(TARGET_NAME) +FRAMEWORK_SEARCH_PATHS = $(inherited) $(PROJECT_DIR)/Frameworks/Vendor +ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon