testgenie-py 0.2.2__py3-none-any.whl → 0.2.4__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.
Files changed (62) hide show
  1. testgen/.coverage +0 -0
  2. testgen/analyzer/ast_analyzer.py +4 -1
  3. testgen/analyzer/fuzz_analyzer.py +2 -2
  4. testgen/analyzer/random_feedback_analyzer.py +3 -3
  5. testgen/analyzer/test_case_analyzer.py +2 -0
  6. testgen/code_to_test/__init__.py +0 -0
  7. testgen/code_to_test/boolean.py +146 -0
  8. testgen/code_to_test/calculator.py +29 -0
  9. testgen/code_to_test/code_to_fuzz.py +234 -0
  10. testgen/code_to_test/code_to_fuzz_lite.py +397 -0
  11. testgen/code_to_test/decisions.py +57 -0
  12. testgen/code_to_test/math_utils.py +47 -0
  13. testgen/code_to_test/sample_code_bin.py +141 -0
  14. testgen/controller/cli_controller.py +0 -1
  15. testgen/generated_boolean.py +48 -0
  16. testgen/reinforcement/agent.py +30 -26
  17. testgen/reinforcement/environment.py +7 -6
  18. testgen/reinforcement/statement_coverage_state.py +5 -3
  19. testgen/service/analysis_service.py +8 -6
  20. testgen/service/cfg_service.py +2 -0
  21. testgen/service/generator_service.py +6 -9
  22. testgen/service/logging_service.py +4 -2
  23. testgen/service/service.py +11 -20
  24. testgen/testgen.db +0 -0
  25. testgen/tests/__init__.py +0 -0
  26. testgen/tests/test_boolean.py +81 -0
  27. testgen/tests/test_generated_boolean.py +83 -0
  28. testgen/util/coverage_visualizer.py +5 -3
  29. testgen/util/file_utils.py +1 -1
  30. testgen/visualize/boolean_bin_and_coverage.png +0 -0
  31. testgen/visualize/boolean_bin_and_coverage_v1.png +0 -0
  32. testgen/visualize/boolean_bin_and_coverage_v2.png +0 -0
  33. testgen/visualize/boolean_bin_and_coverage_v3.png +0 -0
  34. testgen/visualize/boolean_bin_and_coverage_v4.png +0 -0
  35. testgen/visualize/boolean_bin_and_coverage_v5.png +0 -0
  36. testgen/visualize/boolean_bin_and_coverage_v6.png +0 -0
  37. testgen/visualize/boolean_bin_and_coverage_v7.png +0 -0
  38. testgen/visualize/boolean_bin_and_coverage_v8.png +0 -0
  39. testgen/visualize/boolean_bin_xor_coverage.png +0 -0
  40. testgen/visualize/boolean_bin_xor_coverage_v1.png +0 -0
  41. testgen/visualize/boolean_bin_xor_coverage_v2.png +0 -0
  42. testgen/visualize/boolean_bin_xor_coverage_v3.png +0 -0
  43. testgen/visualize/boolean_bin_xor_coverage_v4.png +0 -0
  44. testgen/visualize/boolean_bin_xor_coverage_v5.png +0 -0
  45. testgen/visualize/boolean_bin_xor_coverage_v6.png +0 -0
  46. testgen/visualize/boolean_bin_xor_coverage_v7.png +0 -0
  47. testgen/visualize/boolean_bin_xor_coverage_v8.png +0 -0
  48. testgen/visualize/boolean_status_flags_coverage.png +0 -0
  49. testgen/visualize/boolean_status_flags_coverage_v1.png +0 -0
  50. testgen/visualize/boolean_status_flags_coverage_v2.png +0 -0
  51. testgen/visualize/boolean_status_flags_coverage_v3.png +0 -0
  52. testgen/visualize/boolean_status_flags_coverage_v4.png +0 -0
  53. testgen/visualize/boolean_status_flags_coverage_v5.png +0 -0
  54. testgen/visualize/boolean_status_flags_coverage_v6.png +0 -0
  55. testgen/visualize/boolean_status_flags_coverage_v7.png +0 -0
  56. testgen/visualize/boolean_status_flags_coverage_v8.png +0 -0
  57. testgenie_py-0.2.4.dist-info/METADATA +139 -0
  58. testgenie_py-0.2.4.dist-info/RECORD +108 -0
  59. testgenie_py-0.2.2.dist-info/METADATA +0 -27
  60. testgenie_py-0.2.2.dist-info/RECORD +0 -67
  61. {testgenie_py-0.2.2.dist-info → testgenie_py-0.2.4.dist-info}/WHEEL +0 -0
  62. {testgenie_py-0.2.2.dist-info → testgenie_py-0.2.4.dist-info}/entry_points.txt +0 -0
testgen/.coverage ADDED
Binary file
@@ -8,6 +8,9 @@ from abc import ABC
8
8
  from testgen.models.function_metadata import FunctionMetadata
9
9
 
10
10
  class ASTAnalyzer(TestCaseAnalyzerStrategy, ABC):
11
+ def __init__(self, analysis_context=None):
12
+ super().__init__(analysis_context)
13
+
11
14
  def collect_test_cases(self, function_metadata: FunctionMetadata) -> List[TestCase]:
12
15
  """Collect test cases by analyzing AST conditions and return statements"""
13
16
 
@@ -34,7 +37,7 @@ class ASTAnalyzer(TestCaseAnalyzerStrategy, ABC):
34
37
  for node in func_node_body:
35
38
  if isinstance(node, ast.If):
36
39
  condition_str = self.parse_condition(node.test)
37
- print(f"Condition found in function: {condition_str}")
40
+ self.logger.debug(f"Condition found in function: {condition_str}")
38
41
  self.get_conditions_recursively(function_metadata, func_name, node.body, param_names, test_cases, conditions + [condition_str])
39
42
  if node.orelse:
40
43
  self.get_conditions_recursively(function_metadata, func_name, node.orelse, param_names, test_cases, conditions)
@@ -61,8 +61,8 @@ class FuzzAnalyzer(TestCaseAnalyzerStrategy, ABC):
61
61
  covered_branches = self.get_branch_coverage(module)
62
62
  covered_branches_tuple = tuple(covered_branches)
63
63
 
64
- print(f"[COVERED_BRANCHES]: {covered_branches}")
65
- print(f"[EXECUTED BRANCHES]: {self.executed_branches}")
64
+ self.logger.debug(f"[COVERED_BRANCHES]: {covered_branches}")
65
+ self.logger.debug(f"[EXECUTED BRANCHES]: {self.executed_branches}")
66
66
 
67
67
  for branch in covered_branches:
68
68
  if branch[1] < 0:
@@ -74,7 +74,7 @@ class RandomFeedbackAnalyzer(TestCaseAnalyzerStrategy, ABC):
74
74
  break
75
75
  else:
76
76
  # Optionally log duplicate detection
77
- print(f"Skipping duplicate test case: {func_name}{test_case.inputs}")
77
+ self.logger.debug(f"Skipping duplicate test case: {func_name}{test_case.inputs}")
78
78
 
79
79
  except Exception as e:
80
80
  print(f"Error testing {function_metadata.function_name}: {e}")
@@ -97,10 +97,10 @@ class RandomFeedbackAnalyzer(TestCaseAnalyzerStrategy, ABC):
97
97
  func.function_name, test_case.inputs)
98
98
  covered = coverage_utils.get_list_of_covered_statements(analysis)
99
99
  self.covered_lines[func.function_name].update(covered)
100
- print(f"Covered lines for {func.function_name}: {self.covered_lines[func.function_name]}")
100
+ self.logger.debug(f"Covered lines for {func.function_name}: {self.covered_lines[func.function_name]}")
101
101
 
102
102
  executable_statements = set(self.get_all_executable_statements(func))
103
- print(f"Executable statements for {func.function_name}: {executable_statements}")
103
+ self.logger.debug(f"Executable statements for {func.function_name}: {executable_statements}")
104
104
 
105
105
  return self.covered_lines[func.function_name] == executable_statements
106
106
 
@@ -5,10 +5,12 @@ from typing import List, Dict
5
5
  from testgen.models.test_case import TestCase
6
6
  from testgen.models.analysis_context import AnalysisContext
7
7
  from testgen.models.function_metadata import FunctionMetadata
8
+ from testgen.service.logging_service import get_logger
8
9
 
9
10
  class TestCaseAnalyzerStrategy(ABC):
10
11
  def __init__(self, analysis_context: AnalysisContext = None):
11
12
  self._analysis_context = analysis_context
13
+ self.logger = get_logger()
12
14
 
13
15
  @abstractmethod
14
16
  def collect_test_cases(self, function_metadata: FunctionMetadata) -> List[TestCase]:
File without changes
@@ -0,0 +1,146 @@
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"""
@@ -0,0 +1,29 @@
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'
@@ -0,0 +1,234 @@
1
+ from typing import List
2
+
3
+
4
+ def bin_and(a: bool, b: bool) ->bool:
5
+ """"
6
+ >>> bin_and(True, True)
7
+ True
8
+ >>> bin_and(True, False)
9
+ False
10
+ >>> bin_and(False, True)
11
+ False
12
+ >>> bin_and(False, False)
13
+ False
14
+
15
+ Examples:
16
+ >>> bin_and(True, False)
17
+ False"""
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_or(a: bool, b: bool) ->bool:
28
+ """"
29
+ >>> bin_or(True, True)
30
+ True
31
+ >>> bin_or(True, False)
32
+ True
33
+ >>> bin_or(False, True)
34
+ True
35
+ >>> bin_or(False, False)
36
+ False
37
+
38
+ Examples:
39
+ >>> bin_or(False, True)
40
+ True"""
41
+ return a | b
42
+
43
+
44
+ def bin_xor(a: bool, b: bool) ->bool:
45
+ """>>> bin_xor(True, True)
46
+ False
47
+ >>> bin_xor(True, False)
48
+ True
49
+ >>> bin_xor(False, True)
50
+ True
51
+ >>> bin_xor(False, False)
52
+ False
53
+
54
+ Examples:
55
+ >>> bin_xor(True, True)
56
+ False"""
57
+ return a ^ b
58
+
59
+
60
+ def bin_nand(a: bool, b: bool) ->bool:
61
+ """>>> bin_nand(True, True)
62
+ False
63
+ >>> bin_nand(True, False)
64
+ True
65
+ >>> bin_nand(False, True)
66
+ True
67
+ >>> bin_nand(False, False)
68
+ True
69
+
70
+ Examples:
71
+ >>> bin_nand(True, False)
72
+ True"""
73
+ return not (a and b)
74
+
75
+
76
+ def bin_nor(a: bool, b: bool) ->bool:
77
+ """>>> bin_nor(True, True)
78
+ False
79
+ >>> bin_nor(True, False)
80
+ False
81
+ >>> bin_nor(False, True)
82
+ False
83
+ >>> bin_nor(False, False)
84
+ True
85
+
86
+ Examples:
87
+ >>> bin_nor(False, True)
88
+ False"""
89
+ return not a | b
90
+
91
+
92
+ def mux(c1: bool, c2: bool, x0: bool, x1: bool, x2: bool, x3: bool) ->bool:
93
+ """"
94
+ >>> mux(1, 1, True, False, False, False)
95
+ True
96
+ >>> mux(1, 0, False, True, False, False)
97
+ True
98
+ >>> mux(0, 1, False, False, True, False)
99
+ True
100
+ >>> mux(0, 0, False, False, False, True)
101
+ True
102
+ >>> mux(0, 0, False, False, False, False)
103
+ False
104
+
105
+ Examples:
106
+ >>> mux(False, False, False, False, False, True)
107
+ True"""
108
+ return (c1 and c2 and x0) | (c1 and not c2 and x1) | (not c1 and c2 and x2
109
+ ) | (not c1 and not c2 and x3)
110
+
111
+
112
+ def bin_and_bad(a: bool, b: bool) ->bool:
113
+ """"
114
+ >>> bin_and(True, True)
115
+ True
116
+ >>> bin_and(True, False)
117
+ False
118
+ >>> bin_and(False, True)
119
+ False
120
+ >>> bin_and(False, False)
121
+ False
122
+
123
+ Examples:
124
+ >>> bin_and_bad(False, True)
125
+ True"""
126
+ if a == True and b == True:
127
+ return a and b
128
+ return a or b
129
+
130
+
131
+ def bin_or_bad(a: bool, b: bool) ->bool:
132
+ """"
133
+ >>> bin_or(True, True)
134
+ True
135
+ >>> bin_or(True, False)
136
+ True
137
+ >>> bin_or(False, True)
138
+ True
139
+ >>> bin_or(False, False)
140
+ False
141
+
142
+ Examples:
143
+ >>> bin_or_bad(True, True)
144
+ False"""
145
+ return not a | b
146
+
147
+
148
+ def bit_converter_excep(num: int) ->List[int]:
149
+ """>>> bit_converter_excep(30)
150
+ [1, 1, 1, 1, 0]"""
151
+ bs = bin(num)
152
+ binary_str = bs[2:]
153
+ try:
154
+ return [int(digit) for digit in binary_str]
155
+ except Exception as e:
156
+ print(binary_str)
157
+ print(bs)
158
+ print(f'Invalid Literal Exception in Bit Converter: {e}')
159
+ return
160
+
161
+
162
+ def bit_converter(num: int) ->List[int]:
163
+ """
164
+ >>> bit_converter(25)
165
+ [1, 1, 0, 0, 1]
166
+ """
167
+ binary_str: str = bin(num)[2:]
168
+ print(bin(num)[2:])
169
+ return [int(digit) for digit in binary_str]
170
+
171
+
172
+ def half_adder(a: bool, b: bool) ->tuple:
173
+ """>>> half_adder(True, True)
174
+ (False, True)"""
175
+ sum: bool = bin_xor(a, b)
176
+ carry: bool = bin_and(a, b)
177
+ return sum, carry
178
+
179
+
180
+ def full_adder(a: bool, b: bool, carry_in: bool) ->tuple:
181
+ """>>> full_adder(True, False, False)
182
+ (True, False)"""
183
+ sum1, carry = half_adder(a, b)
184
+ sum2, carry_out = half_adder(sum1, carry_in)
185
+ return sum2, carry or carry_out
186
+
187
+
188
+ def thirty_two_bit_adder_excep(x: int, y: int) ->List[int]:
189
+ """>>> thirty_two_bit_adder_excep(9, 3)
190
+ None
191
+
192
+ Examples:
193
+ >>> thirty_two_bit_adder_excep(34, 1)
194
+ None"""
195
+ x_bits: List[int] = bit_converter(x)
196
+ y_bits: List[int] = bit_converter(y)
197
+ result: List[int] = [0] * 32
198
+ carry: bool = False
199
+ for i in range(32):
200
+ try:
201
+ sum_bit, carry = full_adder(x_bits[i], y_bits[i], carry)
202
+ result[i] = sum_bit
203
+ except IndexError as e:
204
+ print(f'Index Out of Bounds Error In ThirtyTwoBitAdder: {e}')
205
+ result = [1] * 32
206
+ if carry:
207
+ return OverflowError('Sum exceeds 32 bits')
208
+ return result
209
+
210
+
211
+ def thirty_two_bit_adder(x: int, y: int) ->List[int]:
212
+ """>>> thirty_two_bit_adder(8, 45)
213
+ None"""
214
+ print(x.bit_length() - 1)
215
+ print(y.bit_length() - 1)
216
+ x_bits: List[int] = bit_converter(x)
217
+ y_bits: List[int] = bit_converter(y)
218
+ result: List[int] = [0] * 32
219
+ carry: bool = False
220
+ for i in range(32):
221
+ sum_bit, carry = full_adder(x_bits[i], y_bits[i], carry)
222
+ result[i] = sum_bit
223
+ return result
224
+
225
+
226
+ def thirty_two_bit_adder_excep(x: int, y: int) ->List[int]:
227
+ x_bits: List[int] = bit_converter(x)
228
+ y_bits: List[int] = bit_converter(y)
229
+ result: List[int] = [0] * 32
230
+ carry: bool = False
231
+ for i in range(32):
232
+ sum_bit, carry = full_adder(x_bits[i], y_bits[i], carry)
233
+ result[i] = sum_bit
234
+ return result