mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-05-02 20:32:38 +02:00
fix conflict
This commit is contained in:
commit
93d4c8c318
34 changed files with 2310 additions and 260 deletions
2
tests/data/embedding/2.answer.md
Normal file
2
tests/data/embedding/2.answer.md
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
检索结果
|
||||
法务查询者可根据国际小超人钉钉小程序UI上的滚筒切换业务线 这张图片展示了一个移动应用的界面,界面标题为“法律意见详情”。用户可以根据具体情况切换业务线。界面中有多个字段,包括“国家名称”、“国家情况描述”、“业务线”、“产品法规分析”和“签约主体”。第一张截图显示了详细的法律情报信息,包含区域名称、区域情况描述、业务线和产品法规概述等字段。第二张截图显示了“法律意见详情”界面,其中列出了国家名称、国家情况描述、业务线、产品法规分析和签约主体。第三张截图与第二张相似,但显示了选项的可选择状态。最下方有“取消”和“确定”的按钮。 法务查询者从国家详情中的业务线名列表中选出要查看的业务线。
|
||||
25
tests/data/embedding/2.knowledge.md
Normal file
25
tests/data/embedding/2.knowledge.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
## Textual User Requirements
|
||||
|
||||
### 3.2. 首页
|
||||
|
||||
首页有两个分区,上面部分是法律意见检索栏。
|
||||
|
||||
法务查询者第一次进入国际小超人钉钉小程序展示引导页,以后进入不再展示,点击「我知道了」引导页消失。
|
||||
|
||||
#### 首页
|
||||

|
||||
这是一个名为“法务小超人”的移动应用程序的界面截图。界面顶部显示了应用名称和一个可切换语言的按钮“English”。在界面中间部分,有一个标题“法律意见查询”,以及一个搜索框,提示输入国家名称以查询法律意见。下方显示已收录法律意见8394篇。界面下半部分是“法务 Q&A”部分,列出了一些法律相关的选项,例如“国际法务接入口人”、“国内法务接入口人”、“国际法律协议合同办理指引”和“国内法律协议合同办理指引”。界面底部有三个导航按钮,分别是“首页”、“模板”和“我的”。
|
||||
|
||||
#### 按国家名维度搜索
|
||||
法务查询者在国际小超人钉钉小程序的搜索框中进行检索时采用typeahead,只能下拉选择法务中台中有的国家名称。
|
||||

|
||||
在这张图像中,用户正在一个名为“法律意见查询”的应用中进行国家名称的搜索。用户在搜索框中输入国家名称时,系统会提供下拉建议。这些建议基于 typeahead 功能,从法务中台中筛选出匹配的国家名称供用户选择。目前,搜索结果包含了“中国”和“菲律宾”两个具体的国家名称,其它显示为“国家名”。用户可以通过下拉菜单快速选择所需的国家名称。
|
||||
|
||||
#### 检索结果
|
||||
法务查询者可根据国际小超人钉钉小程序UI上的滚筒切换业务线
|
||||

|
||||
这张图片展示了一个移动应用的界面,界面标题为“法律意见详情”。用户可以根据具体情况切换业务线。界面中有多个字段,包括“国家名称”、“国家情况描述”、“业务线”、“产品法规分析”和“签约主体”。第一张截图显示了详细的法律情报信息,包含区域名称、区域情况描述、业务线和产品法规概述等字段。第二张截图显示了“法律意见详情”界面,其中列出了国家名称、国家情况描述、业务线、产品法规分析和签约主体。第三张截图与第二张相似,但显示了选项的可选择状态。最下方有“取消”和“确定”的按钮。
|
||||
法务查询者从国家详情中的业务线名列表中选出要查看的业务线。
|
||||
|
||||
#### 查看法律意见详情
|
||||
国际小超人钉钉小程序用国家代码和业务代码做参数,查询法律意见详情,然后将法律意见详情展示给法务查询者。
|
||||
1
tests/data/embedding/2.query.md
Normal file
1
tests/data/embedding/2.query.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
业务线UI有哪些操作?
|
||||
7
tests/data/embedding/3.answer.md
Normal file
7
tests/data/embedding/3.answer.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
国家/区域导游详情 & 法律意见详情 查询
|
||||
Description:根据国家code查询国家/区域导游信息详情
|
||||
ID: 8
|
||||
HTTP METHOD: GET
|
||||
Endpoint: /contract/country/navigate.json
|
||||
Input Parameters: |名称|描述|类型(长度)|必选|备注| | :- | :- | :-: | :- | :- | |countryCode|国家code|string|√||
|
||||
Returns: |名称|描述|类型(长度)|必选|备注| | :- | :- | :-: | :- | :- | |success|业务处理成功true,否则false|boolean|√|只判断这个属性即可| |message|错误信息,可以用来提示|string|√|| |code|返回状态码|string|√|| |data|国家/区域导游详情|object|√|| |-> country||||| |-> -> id|id|integer|√|| |-> -> country|国家code|string|√|| |-> -> countryName|国家中文名称|string|√|| |-> -> countryNameEn|国家英文名称|string|√|| |-> -> content|国家导游中文详情json数组,具体格式见下示例|list of object|√|| |-> -> -> title|标题|object|√|| |-> -> -> -> title|中文标题|string||| |-> -> -> -> titleEn|英文标题|string||| |-> -> -> contentList|标题下面的文字描述列表|list of object|√|| |-> -> -> -> detail|内容中文详情|string|√|| |-> -> -> -> detailEn|内容英文详情|string|√|| |-> -> -> -> url|超链接|string||| |-> legal|法务信息|object||| |-> -> country|国家code|string|√|| |-> -> businessList|业务线列表|list of object||| |-> -> -> id|id|integer||新增时不传,修改时传递| |-> -> -> business|业务线code|string|√|| |-> -> -> businessName|业务线中文名称|string|√|| |-> -> -> businessNameEn|业务线英文名称|string|√|| |-> -> -> content|业务线json,具体如下|object|√|| |-> -> -> -> detailEn|具体的详情英文内容|string|√|| |-> -> -> -> detail|具体的详情内容|string|√||
|
||||
189
tests/data/embedding/3.knowledge.md
Normal file
189
tests/data/embedding/3.knowledge.md
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
## Interfaces
|
||||
- 用户登录
|
||||
- Description: 用户从小程序/微应用发起请求,需要验证用户的合法身份才能正常处理。
|
||||
- ID: 1
|
||||
- HTTP METHOD: GET
|
||||
- Endpoint: `/sup/login.json`
|
||||
- Input Parameters:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|authCode|用户临时免登授权码|String(64)|√||
|
||||
|loginTypeEnum|登录类型|String(20)|√||
|
||||
|authCorpId|用户所在企业/组织id|String(64)||微应用免登时传递|
|
||||
|app|应用标识|String(3)|√||
|
||||
- Returns:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|success|业务处理成功与否,成功true,否则false|boolean|√|只判断这个属性即可|
|
||||
|message|错误信息,可以用来提示|string|√||
|
||||
|code|返回状态码|string|√||
|
||||
|data|用户的sessionId|string|√||
|
||||
- 根据sessionId查询用户详细信息
|
||||
- Description: 查询当前用户的详细信息,如 staffId,unionId,name,avatar等信息
|
||||
- ID: 2
|
||||
- HTTP METHOD: GET
|
||||
- Endpoint: `/sup/user.json`
|
||||
- Input Parameters:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|NDA_SESSION|用户sessionId|String(64)|√||
|
||||
- Returns:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|success|业务处理成功与否,成功true,否则false|boolean|√|只判断这个属性即可|
|
||||
|message|错误信息,可以用来提示|string|√||
|
||||
|code|返回状态码|string|√||
|
||||
|data|用户的详细信息|object|√||
|
||||
|-> corpId|当前用户企业 钉钉ID(小程序端会拿不到该信息)|string|√||
|
||||
|-> corpName|当前用户企业名称(小程序端会拿不到该信息)|string|√||
|
||||
|-> staffId|员工在当前企业内的唯一标识,也称staffId(小程序端会拿不到该信息)|string|√||
|
||||
|-> unionId|员工在当前开发者企业账号范围内的唯一标识,系统生成,固定值,不会改变。|string|√||
|
||||
|-> name|当前用户的名称(小程序端会拿不到该信息)|string|√||
|
||||
|-> avatar|头像图片URL|string|√||
|
||||
- 查询国家情况描述
|
||||
- Description: 根据国家code查询国家情况描述
|
||||
- ID: 3
|
||||
- HTTP METHOD: GET
|
||||
- Endpoint: `/sup/country/detail.json`
|
||||
- Input Parameters:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|countryCode|国家code|string|√||
|
||||
- Returns:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|success|业务处理成功true,否则false|boolean|√|只判断这个属性即可|
|
||||
|message|错误信息,可以用来提示|string|√||
|
||||
|code|返回状态码|string|√||
|
||||
|data|国家情况描述|object|√||
|
||||
|-> id|id|integer|√||
|
||||
|-> countryName|国家名称|string|√||
|
||||
|-> countryCode|国家code|string|√||
|
||||
|-> detail|产品法规分析|string|√||
|
||||
- 查询产品法规分析(法律意见详情)
|
||||
- Description: 根据国家和业务线查询产品法规分析
|
||||
- ID: 4
|
||||
- HTTP METHOD: GET
|
||||
- Endpoint: `/sup/legal/detail.json`
|
||||
- Input Parameters:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|countryCode|国家code|string|√||
|
||||
|businessCode|业务线code|string|√||
|
||||
- Returns:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|success|业务处理成功true,否则false|boolean|√|只判断这个属性即可|
|
||||
|message|错误信息,可以用来提示|string|√||
|
||||
|code|返回状态码|string|√||
|
||||
|data|法律意见详情|object|√||
|
||||
|-> id|id|integer|√||
|
||||
|-> countryName|国家名称|string|√||
|
||||
|-> countryCode|国家code|string|√||
|
||||
|-> businessLine|业务线|string|√||
|
||||
|-> businessCode|业务线code|string|√||
|
||||
|-> detail|产品法规分析|string|√||
|
||||
|-> signEntity|签约主体|string|√||
|
||||
- 查询法律意见总数
|
||||
- Description: 法律意见总数查询
|
||||
- ID: 5
|
||||
- HTTP METHOD: GET
|
||||
- Endpoint: `/sup/legal/count.json`
|
||||
- Input Parameters:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
- Returns:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|success|业务处理成功true,否则false|boolean|√|只判断这个属性即可|
|
||||
|message|错误信息,可以用来提示|string|√||
|
||||
|code|返回状态码|string|√||
|
||||
|data|总数|integer|√||
|
||||
- 查询所有国家和业务线信息列表
|
||||
- Description: 查询所有国家和业务线信息列表
|
||||
- ID: 6
|
||||
- HTTP METHOD: GET
|
||||
- Endpoint: `/sup/legal/country/list.json`
|
||||
- Input Parameters:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
- Returns:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|success|业务处理成功true,否则false|boolean|√|只判断这个属性即可|
|
||||
|message|错误信息,可以用来提示|string|√||
|
||||
|code|返回状态码|string|√||
|
||||
|data|所有数据列表|list of object|√||
|
||||
|-> country|国家code|string|√||
|
||||
|-> business|业务线code|string|√||
|
||||
|-> dataType|数据类型|string|√||
|
||||
|-> businessName|业务线名|string|√||
|
||||
|-> countryName|国家名|string|√||
|
||||
|-> businessNameEn|业务线名(英文)|string|√||
|
||||
- 调用法务中台antlaw接口
|
||||
- ID: 7
|
||||
- 国家/区域导游详情 & 法律意见详情 查询
|
||||
- Description:根据国家code查询国家/区域导游信息详情
|
||||
- ID: 8
|
||||
- HTTP METHOD: GET
|
||||
- Endpoint: `/contract/country/navigate.json`
|
||||
- Input Parameters:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|countryCode|国家code|string|√||
|
||||
- Returns:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|success|业务处理成功true,否则false|boolean|√|只判断这个属性即可|
|
||||
|message|错误信息,可以用来提示|string|√||
|
||||
|code|返回状态码|string|√||
|
||||
|data|国家/区域导游详情|object|√||
|
||||
|-> country|||||
|
||||
|-> -> id|id|integer|√||
|
||||
|-> -> country|国家code|string|√||
|
||||
|-> -> countryName|国家中文名称|string|√||
|
||||
|-> -> countryNameEn|国家英文名称|string|√||
|
||||
|-> -> content|国家导游中文详情json数组,具体格式见下示例|list of object|√||
|
||||
|-> -> -> title|标题|object|√||
|
||||
|-> -> -> -> title|中文标题|string|||
|
||||
|-> -> -> -> titleEn|英文标题|string|||
|
||||
|-> -> -> contentList|标题下面的文字描述列表|list of object|√||
|
||||
|-> -> -> -> detail|内容中文详情|string|√||
|
||||
|-> -> -> -> detailEn|内容英文详情|string|√||
|
||||
|-> -> -> -> url|超链接|string|||
|
||||
|-> legal|法务信息|object|||
|
||||
|-> -> country|国家code|string|√||
|
||||
|-> -> businessList|业务线列表|list of object|||
|
||||
|-> -> -> id|id|integer||新增时不传,修改时传递|
|
||||
|-> -> -> business|业务线code|string|√||
|
||||
|-> -> -> businessName|业务线中文名称|string|√||
|
||||
|-> -> -> businessNameEn|业务线英文名称|string|√||
|
||||
|-> -> -> content|业务线json,具体如下|object|√||
|
||||
|-> -> -> -> detailEn|具体的详情英文内容|string|√||
|
||||
|-> -> -> -> detail|具体的详情内容|string|√||
|
||||
- 国家/区域导游列表分页查询
|
||||
- Description: 分页查询国家/区域列表
|
||||
- ID: 9
|
||||
- HTTP METHOD: GET
|
||||
- Endpoint: `/contract/country/list.json`
|
||||
- Input Parameters:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|pageSize|分页大小|integer|√|>=1|
|
||||
|pageNum|分页大小|integer|√|>=1|
|
||||
|country|国家code|string|||
|
||||
|business|业务线code|string|||
|
||||
- Returns:
|
||||
|名称|描述|类型(长度)|必选|备注|
|
||||
| :- | :- | :-: | :- | :- |
|
||||
|success|业务处理成功true,否则false|boolean|√|只判断这个属性即可|
|
||||
|message|错误信息,可以用来提示|string|√||
|
||||
|code|返回状态码|string|√||
|
||||
|data|国家/区域导游详情|list of object|√||
|
||||
|-> id|id|integer|√||
|
||||
|-> country|国家code|string|√||
|
||||
|-> countryName|国家中文名称|string|√||
|
||||
|-> countryNameEn|国家英文名称|string|√||
|
||||
|-> gmtCreate|创建时间|string|√||
|
||||
|-> gmtModified|更新时间|string|√||
|
||||
|total|数据总量|integer|√||
|
||||
1
tests/data/embedding/3.query.md
Normal file
1
tests/data/embedding/3.query.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
根据国家code查询国家业务线列表
|
||||
0
tests/metagpt/rag/__init__.py
Normal file
0
tests/metagpt/rag/__init__.py
Normal file
55
tests/metagpt/rag/test_large_pdf.py
Normal file
55
tests/metagpt/rag/test_large_pdf.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.config2 import Config
|
||||
from metagpt.const import TEST_DATA_PATH
|
||||
from metagpt.rag.engines import SimpleEngine
|
||||
from metagpt.rag.factories.embedding import RAGEmbeddingFactory
|
||||
from metagpt.utils.common import aread
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
@pytest.mark.parametrize(
|
||||
("knowledge_filename", "query_filename", "answer_filename"),
|
||||
[
|
||||
(
|
||||
TEST_DATA_PATH / "embedding/2.knowledge.md",
|
||||
TEST_DATA_PATH / "embedding/2.query.md",
|
||||
TEST_DATA_PATH / "embedding/2.answer.md",
|
||||
),
|
||||
(
|
||||
TEST_DATA_PATH / "embedding/3.knowledge.md",
|
||||
TEST_DATA_PATH / "embedding/3.query.md",
|
||||
TEST_DATA_PATH / "embedding/3.answer.md",
|
||||
),
|
||||
],
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
async def test_large_pdf(knowledge_filename, query_filename, answer_filename):
|
||||
Config.default(reload=True) # `config.embedding.model = "text-embedding-ada-002"` changes the cache.
|
||||
|
||||
engine = SimpleEngine.from_docs(
|
||||
input_files=[knowledge_filename],
|
||||
)
|
||||
|
||||
query = await aread(filename=query_filename)
|
||||
rsp = await engine.aretrieve(query)
|
||||
assert rsp
|
||||
|
||||
config = Config.default()
|
||||
config.embedding.model = "text-embedding-ada-002"
|
||||
factory = RAGEmbeddingFactory(config)
|
||||
embedding = factory.get_rag_embedding()
|
||||
answer = await aread(filename=answer_filename)
|
||||
answer_embedding = await embedding.aget_text_embedding(answer)
|
||||
similarity = 0
|
||||
for i in rsp:
|
||||
rsp_embedding = await embedding.aget_query_embedding(i.text)
|
||||
v = embedding.similarity(answer_embedding, rsp_embedding)
|
||||
similarity = max(similarity, v)
|
||||
|
||||
print(similarity)
|
||||
assert similarity > 0.9
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-s"])
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.const import TEST_DATA_PATH
|
||||
from metagpt.tools.libs.editor import Editor, FileBlock
|
||||
from metagpt.tools.libs.editor import Editor
|
||||
|
||||
TEST_FILE_CONTENT = """
|
||||
# this is line one
|
||||
|
|
@ -13,31 +13,24 @@ def test_function_for_fm():
|
|||
# this is the 7th line
|
||||
""".strip()
|
||||
|
||||
TEST_FILE_PATH = TEST_DATA_PATH / "tools/test_script_for_editor.py"
|
||||
WINDOW = 100
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_file():
|
||||
with open(TEST_FILE_PATH, "w") as f:
|
||||
f.write(TEST_FILE_CONTENT)
|
||||
yield
|
||||
with open(TEST_FILE_PATH, "w") as f:
|
||||
f.write("")
|
||||
def temp_file_path(tmp_path):
|
||||
assert tmp_path is not None
|
||||
temp_file_path = tmp_path / "a.txt"
|
||||
yield temp_file_path
|
||||
temp_file_path.unlink()
|
||||
|
||||
|
||||
EXPECTED_SEARCHED_BLOCK = FileBlock(
|
||||
file_path=str(TEST_FILE_PATH),
|
||||
block_content='001|# this is line one\n002|def test_function_for_fm():\n003| "some docstring"\n004| a = 1\n005| b = 2\n',
|
||||
block_start_line=1,
|
||||
block_end_line=5,
|
||||
symbol="def test_function_for_fm",
|
||||
symbol_line=2,
|
||||
)
|
||||
|
||||
|
||||
def test_search_content(test_file):
|
||||
block = Editor().search_content("def test_function_for_fm", root_path=TEST_DATA_PATH, window=3)
|
||||
assert block == EXPECTED_SEARCHED_BLOCK
|
||||
@pytest.fixture
|
||||
def temp_py_file(tmp_path):
|
||||
assert tmp_path is not None
|
||||
temp_file_path = tmp_path / "test_script_for_editor.py"
|
||||
temp_file_path.write_text(TEST_FILE_CONTENT)
|
||||
yield temp_file_path
|
||||
temp_file_path.unlink()
|
||||
|
||||
|
||||
EXPECTED_CONTENT_AFTER_REPLACE = """
|
||||
|
|
@ -50,32 +43,43 @@ def test_function_for_fm():
|
|||
""".strip()
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_replace_content(test_file):
|
||||
Editor().write_content(
|
||||
file_path=str(TEST_FILE_PATH),
|
||||
start_line=3,
|
||||
end_line=5,
|
||||
new_block_content=" # This is the new line A replacing lines 3 to 5.\n # This is the new line B.",
|
||||
def test_replace_content(temp_py_file):
|
||||
editor = Editor()
|
||||
editor._edit_file_impl(
|
||||
file_name=temp_py_file,
|
||||
start=3,
|
||||
end=5,
|
||||
content=" # This is the new line A replacing lines 3 to 5.\n # This is the new line B.",
|
||||
is_insert=False,
|
||||
is_append=False,
|
||||
)
|
||||
with open(TEST_FILE_PATH, "r") as f:
|
||||
with open(temp_py_file, "r") as f:
|
||||
new_content = f.read()
|
||||
assert new_content == EXPECTED_CONTENT_AFTER_REPLACE
|
||||
assert new_content.strip() == EXPECTED_CONTENT_AFTER_REPLACE.strip()
|
||||
|
||||
|
||||
EXPECTED_CONTENT_AFTER_DELETE = """
|
||||
# this is line one
|
||||
def test_function_for_fm():
|
||||
|
||||
c = 3
|
||||
# this is the 7th line
|
||||
""".strip()
|
||||
|
||||
|
||||
def test_delete_content(test_file):
|
||||
Editor().write_content(file_path=str(TEST_FILE_PATH), start_line=3, end_line=5)
|
||||
with open(TEST_FILE_PATH, "r") as f:
|
||||
def test_delete_content(temp_py_file):
|
||||
editor = Editor()
|
||||
editor._edit_file_impl(
|
||||
file_name=temp_py_file,
|
||||
start=3,
|
||||
end=5,
|
||||
content="",
|
||||
is_insert=False,
|
||||
is_append=False,
|
||||
)
|
||||
with open(temp_py_file, "r") as f:
|
||||
new_content = f.read()
|
||||
assert new_content == EXPECTED_CONTENT_AFTER_DELETE
|
||||
assert new_content.strip() == EXPECTED_CONTENT_AFTER_DELETE.strip()
|
||||
|
||||
|
||||
EXPECTED_CONTENT_AFTER_INSERT = """
|
||||
|
|
@ -90,39 +94,16 @@ def test_function_for_fm():
|
|||
""".strip()
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_insert_content(test_file):
|
||||
Editor().write_content(
|
||||
file_path=str(TEST_FILE_PATH),
|
||||
start_line=3,
|
||||
end_line=-1,
|
||||
new_block_content=" # This is the new line to be inserted, at line 3",
|
||||
def test_insert_content(temp_py_file):
|
||||
editor = Editor(enable_auto_lint=True)
|
||||
editor.insert_content_at_line(
|
||||
file_name=temp_py_file,
|
||||
line_number=3,
|
||||
content=" # This is the new line to be inserted, at line 3",
|
||||
)
|
||||
with open(TEST_FILE_PATH, "r") as f:
|
||||
with open(temp_py_file, "r") as f:
|
||||
new_content = f.read()
|
||||
assert new_content == EXPECTED_CONTENT_AFTER_INSERT
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_new_content_wrong_indentation(test_file):
|
||||
msg = Editor().write_content(
|
||||
file_path=str(TEST_FILE_PATH),
|
||||
start_line=3,
|
||||
end_line=-1,
|
||||
new_block_content=" This is the new line to be inserted, at line 3", # omit # should throw a syntax error
|
||||
)
|
||||
assert "failed" in msg
|
||||
|
||||
|
||||
@pytest.mark.skip
|
||||
def test_new_content_format_issue(test_file):
|
||||
msg = Editor().write_content(
|
||||
file_path=str(TEST_FILE_PATH),
|
||||
start_line=3,
|
||||
end_line=-1,
|
||||
new_block_content=" # This is the new line to be inserted, at line 3 ", # trailing spaces are format issue only, and should not throw an error
|
||||
)
|
||||
assert "failed" not in msg
|
||||
assert new_content.strip() == EXPECTED_CONTENT_AFTER_INSERT.strip()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
@ -151,5 +132,518 @@ async def test_read_files(filename):
|
|||
assert file_block.block_content
|
||||
|
||||
|
||||
def _numbered_test_lines(start, end) -> str:
|
||||
return ("\n".join(f"{i}|" for i in range(start, end + 1))) + "\n"
|
||||
|
||||
|
||||
def _generate_test_file_with_lines(temp_path, num_lines) -> str:
|
||||
file_path = temp_path / "test_file.py"
|
||||
file_path.write_text("\n" * num_lines)
|
||||
return file_path
|
||||
|
||||
|
||||
def _generate_ruby_test_file_with_lines(temp_path, num_lines) -> str:
|
||||
file_path = temp_path / "test_file.rb"
|
||||
file_path.write_text("\n" * num_lines)
|
||||
return file_path
|
||||
|
||||
|
||||
def _calculate_window_bounds(current_line, total_lines, window_size):
|
||||
half_window = window_size // 2
|
||||
if current_line - half_window < 0:
|
||||
start = 1
|
||||
end = window_size
|
||||
else:
|
||||
start = current_line - half_window
|
||||
end = current_line + half_window
|
||||
return start, end
|
||||
|
||||
|
||||
def test_open_file_unexist_path():
|
||||
editor = Editor()
|
||||
with pytest.raises(FileNotFoundError):
|
||||
editor.open_file("/unexist/path/a.txt")
|
||||
|
||||
|
||||
def test_open_file(temp_file_path):
|
||||
editor = Editor()
|
||||
temp_file_path.write_text("Line 1\nLine 2\nLine 3\nLine 4\nLine 5")
|
||||
|
||||
result = editor.open_file(str(temp_file_path))
|
||||
|
||||
assert result is not None
|
||||
expected = (
|
||||
f"[File: {temp_file_path} (5 lines total)]\n"
|
||||
"(this is the beginning of the file)\n"
|
||||
"1|Line 1\n"
|
||||
"2|Line 2\n"
|
||||
"3|Line 3\n"
|
||||
"4|Line 4\n"
|
||||
"5|Line 5\n"
|
||||
"(this is the end of the file)"
|
||||
)
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
def test_open_file_with_indentation(temp_file_path):
|
||||
editor = Editor()
|
||||
temp_file_path.write_text("Line 1\n Line 2\nLine 3\nLine 4\nLine 5")
|
||||
|
||||
result = editor.open_file(str(temp_file_path))
|
||||
assert result is not None
|
||||
expected = (
|
||||
f"[File: {temp_file_path} (5 lines total)]\n"
|
||||
"(this is the beginning of the file)\n"
|
||||
"1|Line 1\n"
|
||||
"2| Line 2\n"
|
||||
"3|Line 3\n"
|
||||
"4|Line 4\n"
|
||||
"5|Line 5\n"
|
||||
"(this is the end of the file)"
|
||||
)
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
def test_open_file_long(temp_file_path):
|
||||
editor = Editor()
|
||||
content = "\n".join([f"Line {i}" for i in range(1, 1001)])
|
||||
temp_file_path.write_text(content)
|
||||
|
||||
result = editor.open_file(str(temp_file_path), 1, 50)
|
||||
assert result is not None
|
||||
expected = f"[File: {temp_file_path} (1000 lines total)]\n"
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
for i in range(1, 51):
|
||||
expected += f"{i}|Line {i}\n"
|
||||
expected += "(950 more lines below)"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
def test_open_file_long_with_lineno(temp_file_path):
|
||||
editor = Editor()
|
||||
content = "\n".join([f"Line {i}" for i in range(1, 1001)])
|
||||
temp_file_path.write_text(content)
|
||||
|
||||
cur_line = 100
|
||||
|
||||
result = editor.open_file(str(temp_file_path), cur_line)
|
||||
assert result is not None
|
||||
expected = f"[File: {temp_file_path} (1000 lines total)]\n"
|
||||
start, end = _calculate_window_bounds(cur_line, 1000, WINDOW)
|
||||
if start == 1:
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
else:
|
||||
expected += f"({start - 1} more lines above)\n"
|
||||
for i in range(start, end + 1):
|
||||
expected += f"{i}|Line {i}\n"
|
||||
if end == 1000:
|
||||
expected += "(this is the end of the file)\n"
|
||||
else:
|
||||
expected += f"({1000 - end} more lines below)"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
def test_create_file_unexist_path():
|
||||
editor = Editor()
|
||||
with pytest.raises(FileNotFoundError):
|
||||
editor.create_file("/unexist/path/a.txt")
|
||||
|
||||
|
||||
def test_create_file(temp_file_path):
|
||||
editor = Editor()
|
||||
result = editor.create_file(str(temp_file_path))
|
||||
|
||||
expected = f"[File {temp_file_path} created.]"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
def test_goto_line(temp_file_path):
|
||||
editor = Editor()
|
||||
total_lines = 1000
|
||||
content = "\n".join([f"Line {i}" for i in range(1, total_lines + 1)])
|
||||
temp_file_path.write_text(content)
|
||||
|
||||
result = editor.open_file(str(temp_file_path))
|
||||
assert result is not None
|
||||
|
||||
expected = f"[File: {temp_file_path} ({total_lines} lines total)]\n"
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
for i in range(1, WINDOW + 1):
|
||||
expected += f"{i}|Line {i}\n"
|
||||
expected += f"({total_lines - WINDOW} more lines below)"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
result = editor.goto_line(500)
|
||||
|
||||
assert result is not None
|
||||
|
||||
cur_line = 500
|
||||
expected = f"[File: {temp_file_path} ({total_lines} lines total)]\n"
|
||||
start, end = _calculate_window_bounds(cur_line, total_lines, WINDOW)
|
||||
if start == 1:
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
else:
|
||||
expected += f"({start - 1} more lines above)\n"
|
||||
for i in range(start, end + 1):
|
||||
expected += f"{i}|Line {i}\n"
|
||||
if end == total_lines:
|
||||
expected += "(this is the end of the file)\n"
|
||||
else:
|
||||
expected += f"({total_lines - end} more lines below)"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
def test_goto_line_negative(temp_file_path):
|
||||
editor = Editor()
|
||||
content = "\n".join([f"Line {i}" for i in range(1, 5)])
|
||||
temp_file_path.write_text(content)
|
||||
|
||||
editor.open_file(str(temp_file_path))
|
||||
with pytest.raises(ValueError):
|
||||
editor.goto_line(-1)
|
||||
|
||||
|
||||
def test_goto_line_out_of_bound(temp_file_path):
|
||||
editor = Editor()
|
||||
content = "\n".join([f"Line {i}" for i in range(1, 5)])
|
||||
temp_file_path.write_text(content)
|
||||
|
||||
editor.open_file(str(temp_file_path))
|
||||
with pytest.raises(ValueError):
|
||||
editor.goto_line(100)
|
||||
|
||||
|
||||
def test_scroll_down(temp_file_path):
|
||||
editor = Editor()
|
||||
total_lines = 1000
|
||||
content = "\n".join([f"Line {i}" for i in range(1, total_lines + 1)])
|
||||
temp_file_path.write_text(content)
|
||||
result = editor.open_file(str(temp_file_path))
|
||||
assert result is not None
|
||||
|
||||
expected = f"[File: {temp_file_path} ({total_lines} lines total)]\n"
|
||||
start, end = _calculate_window_bounds(1, total_lines, WINDOW)
|
||||
if start == 1:
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
else:
|
||||
expected += f"({start - 1} more lines above)\n"
|
||||
for i in range(start, end + 1):
|
||||
expected += f"{i}|Line {i}\n"
|
||||
if end == total_lines:
|
||||
expected += "(this is the end of the file)"
|
||||
else:
|
||||
expected += f"({total_lines - end} more lines below)"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
result = editor.scroll_down()
|
||||
|
||||
assert result is not None
|
||||
|
||||
expected = f"[File: {temp_file_path} ({total_lines} lines total)]\n"
|
||||
start, end = _calculate_window_bounds(WINDOW + 1, total_lines, WINDOW)
|
||||
if start == 1:
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
else:
|
||||
expected += f"({start - 1} more lines above)\n"
|
||||
for i in range(start, end + 1):
|
||||
expected += f"{i}|Line {i}\n"
|
||||
if end == total_lines:
|
||||
expected += "(this is the end of the file)\n"
|
||||
else:
|
||||
expected += f"({total_lines - end} more lines below)"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
def test_scroll_up(temp_file_path):
|
||||
editor = Editor()
|
||||
total_lines = 1000
|
||||
content = "\n".join([f"Line {i}" for i in range(1, total_lines + 1)])
|
||||
temp_file_path.write_text(content)
|
||||
|
||||
cur_line = 300
|
||||
|
||||
result = editor.open_file(str(temp_file_path), cur_line)
|
||||
assert result is not None
|
||||
|
||||
expected = f"[File: {temp_file_path} ({total_lines} lines total)]\n"
|
||||
start, end = _calculate_window_bounds(cur_line, total_lines, WINDOW)
|
||||
if start == 1:
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
else:
|
||||
expected += f"({start - 1} more lines above)\n"
|
||||
for i in range(start, end + 1):
|
||||
expected += f"{i}|Line {i}\n"
|
||||
if end == total_lines:
|
||||
expected += "(this is the end of the file)\n"
|
||||
else:
|
||||
expected += f"({total_lines - end} more lines below)"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
result = editor.scroll_up()
|
||||
assert result is not None
|
||||
|
||||
cur_line = cur_line - WINDOW
|
||||
|
||||
expected = f"[File: {temp_file_path} ({total_lines} lines total)]\n"
|
||||
start, end = _calculate_window_bounds(cur_line, total_lines, WINDOW)
|
||||
if start == 1:
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
else:
|
||||
expected += f"({start - 1} more lines above)\n"
|
||||
for i in range(start, end + 1):
|
||||
expected += f"{i}|Line {i}\n"
|
||||
if end == total_lines:
|
||||
expected += "(this is the end of the file)\n"
|
||||
else:
|
||||
expected += f"({total_lines - end} more lines below)"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
def test_scroll_down_edge(temp_file_path):
|
||||
editor = Editor()
|
||||
content = "\n".join([f"Line {i}" for i in range(1, 10)])
|
||||
temp_file_path.write_text(content)
|
||||
|
||||
result = editor.open_file(str(temp_file_path))
|
||||
assert result is not None
|
||||
|
||||
expected = f"[File: {temp_file_path} (9 lines total)]\n"
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
for i in range(1, 10):
|
||||
expected += f"{i}|Line {i}\n"
|
||||
expected += "(this is the end of the file)"
|
||||
|
||||
result = editor.scroll_down()
|
||||
assert result is not None
|
||||
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
def test_print_window_internal(temp_file_path):
|
||||
editor = Editor()
|
||||
editor.create_file(str(temp_file_path))
|
||||
with open(temp_file_path, "w") as file:
|
||||
for i in range(1, 101):
|
||||
file.write(f"Line `{i}`\n")
|
||||
|
||||
current_line = 50
|
||||
window = 2
|
||||
|
||||
result = editor._print_window(temp_file_path, current_line, window)
|
||||
expected = "(48 more lines above)\n" "49|Line `49`\n" "50|Line `50`\n" "51|Line `51`\n" "(49 more lines below)"
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_open_file_large_line_number(temp_file_path):
|
||||
editor = Editor()
|
||||
editor.create_file(str(temp_file_path))
|
||||
with open(temp_file_path, "w") as file:
|
||||
for i in range(1, 1000):
|
||||
file.write(f"Line `{i}`\n")
|
||||
|
||||
current_line = 800
|
||||
window = 100
|
||||
|
||||
result = editor.open_file(str(temp_file_path), current_line, window)
|
||||
|
||||
expected = f"[File: {temp_file_path} (999 lines total)]\n"
|
||||
expected += "(749 more lines above)\n"
|
||||
for i in range(750, 850 + 1):
|
||||
expected += f"{i}|Line `{i}`\n"
|
||||
expected += "(149 more lines below)"
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_open_file_large_line_number_consecutive_diff_window(temp_file_path):
|
||||
editor = Editor()
|
||||
editor.create_file(str(temp_file_path))
|
||||
total_lines = 1000
|
||||
with open(temp_file_path, "w") as file:
|
||||
for i in range(1, total_lines + 1):
|
||||
file.write(f"Line `{i}`\n")
|
||||
|
||||
current_line = 800
|
||||
cur_window = 300
|
||||
|
||||
result = editor.open_file(str(temp_file_path), current_line, cur_window)
|
||||
|
||||
expected = f"[File: {temp_file_path} ({total_lines} lines total)]\n"
|
||||
start, end = _calculate_window_bounds(current_line, total_lines, cur_window)
|
||||
if start == 1:
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
else:
|
||||
expected += f"({start - 1} more lines above)\n"
|
||||
for i in range(current_line - cur_window // 2, current_line + cur_window // 2 + 1):
|
||||
expected += f"{i}|Line `{i}`\n"
|
||||
if end == total_lines:
|
||||
expected += "(this is the end of the file)\n"
|
||||
else:
|
||||
expected += f"({total_lines - end} more lines below)"
|
||||
assert result == expected
|
||||
|
||||
current_line = current_line - WINDOW
|
||||
|
||||
result = editor.scroll_up()
|
||||
|
||||
expected = f"[File: {temp_file_path} ({total_lines} lines total)]\n"
|
||||
start, end = _calculate_window_bounds(current_line, total_lines, WINDOW)
|
||||
if start == 1:
|
||||
expected += "(this is the beginning of the file)\n"
|
||||
else:
|
||||
expected += f"({start - 1} more lines above)\n"
|
||||
for i in range(start, end + 1):
|
||||
expected += f"{i}|Line `{i}`\n"
|
||||
if end == total_lines:
|
||||
expected += "(this is the end of the file)\n"
|
||||
else:
|
||||
expected += f"({total_lines - end} more lines below)"
|
||||
assert result.split("\n") == expected.split("\n")
|
||||
|
||||
|
||||
EXPECTED_CONTENT_AFTER_REPLACE_TEXT = """
|
||||
# this is line one
|
||||
def test_function_for_fm():
|
||||
"some docstring"
|
||||
a = 1
|
||||
b = 9
|
||||
c = 3
|
||||
# this is the 7th line
|
||||
""".strip()
|
||||
|
||||
|
||||
def test_edit_file_by_replace(temp_py_file):
|
||||
editor = Editor()
|
||||
editor.edit_file_by_replace(file_name=str(temp_py_file), to_replace=" b = 2", new_content=" b = 9")
|
||||
with open(temp_py_file, "r") as f:
|
||||
new_content = f.read()
|
||||
assert new_content.strip() == EXPECTED_CONTENT_AFTER_REPLACE_TEXT.strip()
|
||||
|
||||
|
||||
def test_append_file(temp_file_path):
|
||||
editor = Editor()
|
||||
# 写入初始内容
|
||||
initial_content = "Line 1\nLine 2\nLine 3\n"
|
||||
temp_file_path.write_text(initial_content)
|
||||
|
||||
# 追加内容到文件
|
||||
append_content = "Line 4\nLine 5\n"
|
||||
|
||||
result = editor.append_file(str(temp_file_path), append_content)
|
||||
|
||||
# 预期内容
|
||||
expected_content = initial_content + append_content
|
||||
|
||||
# 读取文件并断言内容与预期一致
|
||||
with open(temp_file_path, "r") as f:
|
||||
new_content = f.read()
|
||||
assert new_content == expected_content
|
||||
|
||||
# 输出的预期结果
|
||||
expected_output = (
|
||||
f"[File: {temp_file_path.resolve()} (5 lines total after edit)]\n"
|
||||
"(this is the beginning of the file)\n"
|
||||
"1|Line 1\n"
|
||||
"2|Line 2\n"
|
||||
"3|Line 3\n"
|
||||
"4|Line 4\n"
|
||||
"5|Line 5\n"
|
||||
"(this is the end of the file)\n"
|
||||
"[File updated (edited at line 3). Please review the changes and make sure they are correct (correct indentation, no duplicate lines, etc). Edit the file again if necessary.]"
|
||||
)
|
||||
|
||||
assert result.split("\n") == expected_output.split("\n")
|
||||
|
||||
|
||||
def test_search_dir(tmp_path):
|
||||
editor = Editor()
|
||||
dir_path = tmp_path / "test_dir"
|
||||
dir_path.mkdir()
|
||||
|
||||
# Create some files with specific content
|
||||
(dir_path / "file1.txt").write_text("This is a test file with some content.")
|
||||
(dir_path / "file2.txt").write_text("Another file with different content.")
|
||||
sub_dir = dir_path / "sub_dir"
|
||||
sub_dir.mkdir()
|
||||
(sub_dir / "file3.txt").write_text("This file is inside a sub directory with some content.")
|
||||
|
||||
search_term = "some content"
|
||||
|
||||
result = editor.search_dir(search_term, str(dir_path))
|
||||
|
||||
assert "file1.txt" in result
|
||||
assert "file3.txt" in result
|
||||
assert "Another file with different content." not in result
|
||||
|
||||
|
||||
def test_search_file(temp_file_path):
|
||||
editor = Editor()
|
||||
file_path = temp_file_path
|
||||
file_path.write_text("This is a test file with some content.\nAnother line with more content.")
|
||||
|
||||
search_term = "some content"
|
||||
|
||||
result = editor.search_file(search_term, str(file_path))
|
||||
|
||||
assert "Line 1: This is a test file with some content." in result
|
||||
assert "Line 2: Another line with more content." not in result
|
||||
|
||||
|
||||
def test_find_file(tmp_path):
|
||||
editor = Editor()
|
||||
dir_path = tmp_path / "test_dir"
|
||||
dir_path.mkdir()
|
||||
|
||||
# Create some files with specific names
|
||||
(dir_path / "file1.txt").write_text("Content of file 1.")
|
||||
(dir_path / "file2.txt").write_text("Content of file 2.")
|
||||
sub_dir = dir_path / "sub_dir"
|
||||
sub_dir.mkdir()
|
||||
(sub_dir / "file3.txt").write_text("Content of file 3.")
|
||||
|
||||
file_name = "file1.txt"
|
||||
|
||||
result = editor.find_file(file_name, str(dir_path))
|
||||
|
||||
assert "file1.txt" in result
|
||||
assert "file2.txt" not in result
|
||||
assert "file3.txt" not in result
|
||||
|
||||
|
||||
# Test data for _append_impl method
|
||||
TEST_LINES = ["First line\n", "Second line\n", "Third line\n"]
|
||||
|
||||
NEW_CONTENT = "Appended line\n"
|
||||
|
||||
EXPECTED_APPEND_NON_EMPTY_FILE = ["First line\n", "Second line\n", "Third line\n", "Appended line\n"]
|
||||
|
||||
EXPECTED_APPEND_EMPTY_FILE = ["Appended line\n"]
|
||||
|
||||
|
||||
def test_append_non_empty_file():
|
||||
editor = Editor()
|
||||
lines = TEST_LINES.copy()
|
||||
content, n_added_lines = editor._append_impl(lines, NEW_CONTENT)
|
||||
|
||||
assert content.splitlines(keepends=True) == EXPECTED_APPEND_NON_EMPTY_FILE
|
||||
assert n_added_lines == 1
|
||||
|
||||
|
||||
def test_append_empty_file():
|
||||
editor = Editor()
|
||||
lines = []
|
||||
content, n_added_lines = editor._append_impl(lines, NEW_CONTENT)
|
||||
|
||||
assert content.splitlines(keepends=True) == EXPECTED_APPEND_EMPTY_FILE
|
||||
assert n_added_lines == 1
|
||||
|
||||
|
||||
def test_append_to_single_empty_line_file():
|
||||
editor = Editor()
|
||||
lines = [""]
|
||||
content, n_added_lines = editor._append_impl(lines, NEW_CONTENT)
|
||||
|
||||
assert content.splitlines(keepends=True) == EXPECTED_APPEND_EMPTY_FILE
|
||||
assert n_added_lines == 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-s"])
|
||||
|
|
|
|||
32
tests/metagpt/tools/libs/test_index_repo.py
Normal file
32
tests/metagpt/tools/libs/test_index_repo.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import shutil
|
||||
|
||||
import pytest
|
||||
|
||||
from metagpt.const import DEFAULT_WORKSPACE_ROOT, TEST_DATA_PATH
|
||||
from metagpt.tools.libs.index_repo import IndexRepo
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(("path", "query"), [(TEST_DATA_PATH / "requirements", "业务线")])
|
||||
async def test_index_repo(path, query):
|
||||
index_path = DEFAULT_WORKSPACE_ROOT / ".index"
|
||||
repo = IndexRepo(persist_path=str(index_path), root_path=str(path), min_token_count=0)
|
||||
await repo.add([path])
|
||||
await repo.add([path])
|
||||
assert index_path.exists()
|
||||
|
||||
rsp = await repo.search(query)
|
||||
assert rsp
|
||||
|
||||
repo2 = IndexRepo(persist_path=str(index_path), root_path=str(path), min_token_count=0)
|
||||
rsp2 = await repo2.search(query)
|
||||
assert rsp2
|
||||
|
||||
merged_rsp = await repo.merge(query=query, indices_list=[rsp, rsp2])
|
||||
assert merged_rsp
|
||||
|
||||
shutil.rmtree(index_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pytest.main([__file__, "-s"])
|
||||
Loading…
Add table
Add a link
Reference in a new issue