mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-04-26 17:26:22 +02:00
1. remove INC prompt in some ActionNode
2. replace Code archive from data to tests/data/incremental_dev_project 3. update test case for ActionNode
This commit is contained in:
parent
f460771978
commit
f4e39a462c
19 changed files with 194 additions and 420 deletions
|
|
@ -101,4 +101,7 @@ def llm():
|
|||
async def test_write_design_an():
|
||||
node = await REFINED_DESIGN_NODES.fill(CONTEXT, llm)
|
||||
assert node.instruct_content
|
||||
assert "Refined Implementation Approach" in node.instruct_content.model_dump_json()
|
||||
assert "Refined File List" in node.instruct_content.model_dump_json()
|
||||
assert "Refined Data Structures and Interfaces" in node.instruct_content.model_dump_json()
|
||||
assert "Refined Program call flow" in node.instruct_content.model_dump_json()
|
||||
|
|
|
|||
|
|
@ -141,4 +141,8 @@ def llm():
|
|||
async def test_project_management_an(llm):
|
||||
node = await REFINED_PM_NODES.fill(CONTEXT, llm)
|
||||
assert node.instruct_content
|
||||
assert "Required Python Packages" in node.instruct_content.model_dump_json()
|
||||
assert "Required Other Language Packages" in node.instruct_content.model_dump_json()
|
||||
assert "Refined Logic Analysis" in node.instruct_content.model_dump_json()
|
||||
assert "Refined Task List" in node.instruct_content.model_dump_json()
|
||||
assert "Refined Shared Knowledge" in node.instruct_content.model_dump_json()
|
||||
|
|
|
|||
|
|
@ -185,9 +185,94 @@ if __name__ == "__main__":
|
|||
CalculatorApp.main()
|
||||
```"""
|
||||
|
||||
INCREMENTAL_CHANGE_EXAMPLE = """
|
||||
GUIDELINES_AND_INCREMENTAL_CHANGE_EXAMPLE = """
|
||||
{
|
||||
"Incremental Change": "- operations.py: Implement the Operations class with a method to perform the requested arithmetic operation. This class will be used by the Calculator class to execute the operations.\n```python\n## operations.py\nclass Operations:\n @staticmethod\n def perform_operation(operation: str, number1: float, number2: float) -> float:\n if operation == 'add':\n return number1 + number2\n elif operation == 'subtract':\n return number1 - number2\n elif operation == 'multiply':\n return number1 * number2\n elif operation == 'divide':\n if number2 == 0:\n raise ValueError('Cannot divide by zero')\n return number1 / number2\n else:\n raise ValueError('Invalid operation')\n```\n\n- calculator.py: Extend the Calculator class to include methods for subtraction, multiplication, and division. These methods will utilize the Operations class to perform the actual calculations.\n```python\n## calculator.py\nfrom operations import Operations\nclass Calculator:\n ...\n def subtract(self, number1: float, number2: float) -> float:\n return Operations.perform_operation('subtract', number1, number2)\n\n def multiply(self, number1: float, number2: float) -> float:\n return Operations.perform_operation('multiply', number1, number2)\n\n def divide(self, number1: float, number2: float) -> float:\n return Operations.perform_operation('divide', number1, number2)\n```\n\n- interface.py: Update the Interface class to include buttons for subtraction, multiplication, and division, and link them to the corresponding methods in the Calculator class. Also, handle the display of errors such as division by zero.\n```python\n## interface.py\nimport tkinter as tk\nfrom tkinter import messagebox\nfrom calculator import Calculator\n...\nclass Interface:\n ...\n def create_widgets(self):\n ...\n self.subtract_button = tk.Button(self.root, text='-', command=self.subtract, font=('Arial', 18))\n self.subtract_button.grid(row=3, column=0, sticky='nsew')\n\n self.multiply_button = tk.Button(self.root, text='*', command=self.multiply, font=('Arial', 18))\n self.multiply_button.grid(row=3, column=1, sticky='nsew')\n\n self.divide_button = tk.Button(self.root, text='/', command=self.divide, font=('Arial', 18))\n self.divide_button.grid(row=3, column=2, sticky='nsew')\n ...\n\n def subtract(self):\n number1, number2 = self.get_input()\n if number1 is not None and number2 is not None:\n result = self.calculator.subtract(number1, number2)\n self.display_result(result)\n\n def multiply(self):\n number1, number2 = self.get_input()\n if number1 is not None and number2 is not None:\n result = self.calculator.multiply(number1, number2)\n self.display_result(result)\n\n def divide(self):\n number1, number2 = self.get_input()\n if number1 is not None and number2 is not None:\n try:\n result = self.calculator.divide(number1, number2)\n except ValueError as e:\n self.show_error(str(e))\n return\n self.display_result(result)\n```\n\n- main.py: No changes needed in main.py as it serves as the entry point and will run the updated Interface class.\n```python\n## main.py\nfrom interface import Interface\n...\n```\n\nNote: Ensure that the new operations buttons in the Interface class are properly arranged and that the grid layout is adjusted accordingly. Also, make sure to import the messagebox module from tkinter for error handling."
|
||||
"Guidelines and Incremental Change": "
|
||||
1. Guideline for calculator.py: Enhance the functionality of `calculator.py` by extending it to incorporate methods for subtraction, multiplication, and division. Additionally, implement robust error handling for the division operation to mitigate potential issues related to division by zero.
|
||||
```python
|
||||
class Calculator:
|
||||
self.result = number1 + number2
|
||||
return self.result
|
||||
|
||||
- def sub(self, number1, number2) -> float:
|
||||
+ def subtract(self, number1: float, number2: float) -> float:
|
||||
+ '''
|
||||
+ Subtracts the second number from the first and returns the result.
|
||||
+
|
||||
+ Args:
|
||||
+ number1 (float): The number to be subtracted from.
|
||||
+ number2 (float): The number to subtract.
|
||||
+
|
||||
+ Returns:
|
||||
+ float: The difference of number1 and number2.
|
||||
+ '''
|
||||
+ self.result = number1 - number2
|
||||
+ return self.result
|
||||
+
|
||||
def multiply(self, number1: float, number2: float) -> float:
|
||||
- pass
|
||||
+ '''
|
||||
+ Multiplies two numbers and returns the result.
|
||||
+
|
||||
+ Args:
|
||||
+ number1 (float): The first number to multiply.
|
||||
+ number2 (float): The second number to multiply.
|
||||
+
|
||||
+ Returns:
|
||||
+ float: The product of number1 and number2.
|
||||
+ '''
|
||||
+ self.result = number1 * number2
|
||||
+ return self.result
|
||||
+
|
||||
def divide(self, number1: float, number2: float) -> float:
|
||||
- pass
|
||||
+ '''
|
||||
+ ValueError: If the second number is zero.
|
||||
+ '''
|
||||
+ if number2 == 0:
|
||||
+ raise ValueError('Cannot divide by zero')
|
||||
+ self.result = number1 / number2
|
||||
+ return self.result
|
||||
+
|
||||
- def reset_result(self):
|
||||
+ def clear(self):
|
||||
+ if self.result != 0.0:
|
||||
+ print("Result is not zero, clearing...")
|
||||
+ else:
|
||||
+ print("Result is already zero, no need to clear.")
|
||||
+
|
||||
self.result = 0.0
|
||||
```
|
||||
|
||||
2. Guideline for main.py: Integrate new API endpoints for subtraction, multiplication, and division into the existing codebase of `main.py`. Then, ensure seamless integration with the overall application architecture and maintain consistency with coding standards.
|
||||
```python
|
||||
def add_numbers():
|
||||
result = calculator.add_numbers(num1, num2)
|
||||
return jsonify({'result': result}), 200
|
||||
|
||||
-# TODO: Implement subtraction, multiplication, and division operations
|
||||
+@app.route('/subtract_numbers', methods=['POST'])
|
||||
+def subtract_numbers():
|
||||
+ data = request.get_json()
|
||||
+ num1 = data.get('num1', 0)
|
||||
+ num2 = data.get('num2', 0)
|
||||
+ result = calculator.subtract_numbers(num1, num2)
|
||||
+ return jsonify({'result': result}), 200
|
||||
+
|
||||
+@app.route('/multiply_numbers', methods=['POST'])
|
||||
+def multiply_numbers():
|
||||
+ data = request.get_json()
|
||||
+ num1 = data.get('num1', 0)
|
||||
+ num2 = data.get('num2', 0)
|
||||
+ try:
|
||||
+ result = calculator.divide_numbers(num1, num2)
|
||||
+ except ValueError as e:
|
||||
+ return jsonify({'error': str(e)}), 400
|
||||
+ return jsonify({'result': result}), 200
|
||||
+
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
||||
```"
|
||||
}
|
||||
"""
|
||||
|
||||
|
|
@ -207,7 +292,7 @@ async def test_write_code_guideline_an():
|
|||
async def test_refine_code():
|
||||
prompt = REFINED_CODE_TEMPLATE.format(
|
||||
requirement=REQUIREMENT_EXAMPLE,
|
||||
guideline=INCREMENTAL_CHANGE_EXAMPLE,
|
||||
guideline=GUIDELINES_AND_INCREMENTAL_CHANGE_EXAMPLE,
|
||||
design=DESIGN_EXAMPLE,
|
||||
tasks=TASKS_EXAMPLE,
|
||||
code=REFINE_CODE_SCRIPT_EXAMPLE,
|
||||
|
|
|
|||
|
|
@ -85,4 +85,8 @@ def llm():
|
|||
async def test_write_prd_an(llm):
|
||||
node = await REFINE_PRD_NODE.fill(CONTEXT, llm)
|
||||
assert node.instruct_content
|
||||
assert "Refined Requirements" in node.instruct_content.model_dump_json()
|
||||
assert "Refined Product Goals" in node.instruct_content.model_dump_json()
|
||||
assert "Refined User Stories" in node.instruct_content.model_dump_json()
|
||||
assert "Refined Requirement Analysis" in node.instruct_content.model_dump_json()
|
||||
assert "Refined Requirement Pool" in node.instruct_content.model_dump_json()
|
||||
|
|
|
|||
|
|
@ -11,24 +11,73 @@ import subprocess
|
|||
import pytest
|
||||
from typer.testing import CliRunner
|
||||
|
||||
from metagpt.const import DATA_PATH
|
||||
from metagpt.const import TEST_DATA_PATH
|
||||
from metagpt.logs import logger
|
||||
from metagpt.startup import app
|
||||
|
||||
runner = CliRunner()
|
||||
|
||||
IDEAS = [
|
||||
"Add subtraction, multiplication and division operations to the calculator. The current calculator can only perform basic addition operations, and it is necessary to introduce subtraction, multiplication, division operation into the calculator",
|
||||
"Add a feature to remove deprecated words from the word cloud. The current word cloud generator does not support removing deprecated words. Now, The word cloud generator should support removing deprecated words. Customize deactivated words to exclude them from word cloud. Let users see all the words in the text file, and allow users to select the words they want to remove.",
|
||||
"Add an AI opponent with fixed difficulty levels. Currently, the game only allows players to compete against themselves. Implement an AI algorithm that can playing with player. This will provide a more engaging and challenging experience for players.",
|
||||
"Add functionality to view the history of scores. The original dice rolling game could only display the current game result, but the new requirement allows players to view the history of scores",
|
||||
"Add functionality to view the history of scores and perform statistical analysis on them. The original dice rolling game could only display the current game result, but the new requirement allows players to view the history of scores and display the statistical analysis results of the current score",
|
||||
"Changed score target for 2048 game from 2048 to 4096. Please change the game's score target from 2048 to 4096, and change the interface size from 4*4 to 8*8",
|
||||
"Display the history score of the player in the 2048 game. Add a record board that can display players' historical score records so that players can trace their scores",
|
||||
"Add limited time mode. The original game only had a default classic mode. The improved game should be able to support limited-time mode, allowing users to choose classic mode or limited-time mode from the available options before starting the game.",
|
||||
"Incremental Idea Gradually increase the speed of the snake as the game progresses. In the current version of the game, the snake’s speed remains constant throughout the gameplay. Implement a feature where the snake’s speed gradually increases over time, making the game more challenging and intense as the player progresses.",
|
||||
"Introduce power-ups and obstacles to the game. The current version of the game only involves eating food and growing the snake. Add new elements such as power-ups that can enhance the snake’s speed or make it invincible for a short duration. At the same time, introduce obstacles like walls or enemies that the snake must avoid or overcome to continue growing.",
|
||||
]
|
||||
|
||||
def test_refined_simple_calculator():
|
||||
project_path = f"{DATA_PATH}/simple_add_calculator"
|
||||
check_or_create_base_tag(project_path)
|
||||
PROJECT_NAMES = [
|
||||
"calculator",
|
||||
"word_cloud",
|
||||
"Gomoku",
|
||||
"dice_simulator_new",
|
||||
"dice_simulator_new",
|
||||
"pygame_2048",
|
||||
"pygame_2048",
|
||||
"pygame_2048",
|
||||
"snake_game",
|
||||
"snake_game",
|
||||
]
|
||||
|
||||
args = [
|
||||
"Add subtraction, multiplication and division operations to the calculator. The current calculator can only perform basic addition operations, and it is necessary to introduce subtraction, multiplication, division operation into the calculator",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
|
||||
def test_refined_calculator():
|
||||
result = get_incremental_dev_result(IDEAS[0], PROJECT_NAMES[0])
|
||||
log_and_check_result(result)
|
||||
|
||||
|
||||
def test_refined_word_cloud():
|
||||
result = get_incremental_dev_result(IDEAS[1], PROJECT_NAMES[1])
|
||||
log_and_check_result(result)
|
||||
|
||||
|
||||
def test_refined_gomoku():
|
||||
result = get_incremental_dev_result(IDEAS[2], PROJECT_NAMES[2])
|
||||
log_and_check_result(result)
|
||||
|
||||
|
||||
def test_refined_dice_simulator_new():
|
||||
for idea, project_name in zip(IDEAS[3:5], PROJECT_NAMES[3:5]):
|
||||
result = get_incremental_dev_result(idea, project_name)
|
||||
log_and_check_result(result)
|
||||
|
||||
|
||||
def test_refined_pygame_2048():
|
||||
for idea, project_name in zip(IDEAS[5:8], PROJECT_NAMES[5:8]):
|
||||
result = get_incremental_dev_result(idea, project_name)
|
||||
log_and_check_result(result)
|
||||
|
||||
|
||||
def test_refined_snake_game():
|
||||
for idea, project_name in zip(IDEAS[8:10], PROJECT_NAMES[8:10]):
|
||||
result = get_incremental_dev_result(idea, project_name)
|
||||
log_and_check_result(result)
|
||||
|
||||
|
||||
def log_and_check_result(result):
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
|
|
@ -46,274 +95,19 @@ def test_refined_simple_calculator():
|
|||
raise e
|
||||
|
||||
|
||||
def test_refined_number_guessing_game():
|
||||
project_path = f"{DATA_PATH}/number_guessing_game"
|
||||
def get_incremental_dev_result(idea, project_name):
|
||||
project_path = TEST_DATA_PATH / "incremental_dev_project" / project_name
|
||||
if not os.path.exists(project_path):
|
||||
raise Exception(f"Project {project_name} not exists")
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Adding graphical interface functionality to enhance the user experience in the number-guessing game. The existing number-guessing game currently relies on command-line input for numbers. The goal is to introduce a graphical interface to improve the game's usability and visual appeal",
|
||||
idea,
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
|
||||
def test_refined_word_cloud():
|
||||
project_path = f"{DATA_PATH}/word_cloud"
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Add a feature to remove deprecated words from the word cloud. The current word cloud generator does not support removing deprecated words. Now, The word cloud generator should support removing deprecated words. Customize deactivated words to exclude them from word cloud. Let users see all the words in the text file, and allow users to select the words they want to remove.",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
|
||||
def test_refined_gomoku():
|
||||
project_path = f"{DATA_PATH}/Gomoku"
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Add an AI opponent with fixed difficulty levels. Currently, the game only allows players to compete against themselves. Implement an AI algorithm that can playing with player. This will provide a more engaging and challenging experience for players.",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
|
||||
def test_refined_dice_simulator_1():
|
||||
project_path = f"{DATA_PATH}/dice_simulator_new"
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Add functionality to view the history of scores. The original dice rolling game could only display the current game result, but the new requirement allows players to view the history of scores",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine_1"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
|
||||
def test_refined_dice_simulator_2():
|
||||
project_path = f"{DATA_PATH}/dice_simulator_new"
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Add functionality to view the history of scores and perform statistical analysis on them. The original dice rolling game could only display the current game result, but the new requirement allows players to view the history of scores and display the statistical analysis results of the current score",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine_2"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
|
||||
def test_refined_pygame_2048_1():
|
||||
project_path = f"{DATA_PATH}/pygame_2048"
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Changed score target for 2048 game from 2048 to 4096. Please change the game's score target from 2048 to 4096, and change the interface size from 4*4 to 8*8",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine_1"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
|
||||
def test_refined_pygame_2048_2():
|
||||
project_path = f"{DATA_PATH}/pygame_2048"
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Display the history score of the player in the 2048 game. Add a record board that can display players' historical score records so that players can trace their scores",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine_2"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
|
||||
def test_refined_pygame_2048_3():
|
||||
project_path = f"{DATA_PATH}/pygame_2048"
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Add limited time mode. The original game only had a default classic mode. The improved game should be able to support limited-time mode, allowing users to choose classic mode or limited-time mode from the available options before starting the game.",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine_3"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
|
||||
def test_refined_snake_game_1():
|
||||
project_path = f"{DATA_PATH}/snake_game"
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Incremental Idea Gradually increase the speed of the snake as the game progresses. In the current version of the game, the snake’s speed remains constant throughout the gameplay. Implement a feature where the snake’s speed gradually increases over time, making the game more challenging and intense as the player progresses.",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine_1"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
|
||||
|
||||
def test_refined_snake_game_2():
|
||||
project_path = f"{DATA_PATH}/snake_game"
|
||||
check_or_create_base_tag(project_path)
|
||||
|
||||
args = [
|
||||
"Introduce power-ups and obstacles to the game. The current version of the game only involves eating food and growing the snake. Add new elements such as power-ups that can enhance the snake’s speed or make it invincible for a short duration. At the same time, introduce obstacles like walls or enemies that the snake must avoid or overcome to continue growing.",
|
||||
"--inc",
|
||||
"--project-path",
|
||||
project_path,
|
||||
]
|
||||
result = runner.invoke(app, args)
|
||||
logger.info(result)
|
||||
logger.info(result.output)
|
||||
if "Aborting" in result.output:
|
||||
assert False
|
||||
else:
|
||||
tag = subprocess.run(["git", "describe", "--tags"], capture_output=True, text=True).stdout.strip()
|
||||
if tag == "base":
|
||||
assert False
|
||||
else:
|
||||
assert True
|
||||
try:
|
||||
subprocess.run(["git", "tag", "refine_2"], check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise e
|
||||
return result
|
||||
|
||||
|
||||
def check_or_create_base_tag(project_path):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue