Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add unit tests #4

Merged
merged 1 commit into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ let package = Package(
name: "AISwiftAssist"),
.testTarget(
name: "AISwiftAssistTests",
dependencies: ["AISwiftAssist"]),
dependencies: ["AISwiftAssist"]
),
]
)
14 changes: 7 additions & 7 deletions Sources/AISwiftAssist/APIs/AssistantsAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public protocol IAssistantsAPI: AnyObject {
/// Returns a list of assistants.
/// - Parameter parameters: Parameters for the list of assistants.
/// - Returns: A list of assistant objects.
func get(with parameters: ASAListAssistantsParameters?) async throws -> [ASAAssistant]
func get(with parameters: ASAListAssistantsParameters?) async throws -> ASAListAssistantsResponse

/// Create an assistant with a model and instructions.
/// - Parameter createAssistant: The create assistant model.
Expand Down Expand Up @@ -58,29 +58,29 @@ public final class AssistantsAPI: HTTPClient, IAssistantsAPI {
self.urlSession = urlSession
}

public func get(with parameters: ASAListAssistantsParameters? = nil) async throws -> [ASAAssistant] {
public func get(with parameters: ASAListAssistantsParameters? = nil) async throws -> ASAListAssistantsResponse {
let endpoint = AssistantEndpoint.getAssistants(parameters)
return try await sendRequest(endpoint: endpoint, responseModel: [ASAAssistant].self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAListAssistantsResponse.self)
}

public func create(by createAssistant: ASACreateAssistantRequest) async throws -> ASAAssistant {
let endpoint = AssistantEndpoint.createAssistant(createAssistant)
return try await sendRequest(endpoint: endpoint, responseModel: ASAAssistant.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAAssistant.self)
}

public func retrieve(by assistantId: String) async throws -> ASAAssistant {
let endpoint = AssistantEndpoint.retrieveAssistant(assistantId)
return try await sendRequest(endpoint: endpoint, responseModel: ASAAssistant.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAAssistant.self)
}

public func modify(by assistantId: String, modifyAssistant: ASAModifyAssistantRequest) async throws -> ASAAssistant {
let endpoint = AssistantEndpoint.modifyAssistant(assistantId, modifyAssistant)
return try await sendRequest(endpoint: endpoint, responseModel: ASAAssistant.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAAssistant.self)
}

public func delete(by assistantId: String) async throws -> ASADeleteModelResponse {
let endpoint = AssistantEndpoint.deleteAssistant(assistantId)
return try await sendRequest(endpoint: endpoint, responseModel: ASADeleteModelResponse.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASADeleteModelResponse.self)
}

}
Expand Down
8 changes: 4 additions & 4 deletions Sources/AISwiftAssist/APIs/MessagesAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,21 @@ public final class MessagesAPI: HTTPClient, IMessagesAPI {

public func create(by threadId: String, createMessage: ASACreateMessageRequest) async throws -> ASAMessage {
let endpoint = MessagesEndpoint.createMessage(threadId, createMessage)
return try await sendRequest(endpoint: endpoint, responseModel: ASAMessage.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessage.self)
}

public func retrieve(by threadId: String, messageId: String) async throws -> ASAMessage {
let endpoint = MessagesEndpoint.retrieveMessage(threadId, messageId)
return try await sendRequest(endpoint: endpoint, responseModel: ASAMessage.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessage.self)
}

public func modify(by threadId: String, messageId: String, modifyMessage: ASAModifyMessageRequest) async throws -> ASAMessage {
let endpoint = MessagesEndpoint.modifyMessage(threadId, messageId, modifyMessage)
return try await sendRequest(endpoint: endpoint, responseModel: ASAMessage.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessage.self)
}

public func getMessages(by threadId: String, parameters: ASAListMessagesParameters?) async throws -> ASAMessagesListResponse {
let endpoint = MessagesEndpoint.listMessages(threadId, parameters)
return try await sendRequest(endpoint: endpoint, responseModel: ASAMessagesListResponse.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessagesListResponse.self)
}
}
6 changes: 3 additions & 3 deletions Sources/AISwiftAssist/APIs/ModelsAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ public final class ModelsAPI: HTTPClient, IModelsAPI {

public func get() async throws -> ASAListModelsResponse {
let endpoint = ModelsEndpoint.getModels
return try await sendRequest(endpoint: endpoint, responseModel: ASAListModelsResponse.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAListModelsResponse.self)
}

public func retrieve(by modelId: String) async throws -> ASAModel {
let endpoint = ModelsEndpoint.retrieveModel(modelId)
return try await sendRequest(endpoint: endpoint, responseModel: ASAModel.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAModel.self)
}

public func delete(by modelId: String) async throws -> ASADeleteModelResponse {
let endpoint = ModelsEndpoint.deleteModel(modelId)
return try await sendRequest(endpoint: endpoint, responseModel: ASADeleteModelResponse.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASADeleteModelResponse.self)
}
}
2 changes: 1 addition & 1 deletion Sources/AISwiftAssist/APIs/RunsAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public final class RunsAPI: HTTPClient, IRunsAPI {

public func create(by threadId: String, createRun: ASACreateRunRequest) async throws -> ASARun {
let endpoint = RunsEndpoint.createRun(threadId, createRun)
return try await sendRequest(endpoint: endpoint, responseModel: ASARun.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASARun.self)
}

}
8 changes: 4 additions & 4 deletions Sources/AISwiftAssist/APIs/ThreadsAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,21 @@ public final class ThreadsAPI: HTTPClient, IThreadsAPI {

public func create(by createThreads: ASACreateThreadRequest?) async throws -> ASAThread {
let endpoint = ThreadsEndpoint.createThread(createThreads)
return try await sendRequest(endpoint: endpoint, responseModel: ASAThread.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAThread.self)
}

public func retrieve(threadId: String) async throws -> ASAThread {
let endpoint = ThreadsEndpoint.retrieveThread(threadId)
return try await sendRequest(endpoint: endpoint, responseModel: ASAThread.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAThread.self)
}

public func modify(threadId: String, with modifyThread: ASAModifyThreadRequest) async throws -> ASAThread {
let endpoint = ThreadsEndpoint.modifyThread(threadId, modifyThread)
return try await sendRequest(endpoint: endpoint, responseModel: ASAThread.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAThread.self)
}

public func delete(threadId: String) async throws -> ASADeleteModelResponse {
let endpoint = ThreadsEndpoint.deleteThread(threadId)
return try await sendRequest(endpoint: endpoint, responseModel: ASADeleteModelResponse.self)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASADeleteModelResponse.self)
}
}
12 changes: 0 additions & 12 deletions Tests/AISwiftAssistTests/AISwiftAssistTests.swift

This file was deleted.

192 changes: 192 additions & 0 deletions Tests/AISwiftAssistTests/APIs/AssistantsAPITests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
//
// AssistantsAPITests.swift
//
//
// Created by Alexey on 11/19/23.
//

import XCTest
@testable import AISwiftAssist

final class AssistantsAPITests: XCTestCase {

var assistantsAPI: IAssistantsAPI!

override func setUp() {
super.setUp()
let configuration = URLSessionConfiguration.default
configuration.protocolClasses = [MockURLProtocol.self]
let mockURLSession = URLSession(configuration: configuration)
assistantsAPI = AssistantsAPI(urlSession: mockURLSession)
}

override func tearDown() {
assistantsAPI = nil
super.tearDown()
}

func testGetAssistants() async {
do {
// Simulate server response
let mockData = AssistantsAPITests.list.data(using: .utf8)!

MockURLProtocol.requestHandler = { request in
let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)!
return (response, mockData)
}

let response: ASAListAssistantsResponse = try await assistantsAPI.get(with: nil)

XCTAssertNotNil(response)
XCTAssertEqual(response.object, "list")
XCTAssertEqual(response.data.count, 3)
XCTAssertEqual(response.firstId, "asst_abc123")
XCTAssertEqual(response.lastId, "asst_abc789")
XCTAssertFalse(response.hasMore)

// Checks for specific assistants
XCTAssertEqual(response.data[0].id, "asst_abc123")
XCTAssertEqual(response.data[0].objectType, "assistant")
XCTAssertEqual(response.data[0].createdAt, 1698982736)
XCTAssertEqual(response.data[0].name, "Coding Tutor")
XCTAssertEqual(response.data[0].model, "gpt-4")
XCTAssertEqual(response.data[0].instructions, "You are a helpful assistant designed to make me better at coding!")

XCTAssertEqual(response.data[1].id, "asst_abc456")
XCTAssertEqual(response.data[1].objectType, "assistant")
XCTAssertEqual(response.data[1].createdAt, 1698982718)
XCTAssertEqual(response.data[1].name, "My Assistant")
XCTAssertEqual(response.data[1].model, "gpt-4")
XCTAssertEqual(response.data[1].instructions, "You are a helpful assistant designed to make me better at coding!")

XCTAssertEqual(response.data[2].id, "asst_abc789")
XCTAssertEqual(response.data[2].objectType, "assistant")
XCTAssertEqual(response.data[2].createdAt, 1698982643)
XCTAssertNil(response.data[2].name)
XCTAssertEqual(response.data[2].model, "gpt-4")
XCTAssertNil(response.data[2].instructions)
} catch {
XCTFail("Error: \(error)")
}
}

func testCreateAssistant() async {
do {
// Simulate server response
let mockData = AssistantsAPITests.create.data(using: .utf8)!

MockURLProtocol.requestHandler = { request in
let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)!
return (response, mockData)
}

let createRequest = ASACreateAssistantRequest(model: "gpt-4",
name: "Math Tutor",
instructions: "You are a personal math tutor. When asked a question, write and run Python code to answer the question.")

let assistant: ASAAssistant = try await assistantsAPI.create(by: createRequest)

// Checks
XCTAssertEqual(assistant.id, "asst_abc123")
XCTAssertEqual(assistant.objectType, "assistant")
XCTAssertEqual(assistant.createdAt, 1698984975)
XCTAssertEqual(assistant.name, "Math Tutor")
XCTAssertEqual(assistant.model, "gpt-4")
XCTAssertEqual(assistant.instructions, "You are a personal math tutor. When asked a question, write and run Python code to answer the question.")
XCTAssertEqual(assistant.tools.count, 1)
XCTAssertEqual(assistant.tools.first?.type, "code_interpreter")
XCTAssertTrue(assistant.fileIds.isEmpty)
XCTAssertTrue(assistant.metadata?.isEmpty ?? true)
} catch {
XCTFail("Error: \(error)")
}
}

func testRetrieveAssistant() async {
do {
// Simulate server response
let mockData = AssistantsAPITests.retrieve.data(using: .utf8)!

MockURLProtocol.requestHandler = { request in
let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)!
return (response, mockData)
}

let assistantId = "asst_abc123"
let assistant: ASAAssistant = try await assistantsAPI.retrieve(by: assistantId)

// Checks
XCTAssertEqual(assistant.id, assistantId)
XCTAssertEqual(assistant.objectType, "assistant")
XCTAssertEqual(assistant.createdAt, 1699009709)
XCTAssertEqual(assistant.name, "HR Helper")
XCTAssertEqual(assistant.model, "gpt-4")
XCTAssertEqual(assistant.instructions, "You are an HR bot, and you have access to files to answer employee questions about company policies.")
XCTAssertEqual(assistant.tools.count, 1)
XCTAssertEqual(assistant.tools.first?.type, "retrieval")
XCTAssertEqual(assistant.fileIds, ["file-abc123"])
XCTAssertTrue(assistant.metadata?.isEmpty ?? true)
} catch {
XCTFail("Error: \(error)")
}
}

func testModifyAssistant() async {
do {
// Simulate server response
let mockData = AssistantsAPITests.modify.data(using: .utf8)!

MockURLProtocol.requestHandler = { request in
let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)!
return (response, mockData)
}

let assistantId = "asst_abc123"
let modifyRequest = ASAModifyAssistantRequest(
instructions: "You are an HR bot, and you have access to files to answer employee questions about company policies. Always response with info from either of the files.",
fileIds: ["file-abc123", "file-abc456"]
)

let modifiedAssistant: ASAAssistant = try await assistantsAPI.modify(by: assistantId,
modifyAssistant: modifyRequest)

// Checks
XCTAssertEqual(modifiedAssistant.id, assistantId)
XCTAssertEqual(modifiedAssistant.objectType, "assistant")
XCTAssertEqual(modifiedAssistant.createdAt, 1699009709)
XCTAssertEqual(modifiedAssistant.name, "HR Helper")
XCTAssertEqual(modifiedAssistant.model, "gpt-4")
XCTAssertEqual(modifiedAssistant.instructions, modifyRequest.instructions)
XCTAssertEqual(modifiedAssistant.tools.count, 1)
XCTAssertEqual(modifiedAssistant.tools.first?.type, "retrieval")
XCTAssertEqual(modifiedAssistant.fileIds, modifyRequest.fileIds)
XCTAssertTrue(modifiedAssistant.metadata?.isEmpty ?? true)
} catch {
XCTFail("Error: \(error)")
}
}

func testDeleteAssistant() async {
do {
// Simulate server response
let mockData = AssistantsAPITests.delete.data(using: .utf8)!

MockURLProtocol.requestHandler = { request in
let response = HTTPURLResponse(url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)!
return (response, mockData)
}

let assistantId = "asst_abc123"
let deleteResponse: ASADeleteModelResponse = try await assistantsAPI.delete(by: assistantId)

// Checks
XCTAssertEqual(deleteResponse.id, assistantId)
XCTAssertEqual(deleteResponse.object, "assistant.deleted")
XCTAssertTrue(deleteResponse.deleted)
} catch {
XCTFail("Error: \(error)")
}
}


}
Loading