mirror of https://github.com/xtekky/gpt4free
Add unitests for the client
Fix: async generator ignored GeneratorExit Fix: ResourceWarning: unclosed event looppull/1587/head
parent
151f8b8b0e
commit
e1a0b3ffa2
@ -0,0 +1,54 @@
|
||||
import unittest
|
||||
|
||||
from g4f.client import Client, ChatCompletion, ChatCompletionChunk
|
||||
from .mocks import AsyncGeneratorProviderMock, ModelProviderMock, YieldProviderMock
|
||||
|
||||
DEFAULT_MESSAGES = [{'role': 'user', 'content': 'Hello'}]
|
||||
|
||||
class TestPassModel(unittest.TestCase):
|
||||
|
||||
def test_response(self):
|
||||
client = Client(provider=AsyncGeneratorProviderMock)
|
||||
response = client.chat.completions.create(DEFAULT_MESSAGES, "")
|
||||
self.assertIsInstance(response, ChatCompletion)
|
||||
self.assertEqual("Mock", response.choices[0].message.content)
|
||||
|
||||
def test_pass_model(self):
|
||||
client = Client(provider=ModelProviderMock)
|
||||
response = client.chat.completions.create(DEFAULT_MESSAGES, "Hello")
|
||||
self.assertIsInstance(response, ChatCompletion)
|
||||
self.assertEqual("Hello", response.choices[0].message.content)
|
||||
|
||||
def test_max_tokens(self):
|
||||
client = Client(provider=YieldProviderMock)
|
||||
messages = [{'role': 'user', 'content': chunk} for chunk in ["How ", "are ", "you", "?"]]
|
||||
response = client.chat.completions.create(messages, "Hello", max_tokens=1)
|
||||
self.assertIsInstance(response, ChatCompletion)
|
||||
self.assertEqual("How ", response.choices[0].message.content)
|
||||
response = client.chat.completions.create(messages, "Hello", max_tokens=2)
|
||||
self.assertIsInstance(response, ChatCompletion)
|
||||
self.assertEqual("How are ", response.choices[0].message.content)
|
||||
|
||||
def test_max_stream(self):
|
||||
client = Client(provider=YieldProviderMock)
|
||||
messages = [{'role': 'user', 'content': chunk} for chunk in ["How ", "are ", "you", "?"]]
|
||||
response = client.chat.completions.create(messages, "Hello", stream=True)
|
||||
for chunk in response:
|
||||
self.assertIsInstance(chunk, ChatCompletionChunk)
|
||||
self.assertIsInstance(chunk.choices[0].delta.content, str)
|
||||
messages = [{'role': 'user', 'content': chunk} for chunk in ["You ", "You ", "Other", "?"]]
|
||||
response = client.chat.completions.create(messages, "Hello", stream=True, max_tokens=2)
|
||||
response = list(response)
|
||||
self.assertEqual(len(response), 2)
|
||||
for chunk in response:
|
||||
self.assertEqual(chunk.choices[0].delta.content, "You ")
|
||||
|
||||
def no_test_stop(self):
|
||||
client = Client(provider=YieldProviderMock)
|
||||
messages = [{'role': 'user', 'content': chunk} for chunk in ["How ", "are ", "you", "?"]]
|
||||
response = client.chat.completions.create(messages, "Hello", stop=["and"])
|
||||
self.assertIsInstance(response, ChatCompletion)
|
||||
self.assertEqual("How are you?", response.choices[0].message.content)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -0,0 +1,44 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
class Model():
|
||||
def __getitem__(self, item):
|
||||
return getattr(self, item)
|
||||
|
||||
class ChatCompletion(Model):
|
||||
def __init__(self, content: str, finish_reason: str):
|
||||
self.choices = [ChatCompletionChoice(ChatCompletionMessage(content, finish_reason))]
|
||||
|
||||
class ChatCompletionChunk(Model):
|
||||
def __init__(self, content: str, finish_reason: str):
|
||||
self.choices = [ChatCompletionDeltaChoice(ChatCompletionDelta(content, finish_reason))]
|
||||
|
||||
class ChatCompletionMessage(Model):
|
||||
def __init__(self, content: str, finish_reason: str):
|
||||
self.content = content
|
||||
self.finish_reason = finish_reason
|
||||
|
||||
class ChatCompletionChoice(Model):
|
||||
def __init__(self, message: ChatCompletionMessage):
|
||||
self.message = message
|
||||
|
||||
class ChatCompletionDelta(Model):
|
||||
def __init__(self, content: str, finish_reason: str):
|
||||
self.content = content
|
||||
self.finish_reason = finish_reason
|
||||
|
||||
class ChatCompletionDeltaChoice(Model):
|
||||
def __init__(self, delta: ChatCompletionDelta):
|
||||
self.delta = delta
|
||||
|
||||
class Image(Model):
|
||||
url: str
|
||||
|
||||
def __init__(self, url: str) -> None:
|
||||
self.url = url
|
||||
|
||||
class ImagesResponse(Model):
|
||||
data: list[Image]
|
||||
|
||||
def __init__(self, data: list) -> None:
|
||||
self.data = data
|
@ -0,0 +1,3 @@
|
||||
<style type="text/css">#designer_attribute_container{display:flex;justify-content:space-between;width:100%;margin-top:10px}#designer_attribute_container .des_attr_i{width:16px;margin-right:2px}#designer_attribute_container .des_attr_txt{height:18px;line-height:18px;font-size:14px;font-weight:400;font-family:"Roboto",Helvetica,sans-serif}#designer_attribute_container #dalle_attribute_container{margin-left:auto}#designer_attribute_container #dalle_attribute_container .des_attr_dal{display:flex;justify-content:center;height:14px;border-radius:4px;background-color:#5f5f5e;padding:2px 8px}#designer_attribute_container #dalle_attribute_container .des_attr_dal_txt{height:14px;line-height:14px;font-size:11px;font-weight:400;font-family:"Roboto",Helvetica,sans-serif;color:#fff}.des_attr_txt{color:#fff}</style><div id="gir_async"
|
||||
class="giric gir_1" data-rewriteurl="/images/create/a-serene-garden-filled-with-colorful-flowers-in-fu/1-65c8a550c2d34e67a93b016cd1f3ade3?FORM=GENCRE" data-cis="512" data-vimgseturl="/images/create/async/viewimageset/1-65c8a550c2d34e67a93b016cd1f3ade3&IG=062C548EC8DD4047A2AAE63FD928194A&IID=images.vis"
|
||||
fir-th="OIG2.EPxx_.JFG402kzMQYYhj" data-ctc="Image copied to clipboard" data-wide="" data-wide-mobile=""><a class="single-img-link" target="_blank" href="/images/create/a-serene-garden-filled-with-colorful-flowers-in-fu/1-65c8a550c2d34e67a93b016cd1f3ade3?id=LrsKPoRLQud1%2bT8YdxQDhA%3d%3d&view=detailv2&idpp=genimg&FORM=GCRIDP" h="ID=images,5015.1"><img class="gir_mmimg" src="https://tse4.mm.bing.net/th/id/OIG2.EPxx_.JFG402kzMQYYhj?w=270&h=270&c=6&r=0&o=5&pid=ImgGn" alt="a serene garden filled with colorful flowers in full bloom"/></a><div id="designer_attribute_container"><img class="des_attr_i rms_img" alt="Designer" src="https://r.bing.com/rp/gmZtdJVd-klWl3XWpa6-ni1FU3M.svg" /><span class="des_attr_txt des_attr_txt_clr">Designer</span><div id="dalle_attribute_container"><div class="des_attr_dal"><span class="des_attr_dal_txt">Powered by DALL·E 3</span></div></div></div></div>
|
Loading…
Reference in New Issue