Procházet zdrojové kódy

Build and run Functions Combine Unit Tests from SPM (#8080)

Paul Beusterien před 4 roky
rodič
revize
e789676eae

+ 5 - 0
.github/workflows/functions.yml

@@ -7,7 +7,10 @@ on:
     - '.github/workflows/functions.yml'
     - 'Interop/Auth/Public/*.h'
     - 'FirebaseMessaging/Sources/Interop/*.h'
+    - 'FirebaseTestingSupport/Functions/**'
+    - 'FirebaseCombineSwift/Sources/Functions/**'
     - 'Gemfile*'
+
   schedule:
     # Run every day at 3am (PST) - cron uses UTC times
     - cron:  '0 11 * * *'
@@ -43,6 +46,8 @@ jobs:
       run: xcodebuild -list
     - name: iOS Unit Tests
       run: scripts/third_party/travis/retry.sh ./scripts/build.sh FirebaseFunctions iOS spmbuildonly
+    - name: Combine Unit Tests
+      run: scripts/third_party/travis/retry.sh ./scripts/build.sh FunctionsCombineUnit iOS spm
 
   spm-cron:
     # Don't run on private repo.

+ 52 - 0
.swiftpm/xcode/xcshareddata/xcschemes/FunctionsCombineUnit.xcscheme

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1250"
+   version = "1.3">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES">
+      <Testables>
+         <TestableReference
+            skipped = "NO">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "FunctionsCombineUnit"
+               BuildableName = "FunctionsCombineUnit"
+               BlueprintName = "FunctionsCombineUnit"
+               ReferencedContainer = "container:">
+            </BuildableReference>
+         </TestableReference>
+      </Testables>
+   </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">
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 72 - 0
FirebaseTestingSupport/Functions/Sources/Public/FirebaseFunctionsTestingSupport/FIRFunctions+Testing.h

@@ -0,0 +1,72 @@
+// Copyright 2017 Google
+//
+// Licensed 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 file is a copy of Functions/Internal/FIRFunctions+Internal.h except for the modular import
+// of FirebaseFunctions.
+
+#import <Foundation/Foundation.h>
+
+@import FirebaseFunctions;
+
+@protocol FIRAppCheckInterop;
+@protocol FIRAuthInterop;
+@protocol FIRMessagingInterop;
+@class FIRHTTPSCallableResult;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FIRFunctions (Testing)
+
+/**
+ * Calls an http trigger endpoint.
+ * @param name The name of the http trigger.
+ * @param data Parameters to pass to the function. Can be anything encodable as JSON.
+ * @param completion The block to call when the request is complete.
+ */
+- (void)callFunction:(NSString *)name
+          withObject:(nullable id)data
+             timeout:(NSTimeInterval)timeout
+          completion:(void (^)(FIRHTTPSCallableResult *_Nullable result,
+                               NSError *_Nullable error))completion;
+
+/**
+ * Constructs the url for an http trigger. This is exposed only for testing.
+ * @param name The name of the endpoint.
+ */
+- (NSString *)URLWithName:(NSString *)name;
+
+/**
+ * Sets the functions client to send requests to localhost instead of Firebase.
+ * For testing only.
+ */
+- (void)useLocalhost;
+
+/**
+ * Internal initializer for the Cloud Functions client.
+ * @param projectID The project ID for the Firebase project.
+ * @param region The region for the http trigger, such as "us-central1".
+ * @param customDomain A custom domain for the http trigger, such as "https://mydomain.com".
+ * @param auth The auth provider to use (optional).
+ * @param messaging The messaging interop to use (optional).
+ */
+- (instancetype)initWithProjectID:(NSString *)projectID
+                           region:(NSString *)region
+                     customDomain:(nullable NSString *)customDomain
+                             auth:(nullable id<FIRAuthInterop>)auth
+                        messaging:(nullable id<FIRMessagingInterop>)messaging
+                         appCheck:(nullable id<FIRAppCheckInterop>)appCheck;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 49 - 0
FirebaseTestingSupport/Functions/Sources/Public/FirebaseFunctionsTestingSupport/FIRHTTPSCallable+Testing.h

@@ -0,0 +1,49 @@
+// Copyright 2017 Google
+//
+// Licensed 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 file is a copy of Functions/Internal/FIRHTTPSCallable+Internal.h except for the modular
+// import of FirebaseFunctions.
+
+#import <Foundation/Foundation.h>
+
+@import FirebaseFunctions;
+
+@class FIRFunctions;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface FIRHTTPSCallableResult (Testing)
+
+/**
+ * Initializes a callable result.
+ *
+ * @param result The data to wrap.
+ */
+- (instancetype)initWithData:(id)result;
+
+@end
+
+@interface FIRHTTPSCallable (Testing)
+
+/**
+ * Initializes a reference to the given http trigger.
+ *
+ * @param functionsClient The functions client to use for making network requests.
+ * @param name The name of the http trigger.
+ */
+- (instancetype)initWithFunctions:(FIRFunctions *)functionsClient name:(NSString *)name;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 2 - 1
FirebaseTestingSupport/Functions/Sources/Public/FirebaseFunctionsTestingSupport/FIRHTTPSCallableFake.h

@@ -12,9 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#import <FirebaseFunctions/FIRHTTPSCallable.h>
 #import <Foundation/Foundation.h>
 
+#import <FirebaseFunctions/FIRHTTPSCallable.h>
+
 NS_ASSUME_NONNULL_BEGIN
 
 /// A fake object to replace a real `FIRHTTPSCallableResult` in tests.

+ 4 - 2
FirebaseCombineSwift/Tests/Unit/Functions/HTTPSCallableTests.swift → Functions/Tests/CombineUnit/HTTPSCallableTests.swift

@@ -13,13 +13,15 @@
 // limitations under the License.
 
 import Foundation
+
 import Combine
-import XCTest
-import FirebaseFunctions
+import FirebaseFunctionsCombineSwift
 @testable import FirebaseFunctionsTestingSupport
+import XCTest
 
 // hardcoded in FIRHTTPSCallable.m
 private let kFunctionsTimeout: TimeInterval = 70.0
+private let expectationTimeout: TimeInterval = 2
 
 class MockFunctions: Functions {
   var mockCallFunction: () throws -> HTTPSCallableResult?

+ 23 - 5
Package.swift

@@ -408,11 +408,6 @@ let package = Package(
       dependencies: ["FirebaseAuth"],
       path: "FirebaseCombineSwift/Sources/Auth"
     ),
-    .target(
-      name: "FirebaseFunctionsCombineSwift",
-      dependencies: ["FirebaseFunctions"],
-      path: "FirebaseCombineSwift/Sources/Functions"
-    ),
     .target(
       name: "FirebaseStorageCombineSwift",
       dependencies: [
@@ -643,6 +638,8 @@ let package = Package(
       ]
     ),
 
+    // MARK: Firebase Functions
+
     .target(
       name: "FirebaseFunctionsTarget",
       dependencies: [.target(name: "FirebaseFunctions",
@@ -662,6 +659,27 @@ let package = Package(
         .headerSearchPath("../../"),
       ]
     ),
+    .target(
+      name: "FirebaseFunctionsCombineSwift",
+      dependencies: ["FirebaseFunctions"],
+      path: "FirebaseCombineSwift/Sources/Functions"
+    ),
+    .testTarget(
+      name: "FunctionsCombineUnit",
+      dependencies: ["FirebaseFunctionsCombineSwift",
+                     "FirebaseFunctionsTestingSupport",
+                     "SharedTestUtilities"],
+      path: "Functions/Tests/CombineUnit"
+    ),
+    .target(
+      name: "FirebaseFunctionsTestingSupport",
+      dependencies: ["FirebaseFunctions"],
+      path: "FirebaseTestingSupport/Functions/Sources",
+      publicHeadersPath: "Public",
+      cSettings: [
+        .headerSearchPath("../../.."),
+      ]
+    ),
 
     .target(
       name: "FirebaseInAppMessagingTarget",

+ 2 - 0
scripts/build.sh

@@ -646,10 +646,12 @@ case "$product-$platform-$method" in
       test
     ;;
 
+  # Note that the combine tests require setting the minimum iOS version to 13.0
   *-*-spm)
     RunXcodebuild \
       -scheme $product \
       "${xcb_flags[@]}" \
+      IPHONEOS_DEPLOYMENT_TARGET=13.0 \
       test
     ;;
 

+ 3 - 0
scripts/check_imports.swift

@@ -104,6 +104,9 @@ private func checkFile(_ file: String, logger: ErrorLogger, inRepo repoURL: URL)
       inSwiftPackageElse = false
     } else if inSwiftPackage {
       continue
+    } else if file.contains("FirebaseTestingSupport") {
+      // Module imports ok in SPM only test infrastructure.
+      continue
     } else if line.starts(with: "@import") {
       // "@import" is only allowed for Swift Package Manager.
       logger.importLog("@import should not be used in CocoaPods library code", file, lineNum)

+ 1 - 0
scripts/check_no_module_imports.sh

@@ -34,6 +34,7 @@ git grep "${options[@]}" \
      ':(exclude,glob)Crashlytics/**' \
      ':(exclude,glob)FirebaseStorage/**' \
      ':(exclude,glob)SwiftPMTests/**' \
+     ':(exclude,glob)FirebaseTestingSupport/**' \
      ':(exclude)Functions/FirebaseFunctions/FIRFunctions.m' \
      ':(exclude)HeadersImports.md' && exit_with_error