Start on fitness function for branch coverage
from __future__ import annotations
from functools import total_ordering
-from typing import Any
+from typing import Any, Optional
+import pynguin.coverage.branch.branchcoveragegoal as bcg
+import pynguin.coverage.branch.branchpool as bp
from pynguin.ga.fitnessfunctions.fitness_utilities import normalise
+from pynguin.testcase.execution.executionresult import ExecutionResult
@total_ordering
@@ -103,11 +106,51 @@ class ControlFlowDistanceCalculator:
@classmethod
def get_distance(
cls,
+ result: ExecutionResult,
+ *,
+ branch: bcg.Branch,
+ value: bool,
+ module_name: str,
+ class_name: Optional[str] = None,
+ function_name: str,
+ ) -> ControlFlowDistance:
+ if branch is None:
+ return cls._get_root_distance(
result,
- branch,
- value,
- module_name,
- class_name,
- function_name,
+ module_name=module_name,
+ class_name=class_name,
+ function_name=function_name,
+ )
+
+ if value:
+ if branch.actual_branch_id in result.execution_trace.true_distances:
+ return ControlFlowDistance(0, 0.0)
+ else:
+ if branch.actual_branch_id in result.execution_trace.false_distances:
+ return ControlFlowDistance(0, 0.0)
+
+ return cls._get_non_root_distance(result, branch, value)
+
+ @classmethod
+ def _get_root_distance(
+ cls,
+ result: ExecutionResult,
+ *,
+ module_name: str,
+ class_name: Optional[str] = None,
+ function_name: str,
+ ) -> ControlFlowDistance:
+ distance = ControlFlowDistance()
+ bp.INSTANCE.is_branchless_function(function_name)
+
+ distance.increase_approach_level()
+ return distance
+
+ @classmethod
+ def _get_non_root_distance(
+ cls,
+ result: ExecutionResult,
+ branch: bcg.Branch,
+ value: bool,
) -> ControlFlowDistance:
pass
