testgenie-py 0.2.1__py3-none-any.whl → 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- testgen/analyzer/random_feedback_analyzer.py +344 -114
- testgen/controller/cli_controller.py +5 -10
- testgen/generated_samplecodebin.py +545 -0
- testgen/generator/code_generator.py +36 -18
- testgen/reinforcement/environment.py +1 -1
- testgen/service/generator_service.py +16 -1
- testgen/service/service.py +124 -32
- testgen/sqlite/db_service.py +22 -2
- testgen/util/coverage_utils.py +35 -0
- testgen/util/randomizer.py +29 -12
- {testgenie_py-0.2.1.dist-info → testgenie_py-0.2.2.dist-info}/METADATA +2 -1
- {testgenie_py-0.2.1.dist-info → testgenie_py-0.2.2.dist-info}/RECORD +14 -28
- testgen/.coverage +0 -0
- testgen/code_to_test/__init__.py +0 -0
- testgen/code_to_test/boolean.py +0 -146
- testgen/code_to_test/calculator.py +0 -29
- testgen/code_to_test/code_to_fuzz.py +0 -234
- testgen/code_to_test/code_to_fuzz_lite.py +0 -397
- testgen/code_to_test/decisions.py +0 -57
- testgen/code_to_test/math_utils.py +0 -47
- testgen/code_to_test/no_types.py +0 -35
- testgen/code_to_test/sample_code_bin.py +0 -141
- testgen/q_table/global_q_table.json +0 -1
- testgen/testgen.db +0 -0
- testgen/tests/__init__.py +0 -0
- testgen/tests/test_boolean.py +0 -69
- testgen/tests/test_decisions.py +0 -195
- {testgenie_py-0.2.1.dist-info → testgenie_py-0.2.2.dist-info}/WHEEL +0 -0
- {testgenie_py-0.2.1.dist-info → testgenie_py-0.2.2.dist-info}/entry_points.txt +0 -0
testgen/service/service.py
CHANGED
@@ -1,12 +1,18 @@
|
|
1
|
+
import doctest
|
2
|
+
import importlib
|
1
3
|
import inspect
|
2
4
|
import json
|
3
5
|
import os
|
4
6
|
import re
|
5
7
|
import sqlite3
|
8
|
+
import sys
|
6
9
|
import time
|
7
10
|
import subprocess
|
11
|
+
import testgen.util.coverage_utils as coverage_utils
|
8
12
|
from types import ModuleType
|
9
13
|
from typing import List
|
14
|
+
|
15
|
+
import testgen
|
10
16
|
import testgen.util.file_utils as file_utils
|
11
17
|
|
12
18
|
from testgen.models.test_case import TestCase
|
@@ -50,11 +56,6 @@ class Service:
|
|
50
56
|
# Create a dummy DB service that doesn't do anything
|
51
57
|
self.db_service = None
|
52
58
|
|
53
|
-
def select_all_from_db(self) -> None:
|
54
|
-
rows = self.db_service.get_test_suites()
|
55
|
-
for row in rows:
|
56
|
-
print(repr(dict(row)))
|
57
|
-
|
58
59
|
def generate_test_cases(self) -> List[TestCase] | None:
|
59
60
|
module = file_utils.load_module(self.file_path)
|
60
61
|
class_name = self.analysis_service.get_class_name(module)
|
@@ -155,36 +156,22 @@ class Service:
|
|
155
156
|
|
156
157
|
try:
|
157
158
|
if self.test_format == UNITTEST_FORMAT:
|
158
|
-
|
159
|
-
result = subprocess.run(
|
160
|
-
["python", "-m", "coverage", "report", file_path_to_use],
|
161
|
-
check=True,
|
162
|
-
capture_output=True,
|
163
|
-
text=True
|
164
|
-
)
|
165
|
-
coverage_output = result.stdout
|
159
|
+
self.execute_and_store_unittest(file_path_to_use, test_file)
|
166
160
|
elif self.test_format == PYTEST_FORMAT:
|
167
|
-
|
168
|
-
result = subprocess.run(
|
169
|
-
["python", "-m", "coverage", "report", file_path_to_use],
|
170
|
-
check=True,
|
171
|
-
capture_output=True,
|
172
|
-
text=True
|
173
|
-
)
|
174
|
-
coverage_output = result.stdout
|
161
|
+
self.execute_and_store_pytest(test_file)
|
175
162
|
elif self.test_format == DOCTEST_FORMAT:
|
176
|
-
|
177
|
-
["python", "-m", "coverage", "run", "--source=.", "-m", "doctest", "-v", test_file],
|
178
|
-
check=True,
|
179
|
-
capture_output=True,
|
180
|
-
text=True
|
181
|
-
)
|
182
|
-
coverage_output = result.stdout
|
163
|
+
self.execute_and_store_doctest(test_file)
|
183
164
|
else:
|
184
|
-
raise ValueError("Unsupported test format for
|
185
|
-
|
165
|
+
raise ValueError("Unsupported test format for test results.")
|
166
|
+
|
167
|
+
#Run coverage analysis
|
168
|
+
subprocess.run(["python", "-m", "coverage", "run", "--source=.", test_file], check=True)
|
169
|
+
result = subprocess.run(["python", "-m", "coverage", "report", file_path_to_use], check=True, capture_output=True, text=True)
|
186
170
|
self._save_coverage_data(coverage_output, file_path_to_use)
|
187
|
-
|
171
|
+
coverage_output = result.stdout
|
172
|
+
|
173
|
+
self._save_coverage_data(coverage_output, file_path_to_use)
|
174
|
+
|
188
175
|
except subprocess.CalledProcessError as e:
|
189
176
|
raise RuntimeError(f"Error running coverage subprocess: {e}")
|
190
177
|
|
@@ -426,4 +413,109 @@ class Service:
|
|
426
413
|
|
427
414
|
def debug(self, message: str):
|
428
415
|
if self.debug_mode:
|
429
|
-
self.logger.debug(message)
|
416
|
+
self.logger.debug(message)
|
417
|
+
|
418
|
+
def _get_test_case_id(self, test_case_name: str) -> int:
|
419
|
+
"""
|
420
|
+
Retrieve the test case ID from the database based on the test case name.
|
421
|
+
Insert the test case if it does not exist.
|
422
|
+
"""
|
423
|
+
if self.db_service is None:
|
424
|
+
raise RuntimeError("Database service is not initialized.")
|
425
|
+
|
426
|
+
# Query the database for the test case ID
|
427
|
+
self.db_service.cursor.execute(
|
428
|
+
"SELECT id FROM TestCase WHERE name = ?",
|
429
|
+
(test_case_name,)
|
430
|
+
)
|
431
|
+
result = self.db_service.cursor.fetchone()
|
432
|
+
|
433
|
+
if result:
|
434
|
+
return result[0] # Return the test case ID
|
435
|
+
else:
|
436
|
+
# Insert the test case into the database
|
437
|
+
self.db_service.cursor.execute(
|
438
|
+
"INSERT INTO TestCase (name) VALUES (?)",
|
439
|
+
(test_case_name,)
|
440
|
+
)
|
441
|
+
self.db_service.conn.commit()
|
442
|
+
return self.db_service.cursor.lastrowid
|
443
|
+
|
444
|
+
def execute_and_store_pytest(self, test_file):
|
445
|
+
import pytest
|
446
|
+
from _pytest.reports import TestReport
|
447
|
+
|
448
|
+
class PytestResultPlugin:
|
449
|
+
def __init__(self, db_service, get_test_case_id):
|
450
|
+
self.db_service = db_service
|
451
|
+
self.get_test_case_id = get_test_case_id
|
452
|
+
|
453
|
+
def pytest_runtest_logreport(self, report: TestReport):
|
454
|
+
if report.when == "call":
|
455
|
+
test_case_id = self.get_test_case_id(report.nodeid)
|
456
|
+
status = report.outcome == "passed"
|
457
|
+
error_message = report.longreprtext if report.outcome == "failed" else None
|
458
|
+
self.db_service.insert_test_result(test_case_id, status, error_message)
|
459
|
+
|
460
|
+
pytest.main([test_file], plugins=[PytestResultPlugin(self.db_service, self._get_test_case_id)])
|
461
|
+
|
462
|
+
pytest.main([test_file])
|
463
|
+
|
464
|
+
def execute_and_store_unittest(self, file_path_to_use, test_file):
|
465
|
+
import unittest
|
466
|
+
loader = unittest.TestLoader()
|
467
|
+
print(f"Discovering tests in: {os.path.dirname(file_path_to_use)} with pattern: {os.path.basename(test_file)}")
|
468
|
+
test_module = os.path.relpath(test_file,
|
469
|
+
start=os.getcwd()) # Get relative path from the current working directory
|
470
|
+
test_module = test_module.replace("/", ".").replace("\\", ".").rstrip(".py") # Convert to module name
|
471
|
+
if test_module.startswith("."):
|
472
|
+
test_module = test_module[1:] # Remove leading dot if present
|
473
|
+
print(f"Test module: {test_module}")
|
474
|
+
suite = loader.loadTestsFromName(test_module)
|
475
|
+
runner = unittest.TextTestRunner()
|
476
|
+
result = runner.run(suite)
|
477
|
+
|
478
|
+
for test_case, traceback in result.failures + result.errors:
|
479
|
+
test_case_id = self._get_test_case_id(str(test_case))
|
480
|
+
self.db_service.insert_test_result(test_case_id, status=False, error=traceback)
|
481
|
+
|
482
|
+
successful_tests = set(str(test) for test in suite) - set(
|
483
|
+
str(test) for test, _ in result.failures + result.errors)
|
484
|
+
for test_case in successful_tests:
|
485
|
+
test_case_id = self._get_test_case_id(str(test_case))
|
486
|
+
self.db_service.insert_test_result(test_case_id, status=True, error=None)
|
487
|
+
|
488
|
+
def execute_and_store_doctest(self, test_file):
|
489
|
+
module_name = os.path.splitext(os.path.basename(test_file))[0]
|
490
|
+
spec = importlib.util.spec_from_file_location(module_name, test_file)
|
491
|
+
module = importlib.util.module_from_spec(spec)
|
492
|
+
sys.modules[module_name] = module
|
493
|
+
spec.loader.exec_module(module)
|
494
|
+
|
495
|
+
# Now run doctests on the loaded module
|
496
|
+
result = doctest.testmod(module)
|
497
|
+
|
498
|
+
test_case_id = self._get_test_case_id(test_file)
|
499
|
+
status = result.failed == 0
|
500
|
+
error_message = f"{result.failed} of {result.attempted} tests failed" if result.failed > 0 else None
|
501
|
+
self.db_service.insert_test_result(test_case_id, status, error_message)
|
502
|
+
|
503
|
+
def query_test_file_data(self, test_file_name: str):
|
504
|
+
if self.db_service is None:
|
505
|
+
raise RuntimeError("Database service is not initialized.")
|
506
|
+
|
507
|
+
results = self.db_service.get_test_file_data(test_file_name)
|
508
|
+
if not results:
|
509
|
+
print(f"No data found for file: {test_file_name}")
|
510
|
+
return
|
511
|
+
|
512
|
+
from tabulate import tabulate
|
513
|
+
rows = [dict(row) for row in results]
|
514
|
+
|
515
|
+
print(f"Results for file: {test_file_name}")
|
516
|
+
print(tabulate(rows, headers="keys", tablefmt="grid"))
|
517
|
+
|
518
|
+
def select_all_from_db(self) -> None:
|
519
|
+
rows = self.db_service.get_test_suites()
|
520
|
+
for row in rows:
|
521
|
+
print(repr(dict(row)))
|
testgen/sqlite/db_service.py
CHANGED
@@ -11,7 +11,6 @@ from testgen.sqlite.db import create_database
|
|
11
11
|
|
12
12
|
class DBService:
|
13
13
|
def __init__(self, db_name="testgen.db"):
|
14
|
-
"""Initialize database service with connection to specified database."""
|
15
14
|
self.db_name = db_name
|
16
15
|
self.conn = None
|
17
16
|
self.cursor = None
|
@@ -111,7 +110,7 @@ class DBService:
|
|
111
110
|
self.conn.commit()
|
112
111
|
return self.cursor.lastrowid
|
113
112
|
|
114
|
-
def insert_coverage_data(self, file_name: str, executed_lines:
|
113
|
+
def insert_coverage_data(self, file_name: str, executed_lines: str, missed_lines: str,
|
115
114
|
branch_coverage: float, source_file_id: int) -> int:
|
116
115
|
"""Insert coverage data and return its ID."""
|
117
116
|
self.cursor.execute(
|
@@ -217,3 +216,24 @@ class DBService:
|
|
217
216
|
(file_path,)
|
218
217
|
)
|
219
218
|
return self.cursor.fetchall()
|
219
|
+
|
220
|
+
def get_test_file_data(self, file_path: str):
|
221
|
+
"""
|
222
|
+
Retrieve all test cases, coverage data, and test results for a specific file.
|
223
|
+
"""
|
224
|
+
query = """
|
225
|
+
SELECT
|
226
|
+
tc.id AS test_case_id,
|
227
|
+
tc.name AS test_case_name,
|
228
|
+
tc.test_function AS test_case_test_function,
|
229
|
+
tc.test_method_type AS test_case_method_type,
|
230
|
+
COALESCE(cd.missed_lines, 'None') AS coverage_data_missed_lines
|
231
|
+
FROM SourceFile sf
|
232
|
+
LEFT JOIN Function f ON sf.id = f.source_file_id
|
233
|
+
LEFT JOIN TestCase tc ON f.id = tc.function_id
|
234
|
+
LEFT JOIN TestResult tr ON tc.id = tr.test_case_id
|
235
|
+
LEFT JOIN CoverageData cd ON sf.id = cd.source_file_id
|
236
|
+
WHERE sf.path = ?;
|
237
|
+
"""
|
238
|
+
self.cursor.execute(query, (file_path,))
|
239
|
+
return self.cursor.fetchall()
|
testgen/util/coverage_utils.py
CHANGED
@@ -3,6 +3,8 @@ from typing import List
|
|
3
3
|
|
4
4
|
import coverage
|
5
5
|
|
6
|
+
from testgen.models.analysis_context import AnalysisContext
|
7
|
+
from testgen.models.function_metadata import FunctionMetadata
|
6
8
|
from testgen.models.test_case import TestCase
|
7
9
|
from testgen.util.file_utils import load_and_parse_file_for_tree, load_module
|
8
10
|
from testgen.util.utils import get_function_boundaries
|
@@ -193,3 +195,36 @@ def get_uncovered_lines_for_func(file_name: str, class_name: str | None, func_no
|
|
193
195
|
uncovered_branch_lines.append(line)
|
194
196
|
|
195
197
|
return uncovered_branch_lines
|
198
|
+
|
199
|
+
def get_all_executable_statements(analysis_context: AnalysisContext, func: FunctionMetadata, test_cases):
|
200
|
+
import ast
|
201
|
+
|
202
|
+
if not test_cases:
|
203
|
+
print("Warning: No test cases available to determine executable statements")
|
204
|
+
else:
|
205
|
+
analysis = get_coverage_analysis(analysis_context.filepath, analysis_context.class_name, func.function_name, test_cases[0].inputs)
|
206
|
+
|
207
|
+
executable_lines = list(analysis[1])
|
208
|
+
|
209
|
+
with open(analysis_context.filepath, 'r') as f:
|
210
|
+
source = f.read()
|
211
|
+
|
212
|
+
tree = ast.parse(source)
|
213
|
+
|
214
|
+
for node in ast.walk(tree):
|
215
|
+
if isinstance(node, ast.FunctionDef) and node.name == func.func_def.name:
|
216
|
+
for if_node in ast.walk(node):
|
217
|
+
if isinstance(if_node, ast.If) and if_node.orelse:
|
218
|
+
if isinstance(if_node.orelse[0], ast.If):
|
219
|
+
continue
|
220
|
+
else_line = if_node.orelse[0].lineno - 1
|
221
|
+
|
222
|
+
with open(analysis_context.filepath, 'r') as f:
|
223
|
+
lines = f.readlines()
|
224
|
+
if else_line <= len(lines):
|
225
|
+
line_content = lines[else_line - 1].strip()
|
226
|
+
if line_content == "else:":
|
227
|
+
if else_line not in executable_lines:
|
228
|
+
executable_lines.append(else_line)
|
229
|
+
|
230
|
+
return sorted(executable_lines)
|
testgen/util/randomizer.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import ast
|
2
2
|
import random
|
3
3
|
import string
|
4
|
+
from types import ModuleType
|
4
5
|
from typing import List
|
5
6
|
|
6
7
|
import testgen.util.coverage_utils
|
@@ -67,22 +68,38 @@ def new_random_test_case(file_name: str, class_name: str | None, func_node: ast.
|
|
67
68
|
print(f"Error generating test case for {func_name}: {e}")
|
68
69
|
raise
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
71
|
+
def combine_cases(module: ModuleType, test_cases: List[TestCase]) -> TestCase:
|
72
|
+
"""Combine two test cases by mixing their inputs and calculating the new expected output."""
|
73
|
+
if not test_cases:
|
74
|
+
raise ValueError("Cannot combine cases with empty test case list")
|
75
|
+
|
74
76
|
random_index1 = random.randint(0, len(test_cases) - 1)
|
75
77
|
test_case1 = test_cases[random_index1]
|
76
|
-
|
78
|
+
|
77
79
|
test_cases_of_the_same_function = [tc for tc in test_cases if tc.func_name == test_case1.func_name]
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
80
|
+
if len(test_cases_of_the_same_function) <= 1:
|
81
|
+
return test_case1 # Not enough cases to combine
|
82
|
+
|
83
|
+
filtered_cases = [tc for tc in test_cases_of_the_same_function if tc != test_case1]
|
84
|
+
if not filtered_cases:
|
85
|
+
random_index2 = random.randint(0, len(test_cases_of_the_same_function) - 1)
|
86
|
+
test_case2 = test_cases_of_the_same_function[random_index2]
|
87
|
+
else:
|
88
|
+
test_case2 = random.choice(filtered_cases)
|
89
|
+
|
82
90
|
mixed_inputs = mix_inputs(test_case1, test_case2)
|
83
|
-
|
84
|
-
|
85
|
-
|
91
|
+
|
92
|
+
try:
|
93
|
+
|
94
|
+
func = getattr(module, test_case1.func_name)
|
95
|
+
|
96
|
+
new_expected = func(*mixed_inputs)
|
97
|
+
|
98
|
+
return TestCase(test_case1.func_name, mixed_inputs, new_expected)
|
99
|
+
|
100
|
+
except Exception as e:
|
101
|
+
print(f"Error calculating expected output for combined test case: {e}")
|
102
|
+
return test_case1 if random.choice([True, False]) else test_case2
|
86
103
|
|
87
104
|
def remove_case(test_cases: List[TestCase]) -> List[TestCase]:
|
88
105
|
random_index = random.randint(0, len(test_cases) - 1)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: testgenie-py
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.2
|
4
4
|
Summary:
|
5
5
|
Author: cjseitz
|
6
6
|
Author-email: charlesjseitz@gmail.com
|
@@ -19,6 +19,7 @@ Requires-Dist: klara (==0.6.3)
|
|
19
19
|
Requires-Dist: pygraphviz (>=1.14,<2.0)
|
20
20
|
Requires-Dist: pytest (>=8.3.5,<9.0.0)
|
21
21
|
Requires-Dist: staticfg (>=0.9.5,<0.10.0)
|
22
|
+
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
22
23
|
Requires-Dist: typed-ast (==1.5.5)
|
23
24
|
Requires-Dist: z3-solver (==4.13.3.0)
|
24
25
|
Description-Content-Type: text/markdown
|
@@ -1,4 +1,3 @@
|
|
1
|
-
testgen/.coverage,sha256=NvtMmi3OL9j4U8zNqffRWADmGX-9ygDEiHlCgjhbRjk,69632
|
2
1
|
testgen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
2
|
testgen/analyzer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
3
|
testgen/analyzer/ast_analyzer.py,sha256=JmqiosxgZJm2fhNDr5VUBpKKHmf8S2HP9Jm0Xl7NnnI,6783
|
@@ -7,25 +6,17 @@ testgen/analyzer/contracts/contract.py,sha256=6rNYJOy_2GrOhGtaXTDIOX6pTEOqo856Fx
|
|
7
6
|
testgen/analyzer/contracts/no_exception_contract.py,sha256=rTWTuu5XKmvzBPD6yNAqiNehk9lbWn_Z8zFj-_djZ_w,512
|
8
7
|
testgen/analyzer/contracts/nonnull_contract.py,sha256=uurnrVptImYTVpSnu8ckdlU6c94AbiOWFoH1YnAQU0w,508
|
9
8
|
testgen/analyzer/fuzz_analyzer.py,sha256=ktkDdh3mgHjcC4ZitGo9fa9RjnGqkdehaYJeSKssWss,4299
|
10
|
-
testgen/analyzer/random_feedback_analyzer.py,sha256=
|
9
|
+
testgen/analyzer/random_feedback_analyzer.py,sha256=TCF4rBEU22YtBMBefNfuKNJRjHo5U-a6Qn-mEr1bH10,23959
|
11
10
|
testgen/analyzer/reinforcement_analyzer.py,sha256=U6W7g-xDFS_P0aqxjPRnaXjGp2gOC9TMdfWaetFV7eE,3568
|
12
11
|
testgen/analyzer/test_case_analyzer.py,sha256=foHRbz9K6WAn711sXbp-smJHDjI8GTG8F2TpovLZVEo,1530
|
13
12
|
testgen/analyzer/test_case_analyzer_context.py,sha256=7umDPHBjoTaCRvZOdNynpnWsr14Gy0E2hpMBPK8mz3Q,2128
|
14
|
-
testgen/code_to_test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
-
testgen/code_to_test/boolean.py,sha256=RM2byJDKFTx1FFrxnPG_uZWb24OcOH20Uh-D1Z-yPcE,3373
|
16
|
-
testgen/code_to_test/calculator.py,sha256=j7lw21BYg_vxaQVCrjOlhQOpObjSe5gu9xzthmdGphk,830
|
17
|
-
testgen/code_to_test/code_to_fuzz.py,sha256=cwgRpUdXjTlrUHSHMtA2TAj8Y-ddAn6CaUdXPM4MRmo,4826
|
18
|
-
testgen/code_to_test/code_to_fuzz_lite.py,sha256=EjS4GB5klnJrvZIDDpS9iIt0iZETVJI0ez9DmihMiYc,10429
|
19
|
-
testgen/code_to_test/decisions.py,sha256=ZiW-EF1yTOWeQVZ7Xh0oIPHK2NSNPUzVxCY0E2GbYvQ,1376
|
20
|
-
testgen/code_to_test/math_utils.py,sha256=FqPQz5-e1oklzGyTVYNO8JMKDg5ob8z05VOlpKfKvvw,853
|
21
|
-
testgen/code_to_test/no_types.py,sha256=kD8CGjVAxVeCjQC45abO773sRNIjiZ4jvhwPRV8-kt0,675
|
22
|
-
testgen/code_to_test/sample_code_bin.py,sha256=kMvV_-oFeAkxUmDx41Pw0iTTmMG1pvX31TezXPWMOkE,4225
|
23
13
|
testgen/controller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
-
testgen/controller/cli_controller.py,sha256=
|
14
|
+
testgen/controller/cli_controller.py,sha256=7zDm0hPcTLQXap8Sw_s9SPYcbY0nbfvP1wW8zUqdv-8,8783
|
25
15
|
testgen/controller/docker_controller.py,sha256=LK3aV-n_J0YMRRcWNNinz-Z0FrKo-4qzEIYZSFht0Yc,8687
|
26
16
|
testgen/docker/Dockerfile,sha256=6mutzP0ZkVueuvMLCOy2bsyGxWjLHU-cq7RFkuC8r5Y,781
|
17
|
+
testgen/generated_samplecodebin.py,sha256=pf_aYtcfpjZzgiZ_FiBOxfug_ii3dRX0jnozBgQm7Xw,17030
|
27
18
|
testgen/generator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
-
testgen/generator/code_generator.py,sha256
|
19
|
+
testgen/generator/code_generator.py,sha256=-Nh5Jt4my29YWA_LKWn98I4jvDA-fNi6AGuw-vJhRV0,3171
|
29
20
|
testgen/generator/doctest_generator.py,sha256=Dkaf2l72ENk1mqNP3WkOnIY-iqrTHh-443AWtxzRWGY,8806
|
30
21
|
testgen/generator/generator.py,sha256=9M9zg8DO0uU5W5s9hsz2oPCL7bz7sAD087M5TYottSs,2007
|
31
22
|
testgen/generator/pytest_generator.py,sha256=ZjQKPHlizFK2yx9WabAxkW9sM-xa64d08IIQibnvwuk,3369
|
@@ -41,33 +32,28 @@ testgen/models/generator_context.py,sha256=V-T9i-3Ar-gdBzQqidyqBb05PTmOu2LtdQdAI
|
|
41
32
|
testgen/models/test_case.py,sha256=jwodn-6fKHCh4SO2qycbrFyggCb9UlwTZ8k3RdTObDQ,216
|
42
33
|
testgen/presentation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
34
|
testgen/presentation/cli_view.py,sha256=2fZrsvZ-Wi4j37UvogsK9_yQV5o3A20jowIr6iFRu-s,296
|
44
|
-
testgen/q_table/global_q_table.json,sha256=xSMRf5ddtLJAogE_RXleAbkmujgAYU3uiblBJmKqc5w,12059
|
45
35
|
testgen/reinforcement/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
46
36
|
testgen/reinforcement/abstract_state.py,sha256=M9Kp8fyJzsTzpyL3ca4HjjYpGXy9DRMw-IG7OgFVisY,154
|
47
37
|
testgen/reinforcement/agent.py,sha256=wvgbi-OVoVJMwhasGgsP2y1TKLiC5qjjTwZBNqKNRns,6098
|
48
|
-
testgen/reinforcement/environment.py,sha256=
|
38
|
+
testgen/reinforcement/environment.py,sha256=gW-Chh_c31AXlYR5GjTKybg4iNWSuZLeujB6Q7TdKPI,10838
|
49
39
|
testgen/reinforcement/statement_coverage_state.py,sha256=mTZ0uiFnyiIoHcQXlJv9FDSH4y1r3rxltYEdZcMaSSg,1552
|
50
40
|
testgen/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
51
41
|
testgen/service/analysis_service.py,sha256=LPvsb6XwFQIOn05niamDiJx_HqCyTX2UznREvKjfvWo,10973
|
52
42
|
testgen/service/cfg_service.py,sha256=ejgwbFlwla9Mfy4OJ-hsLAxo0TV3jO06hkldeEU-akQ,2236
|
53
|
-
testgen/service/generator_service.py,sha256=
|
43
|
+
testgen/service/generator_service.py,sha256=rDwE1mGQdshr_yaDANcCPtgKhcx5sDWxQi8myxkOKhk,8088
|
54
44
|
testgen/service/logging_service.py,sha256=vEQsluxwO-dAxWY4Xkwt8v5XeaXEv3GZh3ZYAsFCOEs,3116
|
55
|
-
testgen/service/service.py,sha256=
|
45
|
+
testgen/service/service.py,sha256=aT6F8TxxBNLX8LIK3bVPvnohts2ssLkrr3dz-RK0L_c,20994
|
56
46
|
testgen/sqlite/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
47
|
testgen/sqlite/db.py,sha256=RUt88ndT4CQRo9aZzLGXPHRK1iw0LyDEGnoWlOLzKGM,2390
|
58
|
-
testgen/sqlite/db_service.py,sha256=
|
59
|
-
testgen/testgen.db,sha256=iyQiDqur-JoS70QD-VYkJFkgjb_YcK2jBAP2aZvvAhY,106496
|
60
|
-
testgen/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
61
|
-
testgen/tests/test_boolean.py,sha256=WzZPPdTLoWHEMnqopimm0g-lbJCp1ExlK_w6KN3Si1s,1636
|
62
|
-
testgen/tests/test_decisions.py,sha256=NF3sTscRMHHTsaV0NzwNsQ4zW2WkPyyTp1C1Sw3rNbQ,4437
|
48
|
+
testgen/sqlite/db_service.py,sha256=F2ug_FBrYOQtJwM2cMkvQrTS54_VhWGDAHXndnTi-c8,9768
|
63
49
|
testgen/tree/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
50
|
testgen/tree/node.py,sha256=ONJtbACShN4yNj1X-UslFRgLyBP6mrbg7qZr3c6dWyA,165
|
65
51
|
testgen/tree/tree_utils.py,sha256=gT7jucky6_GWVOlDI6jpv6RMeWCkntGOHIYLvHxD85k,2122
|
66
52
|
testgen/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
67
|
-
testgen/util/coverage_utils.py,sha256=
|
53
|
+
testgen/util/coverage_utils.py,sha256=xKaFpgLEZLAgDWzugxJPKVwfd0nYZnP5oHLnFzYuRPE,9084
|
68
54
|
testgen/util/coverage_visualizer.py,sha256=Jp9d7SJaGKD38g4GWSOI4TusXtMYgMgQNPGrUnuVynk,5704
|
69
55
|
testgen/util/file_utils.py,sha256=IO239ZQB2DoZN1URrFlPq0fv73Xn5wQUQVEWk7g4gl4,7066
|
70
|
-
testgen/util/randomizer.py,sha256=
|
56
|
+
testgen/util/randomizer.py,sha256=1WTPjCjgQxfHw9UPhvjRWJCKtcE3gCG4nmLn7HJtrac,5767
|
71
57
|
testgen/util/utils.py,sha256=_TPXveAcI_TR9XLU8qaDx63CrZJDvpzSWl_gfYchJz0,5665
|
72
58
|
testgen/util/z3_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
73
59
|
testgen/util/z3_utils/ast_to_z3.py,sha256=V87cvlH2OlO7_owuVTqygymMmK_FyesBovi6qe-BUcg,3180
|
@@ -75,7 +61,7 @@ testgen/util/z3_utils/branch_condition.py,sha256=N9FNR-iJmxIC62NpDQNVZ1OP14rXXqY
|
|
75
61
|
testgen/util/z3_utils/constraint_extractor.py,sha256=RXJLpmk6dAvHZ27839VXKXNtdy9St1F-17-pSEFu4bM,1285
|
76
62
|
testgen/util/z3_utils/variable_finder.py,sha256=dUh3F9_L_BDMz1ybiGss09LLcM_egbitgj0FT5Nh9u4,245
|
77
63
|
testgen/util/z3_utils/z3_test_case.py,sha256=yF4oJOrXMLzOwDUqXdoeg83MOTl3pvc_lYaZcS01CuQ,4983
|
78
|
-
testgenie_py-0.2.
|
79
|
-
testgenie_py-0.2.
|
80
|
-
testgenie_py-0.2.
|
81
|
-
testgenie_py-0.2.
|
64
|
+
testgenie_py-0.2.2.dist-info/METADATA,sha256=gqB_l7Y9ELHsTmydKcJDaTeVKbEmgNltEhL7Si0Ll18,885
|
65
|
+
testgenie_py-0.2.2.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
66
|
+
testgenie_py-0.2.2.dist-info/entry_points.txt,sha256=OUN4GqB4zHlHWwWGjwIPbur4E_ZqQgkeeqaCLhzRZgg,47
|
67
|
+
testgenie_py-0.2.2.dist-info/RECORD,,
|
testgen/.coverage
DELETED
Binary file
|
testgen/code_to_test/__init__.py
DELETED
File without changes
|
testgen/code_to_test/boolean.py
DELETED
@@ -1,146 +0,0 @@
|
|
1
|
-
from typing import List
|
2
|
-
|
3
|
-
|
4
|
-
def bin_and(a: bool, b: bool) ->bool:
|
5
|
-
"""
|
6
|
-
>>> bin_and(True, False)
|
7
|
-
False
|
8
|
-
|
9
|
-
>>> bin_and(False, True)
|
10
|
-
False
|
11
|
-
|
12
|
-
>>> bin_and(False, False)
|
13
|
-
False
|
14
|
-
|
15
|
-
>>> bin_and(True, True)
|
16
|
-
True
|
17
|
-
"""
|
18
|
-
if a == True:
|
19
|
-
if b == True:
|
20
|
-
return True
|
21
|
-
else:
|
22
|
-
return False
|
23
|
-
else:
|
24
|
-
return False
|
25
|
-
|
26
|
-
|
27
|
-
def bin_xor(a: bool, b: bool) ->bool:
|
28
|
-
"""
|
29
|
-
>>> bin_xor(True, True)
|
30
|
-
False
|
31
|
-
|
32
|
-
>>> bin_xor(True, False)
|
33
|
-
True
|
34
|
-
|
35
|
-
>>> bin_xor(False, False)
|
36
|
-
False
|
37
|
-
|
38
|
-
>>> bin_xor(False, True)
|
39
|
-
True
|
40
|
-
"""
|
41
|
-
if a == True:
|
42
|
-
if b == True:
|
43
|
-
return False
|
44
|
-
else:
|
45
|
-
return True
|
46
|
-
elif b == True:
|
47
|
-
return True
|
48
|
-
else:
|
49
|
-
return False
|
50
|
-
|
51
|
-
|
52
|
-
def status_flags(active: bool, verified: bool, admin: bool) ->str:
|
53
|
-
"""
|
54
|
-
>>> status_flags(False, False, False)
|
55
|
-
'inactive'
|
56
|
-
|
57
|
-
>>> status_flags(False, False, True)
|
58
|
-
'admin-unverified'
|
59
|
-
|
60
|
-
>>> status_flags(True, True, False)
|
61
|
-
'user-verified'
|
62
|
-
|
63
|
-
>>> status_flags(True, True, True)
|
64
|
-
'admin-verified'
|
65
|
-
|
66
|
-
>>> status_flags(True, False, False)
|
67
|
-
'user-unverified'
|
68
|
-
|
69
|
-
>>> status_flags(False, True, True)
|
70
|
-
'admin-verified'
|
71
|
-
|
72
|
-
>>> status_flags(False, True, False)
|
73
|
-
'inactive'
|
74
|
-
|
75
|
-
>>> status_flags(True, False, True)
|
76
|
-
'admin-unverified'
|
77
|
-
"""
|
78
|
-
if admin:
|
79
|
-
if verified:
|
80
|
-
return 'admin-verified'
|
81
|
-
else:
|
82
|
-
return 'admin-unverified'
|
83
|
-
elif active:
|
84
|
-
if verified:
|
85
|
-
return 'user-verified'
|
86
|
-
else:
|
87
|
-
return 'user-unverified'
|
88
|
-
else:
|
89
|
-
return 'inactive'
|
90
|
-
|
91
|
-
|
92
|
-
"""def half_adder(a: bool, b: bool) ->tuple:
|
93
|
-
sum: bool = bin_xor(a, b)
|
94
|
-
carry: bool = bin_and(a, b)
|
95
|
-
return sum, carry
|
96
|
-
|
97
|
-
|
98
|
-
def full_adder(a: bool, b: bool, carry_in: bool) ->tuple:
|
99
|
-
sum1, carry = half_adder(a, b)
|
100
|
-
sum2, carry_out = half_adder(sum1, carry_in)
|
101
|
-
return sum2, carry or carry_out
|
102
|
-
|
103
|
-
|
104
|
-
def thirty_two_bit_adder_excep(x: int, y: int) ->List[int]:
|
105
|
-
x_bits: List[int] = bit_converter(x)
|
106
|
-
y_bits: List[int] = bit_converter(y)
|
107
|
-
result: List[int] = [0] * 32
|
108
|
-
carry: bool = False
|
109
|
-
for i in range(32):
|
110
|
-
try:
|
111
|
-
sum_bit, carry = full_adder(x_bits[i], y_bits[i], carry)
|
112
|
-
result[i] = sum_bit
|
113
|
-
except IndexError as e:
|
114
|
-
print(f'Index Out of Bounds Error In ThirtyTwoBitAdder: {e}')
|
115
|
-
result = [1] * 32
|
116
|
-
if carry:
|
117
|
-
return OverflowError('Sum exceeds 32 bits')
|
118
|
-
return result
|
119
|
-
|
120
|
-
|
121
|
-
def thirty_two_bit_adder(x: int, y: int) ->List[int]:
|
122
|
-
print(x.bit_length() - 1)
|
123
|
-
print(y.bit_length() - 1)
|
124
|
-
x_bits: List[int] = bit_converter(x)
|
125
|
-
y_bits: List[int] = bit_converter(y)
|
126
|
-
result: List[int] = [0] * 32
|
127
|
-
carry: bool = False
|
128
|
-
for i in range(32):
|
129
|
-
sum_bit, carry = full_adder(x_bits[i], y_bits[i], carry)
|
130
|
-
result[i] = sum_bit
|
131
|
-
return result
|
132
|
-
|
133
|
-
def bit_converter(num: int) ->List[int]:
|
134
|
-
binary_str: str = bin(num)[2:]
|
135
|
-
print(bin(num)[2:])
|
136
|
-
return [int(digit) for digit in binary_str]
|
137
|
-
|
138
|
-
def thirty_two_bit_adder_excep(x: int, y: int) ->List[int]:
|
139
|
-
x_bits: List[int] = bit_converter(x)
|
140
|
-
y_bits: List[int] = bit_converter(y)
|
141
|
-
result: List[int] = [0] * 32
|
142
|
-
carry: bool = False
|
143
|
-
for i in range(32):
|
144
|
-
sum_bit, carry = full_adder(x_bits[i], y_bits[i], carry)
|
145
|
-
result[i] = sum_bit
|
146
|
-
return result"""
|
@@ -1,29 +0,0 @@
|
|
1
|
-
class AdvancedCalculator:
|
2
|
-
|
3
|
-
def evaluate(self, a: int, b: int, op: str) ->(int | float | str):
|
4
|
-
""">>> AdvancedCalculator().evaluate(16, 56, 'abc')
|
5
|
-
'invalid'"""
|
6
|
-
if op == 'add':
|
7
|
-
return a + b
|
8
|
-
elif op == 'sub':
|
9
|
-
return a - b
|
10
|
-
elif op == 'mul':
|
11
|
-
return a * b
|
12
|
-
elif op == 'div':
|
13
|
-
if b == 0:
|
14
|
-
return 'undefined'
|
15
|
-
return a / b
|
16
|
-
else:
|
17
|
-
return 'invalid'
|
18
|
-
|
19
|
-
def is_in_range(self, val: float) ->str:
|
20
|
-
""">>> AdvancedCalculator().is_in_range(0.4023417704905361)
|
21
|
-
'fractional'"""
|
22
|
-
if val < 0.0:
|
23
|
-
return 'below zero'
|
24
|
-
elif 0.0 <= val < 1.0:
|
25
|
-
return 'fractional'
|
26
|
-
elif 1.0 <= val <= 100.0:
|
27
|
-
return 'valid'
|
28
|
-
else:
|
29
|
-
return 'out of range'
|