|
import os |
|
import time |
|
import subprocess |
|
from typing import Dict, Any |
|
from flow_modules.aiflows.InterpreterFlowModule import InterpreterAtomicFlow |
|
|
|
|
|
class CodeTestingAtomicFlow(InterpreterAtomicFlow): |
|
"""This class inherits from InterpreterAtomicFlow and is used to test code. |
|
|
|
*Input Interface*: |
|
- `temp_code_file_location`: Location of the file containing the code to be tested. |
|
|
|
*Output Interface*: |
|
- `feedback`: Feedback from the test (i.e. test results). |
|
|
|
*Configuration Parameters*: |
|
- `input_interface`: the input interface of the atomic flow. |
|
- `output_interface`: the output interface of the atomic flow. |
|
""" |
|
def _open_file_and_wait_for_file_update(self, file_location, check_interval=1): |
|
"""Opens the file in VSCode and waits for the file to be updated. |
|
:param file_location: The location of the file to be opened. |
|
:type file_location: str |
|
:param check_interval: The interval at which the file is checked for updates. |
|
:type check_interval: int |
|
""" |
|
process = subprocess.Popen(["code", "--wait", file_location]) |
|
while True: |
|
if process.poll() is not None: |
|
break |
|
time.sleep(check_interval) |
|
def _prepare_code_and_lang(self, input_data: Dict[str, Any]): |
|
"""Prepares the code and language to be passed to the interpreter. |
|
:param input_data: The input data to the atomic flow. |
|
:type input_data: Dict[str, Any] |
|
""" |
|
file_location = input_data["temp_code_file_location"] |
|
input_data["language"] = "python" |
|
with open(file_location, "r") as file: |
|
code_str = file.read() |
|
input_data["code"] = code_str |
|
|
|
def _check_input(self, input_data: Dict[str, Any]): |
|
"""Checks if the input data contains the required keys. |
|
:param input_data: The input data to the atomic flow. |
|
:type input_data: Dict[str, Any] |
|
:raises AssertionError: If the input data does not contain the required keys. |
|
""" |
|
assert "temp_code_file_location" in input_data, "temp_code_file_location not passed to CodeTestingAtomicFlow" |
|
|
|
def _delete_file(self, file_location): |
|
"""Deletes the file at the given location. |
|
:param file_location: The location of the file to be deleted. |
|
:type file_location: str |
|
""" |
|
if os.path.exists(file_location): |
|
os.remove(file_location) |
|
|
|
def run( |
|
self, |
|
input_data: Dict[str, Any]): |
|
"""Runs the atomic flow. |
|
:param input_data: The input data to the atomic flow. |
|
:type input_data: Dict[str, Any] |
|
:return: The output data of the atomic flow. |
|
:rtype: Dict[str, Any] |
|
""" |
|
self._check_input(input_data) |
|
file_loc = input_data["temp_code_file_location"] |
|
self._open_file_and_wait_for_file_update(file_loc) |
|
self._prepare_code_and_lang(input_data) |
|
self._process_input_data(input_data) |
|
response = self._call() |
|
self._delete_file(file_loc) |
|
if response.strip() == '': |
|
response = "test passed" |
|
return {"feedback": response} |
|
|