Skip to content

Commit ea6f84e

Browse files
authored
[Vertex AI] Use GoogleService-Info.plist in snippets tests (#13923)
1 parent 8328630 commit ea6f84e

File tree

7 files changed

+82
-36
lines changed

7 files changed

+82
-36
lines changed

FirebaseVertexAI/Tests/Unit/ChatTests.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@ final class ChatTests: XCTestCase {
3232
}
3333

3434
func testMergingText() async throws {
35-
#if SWIFT_PACKAGE
36-
let bundle = Bundle.module
37-
#else // SWIFT_PACKAGE
38-
let bundle = Bundle(for: Self.self)
39-
#endif // SWIFT_PACKAGE
35+
let bundle = BundleTestUtil.bundle()
4036
let fileURL = try XCTUnwrap(bundle.url(
4137
forResource: "streaming-success-basic-reply-parts",
4238
withExtension: "txt"

FirebaseVertexAI/Tests/Unit/GenerativeModelTests.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,11 +1446,7 @@ final class GenerativeModelTests: XCTestCase {
14461446
#if os(watchOS)
14471447
throw XCTSkip("Custom URL protocols are unsupported in watchOS 2 and later.")
14481448
#endif // os(watchOS)
1449-
#if SWIFT_PACKAGE
1450-
let bundle = Bundle.module
1451-
#else // SWIFT_PACKAGE
1452-
let bundle = Bundle(for: Self.self)
1453-
#endif // SWIFT_PACKAGE
1449+
let bundle = BundleTestUtil.bundle()
14541450
let fileURL = try XCTUnwrap(bundle.url(forResource: name, withExtension: ext))
14551451
return { request in
14561452
let requestURL = try XCTUnwrap(request.url)

FirebaseVertexAI/Tests/Unit/Snippets/FirebaseAppSnippetsUtil.swift

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,41 @@ import Foundation
1717
import XCTest
1818

1919
extension FirebaseApp {
20-
static let projectIDEnvVar = "PROJECT_ID"
21-
static let appIDEnvVar = "APP_ID"
22-
static let apiKeyEnvVar = "API_KEY"
23-
24-
static func configureForSnippets() throws {
25-
let environment = ProcessInfo.processInfo.environment
26-
guard let projectID = environment[projectIDEnvVar] else {
27-
throw XCTSkip("No Firebase Project ID specified in environment variable \(projectIDEnvVar).")
28-
}
29-
guard let appID = environment[appIDEnvVar] else {
30-
throw XCTSkip("No Google App ID specified in environment variable \(appIDEnvVar).")
20+
/// Configures the default `FirebaseApp` for use in snippets tests.
21+
///
22+
/// Uses a `GoogleService-Info.plist` file from the
23+
/// [`Resources`](https://github.com/firebase/firebase-ios-sdk/tree/main/FirebaseVertexAI/Tests/Unit/Resources)
24+
/// directory.
25+
///
26+
/// > Note: This is typically called in a snippet test's set up; overriding
27+
/// > `setUpWithError() throws` works well since it supports throwing errors.
28+
static func configureDefaultAppForSnippets() throws {
29+
guard let plistPath = BundleTestUtil.bundle().path(
30+
forResource: "GoogleService-Info",
31+
ofType: "plist"
32+
) else {
33+
throw XCTSkip("No GoogleService-Info.plist found in FirebaseVertexAI/Tests/Unit/Resources.")
3134
}
32-
guard let apiKey = environment[apiKeyEnvVar] else {
33-
throw XCTSkip("No API key specified in environment variable \(apiKeyEnvVar).")
34-
}
35-
36-
let options = FirebaseOptions(googleAppID: appID, gcmSenderID: "")
37-
options.projectID = projectID
38-
options.apiKey = apiKey
3935

36+
let options = try XCTUnwrap(FirebaseOptions(contentsOfFile: plistPath))
4037
FirebaseApp.configure(options: options)
38+
4139
guard FirebaseApp.isDefaultAppConfigured() else {
4240
XCTFail("Default Firebase app not configured.")
4341
return
4442
}
4543
}
44+
45+
/// Deletes the default `FirebaseApp` if configured.
46+
///
47+
/// > Note: This is typically called in a snippet test's tear down; overriding
48+
/// > `tearDown() async throws` works well since deletion is asynchronous.
49+
static func deleteDefaultAppForSnippets() async {
50+
// Checking if `isDefaultAppConfigured()` before calling `FirebaseApp.app()` suppresses a log
51+
// message that "The default Firebase app has not yet been configured." during `tearDown` when
52+
// the tests are skipped. This reduces extraneous noise in the test logs.
53+
if FirebaseApp.isDefaultAppConfigured(), let app = FirebaseApp.app() {
54+
await app.delete()
55+
}
56+
}
4657
}

FirebaseVertexAI/Tests/Unit/Snippets/FunctionCallingSnippets.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,17 @@ import FirebaseCore
1616
import FirebaseVertexAI
1717
import XCTest
1818

19+
// These snippet tests are intentionally skipped in CI jobs; see the README file in this directory
20+
// for instructions on running them manually.
21+
1922
@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
2023
final class FunctionCallingSnippets: XCTestCase {
2124
override func setUpWithError() throws {
22-
try FirebaseApp.configureForSnippets()
25+
try FirebaseApp.configureDefaultAppForSnippets()
2326
}
2427

2528
override func tearDown() async throws {
26-
if let app = FirebaseApp.app() {
27-
await app.delete()
28-
}
29+
await FirebaseApp.deleteDefaultAppForSnippets()
2930
}
3031

3132
func testFunctionCalling() async throws {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Vertex AI in Firebase Code Snippet Tests
2+
3+
These "tests" are for verifying that the code snippets provided in our
4+
documentation continue to compile. They are intentionally skipped in CI but can
5+
be manually run to verify expected behavior / outputs.
6+
7+
To run the tests, place a valid `GoogleService-Info.plist` file in the
8+
[`FirebaseVertexAI/Tests/Unit/Resources`](https://github.com/firebase/firebase-ios-sdk/tree/main/FirebaseVertexAI/Tests/Unit/Resources)
9+
folder. They may then be invoked individually or alongside the rest of the unit
10+
tests in Xcode.

FirebaseVertexAI/Tests/Unit/Snippets/StructuredOutputSnippets.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,17 @@ import FirebaseCore
1616
import FirebaseVertexAI
1717
import XCTest
1818

19+
// These snippet tests are intentionally skipped in CI jobs; see the README file in this directory
20+
// for instructions on running them manually.
21+
1922
@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
2023
final class StructuredOutputSnippets: XCTestCase {
2124
override func setUpWithError() throws {
22-
try FirebaseApp.configureForSnippets()
25+
try FirebaseApp.configureDefaultAppForSnippets()
2326
}
2427

2528
override func tearDown() async throws {
26-
if let app = FirebaseApp.app() {
27-
await app.delete()
28-
}
29+
await FirebaseApp.deleteDefaultAppForSnippets()
2930
}
3031

3132
func testStructuredOutputJSONBasic() async throws {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import Foundation
16+
17+
/// `Bundle` test utilities.
18+
final class BundleTestUtil {
19+
/// Returns the `Bundle` for the test module or target containing the file.
20+
///
21+
/// This abstracts away the `Bundle` differences between SPM and CocoaPods tests.
22+
static func bundle() -> Bundle {
23+
#if SWIFT_PACKAGE
24+
return Bundle.module
25+
#else // SWIFT_PACKAGE
26+
return Bundle(for: Self.self)
27+
#endif // SWIFT_PACKAGE
28+
}
29+
30+
private init() {}
31+
}

0 commit comments

Comments
 (0)