Skip to content

Commit eb04563

Browse files
committed
Add encoding/decoding tests for code execution types
1 parent 9e6fba2 commit eb04563

File tree

2 files changed

+157
-4
lines changed

2 files changed

+157
-4
lines changed

Sources/GoogleAI/FunctionCalling.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,13 +353,14 @@ extension CodeExecution: Encodable {}
353353

354354
extension ExecutableCode: Codable {}
355355

356-
@available(iOS 15.0, macOS 11.0, macCatalyst 15.0, *)
357356
extension CodeExecutionResult.Outcome: Codable {
358357
public init(from decoder: any Decoder) throws {
359358
let value = try decoder.singleValueContainer().decode(String.self)
360359
guard let decodedOutcome = CodeExecutionResult.Outcome(rawValue: value) else {
361-
Logging.default
362-
.error("[GoogleGenerativeAI] Unrecognized Outcome with value \"\(value)\".")
360+
if #available(iOS 15.0, macOS 11.0, macCatalyst 15.0, *) {
361+
Logging.default
362+
.error("[GoogleGenerativeAI] Unrecognized Outcome with value \"\(value)\".")
363+
}
363364
self = .unknown
364365
return
365366
}
@@ -368,7 +369,6 @@ extension CodeExecutionResult.Outcome: Codable {
368369
}
369370
}
370371

371-
@available(iOS 15.0, macOS 11.0, macCatalyst 15.0, *)
372372
extension CodeExecutionResult: Codable {
373373
public init(from decoder: any Decoder) throws {
374374
let container = try decoder.container(keyedBy: CodingKeys.self)
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
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 XCTest
16+
17+
@testable import GoogleGenerativeAI
18+
19+
final class CodeExecutionTests: XCTestCase {
20+
let decoder = JSONDecoder()
21+
let encoder = JSONEncoder()
22+
23+
let languageKey = "language"
24+
let languageValue = "PYTHON"
25+
let codeKey = "code"
26+
let codeValue = "print('Hello, world!')"
27+
let outcomeKey = "outcome"
28+
let outcomeValue = "OUTCOME_OK"
29+
let outputKey = "output"
30+
let outputValue = "Hello, world!"
31+
32+
override func setUp() {
33+
encoder.outputFormatting = .init(
34+
arrayLiteral: .prettyPrinted, .sortedKeys, .withoutEscapingSlashes
35+
)
36+
}
37+
38+
func testEncodeCodeExecution() throws {
39+
let jsonData = try encoder.encode(CodeExecution())
40+
41+
let json = try XCTUnwrap(String(data: jsonData, encoding: .utf8))
42+
XCTAssertEqual(json, """
43+
{
44+
45+
}
46+
""")
47+
}
48+
49+
func testDecodeExecutableCode() throws {
50+
let expectedExecutableCode = ExecutableCode(language: languageValue, code: codeValue)
51+
let json = """
52+
{
53+
"\(languageKey)": "\(languageValue)",
54+
"\(codeKey)": "\(codeValue)"
55+
}
56+
"""
57+
let jsonData = try XCTUnwrap(json.data(using: .utf8))
58+
59+
let executableCode = try XCTUnwrap(decoder.decode(ExecutableCode.self, from: jsonData))
60+
61+
XCTAssertEqual(executableCode, expectedExecutableCode)
62+
}
63+
64+
func testEncodeExecutableCode() throws {
65+
let executableCode = ExecutableCode(language: languageValue, code: codeValue)
66+
67+
let jsonData = try encoder.encode(executableCode)
68+
69+
let json = try XCTUnwrap(String(data: jsonData, encoding: .utf8))
70+
XCTAssertEqual(json, """
71+
{
72+
"\(codeKey)" : "\(codeValue)",
73+
"\(languageKey)" : "\(languageValue)"
74+
}
75+
""")
76+
}
77+
78+
func testDecodeCodeExecutionResultOutcome_ok() throws {
79+
let expectedOutcome = CodeExecutionResult.Outcome.ok
80+
let json = "\"\(outcomeValue)\""
81+
let jsonData = try XCTUnwrap(json.data(using: .utf8))
82+
83+
let outcome = try XCTUnwrap(decoder.decode(CodeExecutionResult.Outcome.self, from: jsonData))
84+
85+
XCTAssertEqual(outcome, expectedOutcome)
86+
}
87+
88+
func testDecodeCodeExecutionResultOutcome_unknown() throws {
89+
let expectedOutcome = CodeExecutionResult.Outcome.unknown
90+
let json = "\"OUTCOME_NEW_VALUE\""
91+
let jsonData = try XCTUnwrap(json.data(using: .utf8))
92+
93+
let outcome = try XCTUnwrap(decoder.decode(CodeExecutionResult.Outcome.self, from: jsonData))
94+
95+
XCTAssertEqual(outcome, expectedOutcome)
96+
}
97+
98+
func testEncodeCodeExecutionResultOutcome() throws {
99+
let jsonData = try encoder.encode(CodeExecutionResult.Outcome.ok)
100+
101+
let json = try XCTUnwrap(String(data: jsonData, encoding: .utf8))
102+
XCTAssertEqual(json, "\"\(outcomeValue)\"")
103+
}
104+
105+
func testDecodeCodeExecutionResult() throws {
106+
let expectedCodeExecutionResult = CodeExecutionResult(outcome: .ok, output: "Hello, world!")
107+
let json = """
108+
{
109+
"\(outcomeKey)": "\(outcomeValue)",
110+
"\(outputKey)": "\(outputValue)"
111+
}
112+
"""
113+
let jsonData = try XCTUnwrap(json.data(using: .utf8))
114+
115+
let codeExecutionResult = try XCTUnwrap(decoder.decode(
116+
CodeExecutionResult.self,
117+
from: jsonData
118+
))
119+
120+
XCTAssertEqual(codeExecutionResult, expectedCodeExecutionResult)
121+
}
122+
123+
func testDecodeCodeExecutionResult_missingOutput() throws {
124+
let expectedCodeExecutionResult = CodeExecutionResult(outcome: .deadlineExceeded, output: "")
125+
let json = """
126+
{
127+
"\(outcomeKey)": "OUTCOME_DEADLINE_EXCEEDED"
128+
}
129+
"""
130+
let jsonData = try XCTUnwrap(json.data(using: .utf8))
131+
132+
let codeExecutionResult = try XCTUnwrap(decoder.decode(
133+
CodeExecutionResult.self,
134+
from: jsonData
135+
))
136+
137+
XCTAssertEqual(codeExecutionResult, expectedCodeExecutionResult)
138+
}
139+
140+
func testEncodeCodeExecutionResult() throws {
141+
let codeExecutionResult = CodeExecutionResult(outcome: .ok, output: outputValue)
142+
143+
let jsonData = try encoder.encode(codeExecutionResult)
144+
145+
let json = try XCTUnwrap(String(data: jsonData, encoding: .utf8))
146+
XCTAssertEqual(json, """
147+
{
148+
"\(outcomeKey)" : "\(outcomeValue)",
149+
"\(outputKey)" : "\(outputValue)"
150+
}
151+
""")
152+
}
153+
}

0 commit comments

Comments
 (0)