mirror of
https://github.com/codeflash-ai/codeflash-internal.git
synced 2026-05-04 18:25:18 +00:00
Added bubble sort implementation and unit tests for it, refactored argument name "--tests-root" to "--test-root", and made some minor code improvements.
This commit is contained in:
parent
d9e487ebe9
commit
31d6c562d7
7 changed files with 64 additions and 36 deletions
3
code_to_optimize/bubble_sort.py
Normal file
3
code_to_optimize/bubble_sort.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
def sorter(arr):
|
||||
arr.sort()
|
||||
return arr
|
||||
18
code_to_optimize/tests/unittest/test_bubble_sort.py
Normal file
18
code_to_optimize/tests/unittest/test_bubble_sort.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import unittest
|
||||
|
||||
from code_to_optimize.bubble_sort import sorter
|
||||
|
||||
|
||||
class TestPigLatin(unittest.TestCase):
|
||||
def test_sort(self):
|
||||
input = [5, 4, 3, 2, 1, 0]
|
||||
output = sorter(input)
|
||||
self.assertEqual(output, [0, 1, 2, 3, 4, 5])
|
||||
|
||||
input = [5.0, 4.0, 3.0, 2.0, 1.0, 0.0]
|
||||
output = sorter(input)
|
||||
self.assertEqual(output, [0.0, 1.0, 2.0, 3.0, 4.0, 5.0])
|
||||
|
||||
input = list(reversed(range(5000)))
|
||||
output = sorter(input)
|
||||
self.assertEqual(output, list(range(5000)))
|
||||
|
|
@ -51,14 +51,12 @@ def discover_tests_unittest(test_directory, project_root_path):
|
|||
print("Didn't find tests for ", test_suite_2)
|
||||
continue
|
||||
for test in test_suite_2._tests:
|
||||
m = re.search("(.*)\s\((.*)\.(.*)\)", str(test))
|
||||
if not m:
|
||||
continue
|
||||
test_function, test_module, test_suite_name = (
|
||||
m.group(1),
|
||||
m.group(2),
|
||||
m.group(3),
|
||||
test._testMethodName,
|
||||
test.__class__.__module__,
|
||||
test.__class__.__qualname__,
|
||||
)
|
||||
|
||||
test_module_path = test_module.replace(".", os.sep)
|
||||
test_module_path = os.path.join(str(test_directory), test_module_path) + ".py"
|
||||
if not os.path.exists(test_module_path):
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ def parse_args():
|
|||
help="Path to the root of the project, from where your python modules are imported",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--tests-root",
|
||||
"--test-root",
|
||||
type=str,
|
||||
)
|
||||
parser.add_argument("--test-framework", choices=["pytest", "unittest"])
|
||||
|
|
@ -59,14 +59,14 @@ def parse_args():
|
|||
raise ValueError("If you specify a --function, you must specify the --file it is in")
|
||||
|
||||
pyproject_config = parse_config_file(args.config_file)
|
||||
supported_keys = ["root", "tests_root", "test_framework"]
|
||||
supported_keys = ["root", "test_root", "test_framework"]
|
||||
for key in supported_keys:
|
||||
if key in pyproject_config and getattr(args, key.replace("-", "_")) is None:
|
||||
setattr(args, key.replace("-", "_"), pyproject_config[key])
|
||||
args.root = os.path.realpath(args.root)
|
||||
args.tests_root = os.path.realpath(args.tests_root)
|
||||
args.test_root = os.path.realpath(args.test_root)
|
||||
assert os.path.isdir(args.root), "--root must be a valid directory"
|
||||
assert os.path.isdir(args.tests_root), "--tests_root must be a valid directory"
|
||||
assert os.path.isdir(args.test_root), "--test_root must be a valid directory"
|
||||
return args
|
||||
|
||||
|
||||
|
|
@ -90,10 +90,10 @@ def main() -> None:
|
|||
os.remove("/tmp/pr_comment_temp.txt")
|
||||
try:
|
||||
functions_to_tests_map = discover_unit_tests(
|
||||
args.tests_root, args.root, test_framework=args.test_framework
|
||||
args.test_root, args.root, test_framework=args.test_framework
|
||||
)
|
||||
for path in modified_functions:
|
||||
if path.startswith(args.tests_root + os.sep):
|
||||
if path.startswith(args.test_root + os.sep):
|
||||
print("SKIPPING OPTIMIZING TEST FILE")
|
||||
continue
|
||||
# TODO: Sequence the functions one goes through intelligently. If we are optimizing f(g(x)), then we might want to first
|
||||
|
|
@ -120,25 +120,31 @@ def main() -> None:
|
|||
print("CODE TO OPTIMIZE", code_to_optimize)
|
||||
module_path = get_module_name_from_file(path, args.root)
|
||||
unique_original_test_files = set()
|
||||
for i, tests_in_file in enumerate(
|
||||
functions_to_tests_map[module_path + "." + function_name]
|
||||
):
|
||||
if tests_in_file.test_file in unique_original_test_files:
|
||||
continue
|
||||
new_test_path = (
|
||||
os.path.splitext(tests_in_file.test_file)[0]
|
||||
+ "__perfinstrumented"
|
||||
+ os.path.splitext(tests_in_file.test_file)[1]
|
||||
if not module_path + "." + function_name in functions_to_tests_map:
|
||||
print(
|
||||
f"Could not find any pre-existing tests for '{module_path + '.' + function_name}', "
|
||||
f"will only use generated tests."
|
||||
)
|
||||
injected_test = inject_profiling_into_existing_test(
|
||||
tests_in_file.test_file,
|
||||
function_name,
|
||||
args.root,
|
||||
)
|
||||
with open(new_test_path, "w") as f:
|
||||
f.write(injected_test)
|
||||
instrumented_unittests_created.add(new_test_path)
|
||||
unique_original_test_files.add(tests_in_file.test_file)
|
||||
else:
|
||||
for i, tests_in_file in enumerate(
|
||||
functions_to_tests_map.get(module_path + "." + function_name)
|
||||
):
|
||||
if tests_in_file.test_file in unique_original_test_files:
|
||||
continue
|
||||
new_test_path = (
|
||||
os.path.splitext(tests_in_file.test_file)[0]
|
||||
+ "__perfinstrumented"
|
||||
+ os.path.splitext(tests_in_file.test_file)[1]
|
||||
)
|
||||
injected_test = inject_profiling_into_existing_test(
|
||||
tests_in_file.test_file,
|
||||
function_name,
|
||||
args.root,
|
||||
)
|
||||
with open(new_test_path, "w") as f:
|
||||
f.write(injected_test)
|
||||
instrumented_unittests_created.add(new_test_path)
|
||||
unique_original_test_files.add(tests_in_file.test_file)
|
||||
new_tests = generate_tests(
|
||||
source_code_being_tested=code_to_optimize,
|
||||
function_name=function_name,
|
||||
|
|
@ -149,7 +155,7 @@ def main() -> None:
|
|||
)
|
||||
if new_tests is None:
|
||||
continue
|
||||
generated_tests_path = get_test_file_path(args.tests_root, function_name, 0)
|
||||
generated_tests_path = get_test_file_path(args.test_root, function_name, 0)
|
||||
test_files_created.add(generated_tests_path)
|
||||
with open(generated_tests_path, "w") as file:
|
||||
file.write(new_tests)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import re
|
||||
import os
|
||||
import pickle
|
||||
|
||||
|
||||
def filter_out_failed_test_timing(test_result, timing_result):
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ def generate_tests(
|
|||
):
|
||||
# TODO: Sometimes this recreates the original Class definition. This overrides and messes up the original
|
||||
# class import. Remove the recreation of the class definition
|
||||
print("Generating new tests...")
|
||||
generated_test_source = regression_tests_from_function(
|
||||
function_to_test=source_code_being_tested,
|
||||
function_name=function_name,
|
||||
|
|
@ -45,10 +46,10 @@ def generate_tests(
|
|||
)
|
||||
print("INSPIRED TESTS GENERATED\n", inspired_unit_tests)
|
||||
|
||||
unified_test_file = merge_unit_tests(unit_test_source, inspired_unit_tests, test_framework)
|
||||
unified_test_file = merge_unit_tests(generated_test_source, inspired_unit_tests, test_framework)
|
||||
|
||||
module_node = ast.parse(generated_test_source)
|
||||
print("REGRESSION TESTS SOURCE GENERATED", generated_test_source)
|
||||
module_node = ast.parse(unified_test_file)
|
||||
print("REGRESSION TESTS SOURCE GENERATED", unified_test_file)
|
||||
auxiliary_function_names = [definition[0] for definition in function_dependencies]
|
||||
new_module_node = InjectPerfAndLogging(
|
||||
function_name,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ authors = ["afik.cohen <afik@tacit.plus>", "Saurabh Misra <saurabh@tacit.plus>"]
|
|||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.11"
|
||||
python = ">=3.8, < 3.12"
|
||||
openai = "^0.28.1"
|
||||
unidiff = "^0.7.5"
|
||||
pytest = "^7.3.1"
|
||||
|
|
@ -15,9 +15,9 @@ libcst = "^1.1.0"
|
|||
jedi = "^0.19.0"
|
||||
tiktoken = "^0.5.1"
|
||||
timeout-decorator = "^0.5.0"
|
||||
pytest-timeout = "^2.1.0"
|
||||
astunparse-fixed = {version = "^1.7.0", optional = true, python = ">=3.8.0,<3.9"}
|
||||
tomli = {version = "^2.0.1" , optional = true, python = "<3.11"}
|
||||
numpy = "1.26.1"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
ipython = "^8.12.0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue