@@ -308,6 +308,33 @@ final class GenerativeModelGoogleAITests: XCTestCase {
308
308
XCTAssertTrue ( thoughtSignature. hasPrefix ( " CtQOAVSoXO74PmYr9AFu " ) )
309
309
}
310
310
311
+ func testGenerateContent_success_codeExecution( ) async throws {
312
+ MockURLProtocol . requestHandler = try GenerativeModelTestUtil . httpRequestHandler (
313
+ forResource: " unary-success-code-execution " ,
314
+ withExtension: " json " ,
315
+ subdirectory: googleAISubdirectory
316
+ )
317
+
318
+ let response = try await model. generateContent ( testPrompt)
319
+
320
+ XCTAssertEqual ( response. candidates. count, 1 )
321
+ let candidate = try XCTUnwrap ( response. candidates. first)
322
+ let parts = candidate. content. parts
323
+ XCTAssertEqual ( candidate. finishReason, . stop)
324
+ XCTAssertEqual ( parts. count, 3 )
325
+ let executableCodePart = try XCTUnwrap ( parts [ 0 ] as? ExecutableCodePart )
326
+ XCTAssertFalse ( executableCodePart. isThought)
327
+ XCTAssertEqual ( executableCodePart. language, . python)
328
+ XCTAssertTrue ( executableCodePart. code. starts ( with: " prime_numbers = [2, 3, 5, 7, 11] " ) )
329
+ let codeExecutionResultPart = try XCTUnwrap ( parts [ 1 ] as? CodeExecutionResultPart )
330
+ XCTAssertFalse ( codeExecutionResultPart. isThought)
331
+ XCTAssertEqual ( codeExecutionResultPart. outcome, . ok)
332
+ XCTAssertEqual ( codeExecutionResultPart. output, " sum_of_primes=28 \n " )
333
+ let textPart = try XCTUnwrap ( parts [ 2 ] as? TextPart )
334
+ XCTAssertFalse ( textPart. isThought)
335
+ XCTAssertTrue ( textPart. text. hasPrefix ( " The first 5 prime numbers are 2, 3, 5, 7, and 11. " ) )
336
+ }
337
+
311
338
func testGenerateContent_failure_invalidAPIKey( ) async throws {
312
339
let expectedStatusCode = 400
313
340
MockURLProtocol . requestHandler = try GenerativeModelTestUtil . httpRequestHandler (
@@ -526,6 +553,39 @@ final class GenerativeModelGoogleAITests: XCTestCase {
526
553
}
527
554
}
528
555
556
+ func testGenerateContentStream_success_codeExecution( ) async throws {
557
+ MockURLProtocol . requestHandler = try GenerativeModelTestUtil . httpRequestHandler (
558
+ forResource: " streaming-success-code-execution " ,
559
+ withExtension: " txt " ,
560
+ subdirectory: googleAISubdirectory
561
+ )
562
+
563
+ var parts = [ any Part ] ( )
564
+ let stream = try model. generateContentStream ( testPrompt)
565
+ for try await response in stream {
566
+ if let responseParts = response. candidates. first? . content. parts {
567
+ parts. append ( contentsOf: responseParts)
568
+ }
569
+ }
570
+
571
+ let thoughtParts = parts. filter { $0. isThought }
572
+ XCTAssertEqual ( thoughtParts. count, 0 )
573
+ let textParts = parts. filter { $0 is TextPart }
574
+ XCTAssertGreaterThan ( textParts. count, 0 )
575
+ let executableCodeParts = parts. compactMap { $0 as? ExecutableCodePart }
576
+ XCTAssertEqual ( executableCodeParts. count, 1 )
577
+ let executableCodePart = try XCTUnwrap ( executableCodeParts. first)
578
+ XCTAssertFalse ( executableCodePart. isThought)
579
+ XCTAssertEqual ( executableCodePart. language, . python)
580
+ XCTAssertTrue ( executableCodePart. code. starts ( with: " prime_numbers = [2, 3, 5, 7, 11] " ) )
581
+ let codeExecutionResultParts = parts. compactMap { $0 as? CodeExecutionResultPart }
582
+ XCTAssertEqual ( codeExecutionResultParts. count, 1 )
583
+ let codeExecutionResultPart = try XCTUnwrap ( codeExecutionResultParts. first)
584
+ XCTAssertFalse ( codeExecutionResultPart. isThought)
585
+ XCTAssertEqual ( codeExecutionResultPart. outcome, . ok)
586
+ XCTAssertEqual ( codeExecutionResultPart. output, " The sum of the first 5 prime numbers is: 28 \n " )
587
+ }
588
+
529
589
func testGenerateContentStream_failureInvalidAPIKey( ) async throws {
530
590
MockURLProtocol . requestHandler = try GenerativeModelTestUtil . httpRequestHandler (
531
591
forResource: " unary-failure-api-key " ,
0 commit comments