This commit is contained in:
femto 2023-09-19 12:23:22 +08:00
parent 04f4a353ad
commit 74217a1df3
5 changed files with 54 additions and 106 deletions

View file

@ -6,6 +6,7 @@
@File : environment.py
"""
from metagpt.actions.action import Action
from metagpt.logs import logger
from metagpt.utils.common import CodeParser
PROMPT_TEMPLATE = """
@ -38,9 +39,9 @@ class WriteTest(Action):
try:
code = CodeParser.parse_code(block="", text=code_rsp)
except Exception as e:
except Exception:
# Handle the exception if needed
print(f"An exception occurred: {str(e)}")
logger.error(f"Can't parse the code: {code_rsp}")
# Return code_rsp in case of an exception, assuming llm just returns code as it is and doesn't wrap it inside ```
code = code_rsp

View file

@ -91,6 +91,24 @@ WHITESPACE_STR = " \t\n\r"
def JSONObject(
s_and_end, strict, scan_once, object_hook, object_pairs_hook, memo=None, _w=WHITESPACE.match, _ws=WHITESPACE_STR
):
"""Parse a JSON object from a string and return the parsed object.
Args:
s_and_end (tuple): A tuple containing the input string to parse and the current index within the string.
strict (bool): If `True`, enforces strict JSON string decoding rules.
If `False`, allows literal control characters in the string. Defaults to `True`.
scan_once (callable): A function to scan and parse JSON values from the input string.
object_hook (callable): A function that, if specified, will be called with the parsed object as a dictionary.
object_pairs_hook (callable): A function that, if specified, will be called with the parsed object as a list of pairs.
memo (dict, optional): A dictionary used to memoize string keys for optimization. Defaults to None.
_w (function): A regular expression matching function for whitespace. Defaults to WHITESPACE.match.
_ws (str): A string containing whitespace characters. Defaults to WHITESPACE_STR.
Returns:
tuple or dict: A tuple containing the parsed object and the index of the character in the input string
after the end of the object.
"""
s, end = s_and_end
pairs = []
pairs_append = pairs.append
@ -175,14 +193,23 @@ def JSONObject(
def py_scanstring(s, end, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match, delimiter='"'):
"""Scan the string s for a JSON string. End is the index of the
character in s after the quote that started the JSON string.
Unescapes all valid JSON string escape sequences and raises ValueError
on attempt to decode an invalid string. If strict is False then literal
control characters are allowed in the string.
"""Scan the string s for a JSON string.
Args:
s (str): The input string to be scanned for a JSON string.
end (int): The index of the character in `s` after the quote that started the JSON string.
strict (bool): If `True`, enforces strict JSON string decoding rules.
If `False`, allows literal control characters in the string. Defaults to `True`.
_b (dict): A dictionary containing escape sequence mappings.
_m (function): A regular expression matching function for string chunks.
delimiter (str): The string delimiter used to define the start and end of the JSON string.
Can be one of: '"', "'", '\"""', or "'''". Defaults to '"'.
Returns:
tuple: A tuple containing the decoded string and the index of the character in `s`
after the end quote.
"""
Returns a tuple of the decoded string and the index of the character in s
after the end quote."""
chunks = []
_append = chunks.append
begin = end - 1

View file

@ -38,3 +38,4 @@ typing-inspect==0.8.0
typing_extensions==4.5.0
libcst==1.0.1
qdrant-client==1.4.0
pytest-mock==3.11.1

View file

@ -31,7 +31,7 @@ async def test_write_test():
code_to_test=code,
test_file_name="test_food.py",
source_file_path="/some/dummy/path/cli_snake_game/cli_snake_game/food.py",
workspace="/some/dummy/path/cli_snake_game"
workspace="/some/dummy/path/cli_snake_game",
)
logger.info(test_code)
@ -40,3 +40,18 @@ async def test_write_test():
assert "from cli_snake_game.food import Food" in test_code
assert "class TestFood(unittest.TestCase)" in test_code
assert "def test_generate" in test_code
@pytest.mark.asyncio
async def test_write_code_invalid_code(mocker):
# Mock the _aask method to return an invalid code string
mocker.patch.object(WriteTest, "_aask", return_value="Invalid Code String")
# Create an instance of WriteTest
write_test = WriteTest()
# Call the write_code method
code = await write_test.write_code("Some prompt:")
# Assert that the returned code is the same as the invalid code string
assert code == "Invalid Code String"

View file

@ -70,99 +70,3 @@ def test_parse_triple_single_quote():
parsed_data = decoder.decode(input_data)
assert parsed_data["a"] == "b"
# def test_parse_complex():
# # Create a custom JSON decoder
# decoder = CustomDecoder(strict=False)
# # Your provided input with single-quoted strings and line breaks
# input_data = '''{
# "Required Python third-party packages": [
# "flask==1.1.2",
# "bcrypt==3.2.0"
# ],
# "Required Other language third-party packages": [
# "No third-party packages are required."
# ],
# "Full API spec": """
# openapi: 3.0.0
#
# description: A JSON object representing the game state.
#
# paths:
# /game:
# get:
# summary: Get the current game state.
# responses:
# '200':
# description: The current game state.
#
# /game/{direction}:
# post:
# summary: Move the snake in the specified direction.
# parameters:
# - name: direction
# in: path
# description: The direction to move the snake (one of UP, DOWN, LEFT, or RIGHT).
# responses:
# '200':
# description: The updated game state.
#
# /game/{food}:
# get:
# summary: Get the current food position.
# responses:
# '200':
# description: The current food position.
#
# /game/{snake}:
# get:
# summary: Get the current snake position.
# responses:
# '200':
# description: The current snake position.
#
# /game/{snake}/{direction}:
# post:
# summary: Set the snake direction.
# parameters:
# - name: direction
# in: path
# description: The direction to move the snake (one of UP, DOWN, LEFT, or RIGHT).
# responses:
# '200':
# description: The updated game state.
#
# /game/end:
# post:
# summary: End the game.
# responses:
# '200':
# description: The final game state.
# "
# ],
# "Logic Analysis": [
# ["game.py","Contains the game logic and snake movement."],
# ["snake.py","Contains the snake class and methods."],
# ["game_objects.py","Contains the game objects and their properties."],
# ["game_logic.py","Contains the game logic and rules."],
# ["ui.py","Contains the user interface and display logic."]
# ],
# "Task list": [
# "game.py",
# "snake.py",
# "game_objects.py",
# "game_logic.py",
# "ui.py"
# ],
# "Shared Knowledge": """
# The game state is represented by a JSON object.
# The snake movement is based on the direction parameter.
# The game ends when the snake collides with the wall or eats the food.
# """,
# "Anything UNCLEAR": "The requirement is clear to me."
# }
# '''
# # Parse the JSON using the custom decoder
#
# parsed_data = decoder.decode(input_data)