Skip to content
This repository was archived by the owner on Feb 12, 2025. It is now read-only.

Commit 211221a

Browse files
committed
updated analyzer with coverage
1 parent 902f45f commit 211221a

File tree

8 files changed

+280
-1401
lines changed

8 files changed

+280
-1401
lines changed

BugsInPy.ipynb

Lines changed: 166 additions & 1011 deletions
Large diffs are not rendered by default.

Demo.ipynb

Lines changed: 58 additions & 382 deletions
Large diffs are not rendered by default.

src/sflkit/analysis/analysis_type.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def set_finder(function_finder, loop_finder, branch_finder):
5757
def __init__(self, event):
5858
self.suspiciousness: float = 0
5959
self.last_evaluation: EvaluationResult = EvaluationResult.UNOBSERVED
60+
self.hits = dict()
6061

6162
def get_last_evaluation(self, id_: int) -> EvaluationResult:
6263
return self.last_evaluation

src/sflkit/analysis/analyzer.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from typing import List, Callable
1+
import os
2+
from typing import List, Callable, Set, Dict
23

3-
from sflkit.analysis.analysis_type import AnalysisType
4+
from sflkit.analysis.analysis_type import AnalysisType, AnalysisObject
45
from sflkit.analysis.factory import AnalysisFactory
56
from sflkit.analysis.suggestion import Suggestion
67
from sflkit.model.event_file import EventFile
@@ -17,6 +18,7 @@ def __init__(
1718
self.relevant_event_files = relevant_event_files
1819
self.irrelevant_event_files = irrelevant_event_files
1920
self.model = Model(factory)
21+
self.paths: Dict[int, os.PathLike] = dict()
2022

2123
def _analyze(self, event_file):
2224
self.model.prepare(event_file)
@@ -29,16 +31,17 @@ def _finalize(self):
2931

3032
def analyze(self):
3133
for event_file in self.relevant_event_files + self.irrelevant_event_files:
34+
self.paths[event_file.run_id] = event_file.path
3235
self._analyze(event_file)
3336
self._finalize()
3437

3538
def dump(self, path):
3639
pass
3740

38-
def get_analysis(self):
41+
def get_analysis(self) -> Set[AnalysisObject]:
3942
return list(self.model.get_analysis())
4043

41-
def get_analysis_by_type(self, type_: AnalysisType):
44+
def get_analysis_by_type(self, type_: AnalysisType) -> Set[AnalysisObject]:
4245
return list(
4346
filter(lambda p: p.analysis_type() == type_, self.model.get_analysis())
4447
)
@@ -66,3 +69,23 @@ def get_sorted_suggestions(
6669
],
6770
reverse=True,
6871
)[:]
72+
73+
def get_coverage_per_run(
74+
self, type_: AnalysisType = None
75+
) -> Dict[EventFile, Set[AnalysisObject]]:
76+
if type_:
77+
objects = self.get_analysis_by_type(type_)
78+
else:
79+
objects = self.get_analysis()
80+
coverage = dict()
81+
for obj in objects:
82+
for run_id in obj.hits:
83+
if run_id not in coverage:
84+
coverage[run_id] = {obj}
85+
else:
86+
coverage[run_id].add(obj)
87+
return coverage
88+
89+
def get_coverage(self, type_: AnalysisType = None) -> Set[AnalysisObject]:
90+
coverage = self.get_coverage_per_run(type_)
91+
return set.union(*coverage.values())

src/sflkit/analysis/spectra.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ def __init__(
3939
self.failed = failed_observed + failed_not_observed
4040
self.failed_observed = failed_observed
4141
self.failed_not_observed = failed_not_observed
42-
self.hits = dict()
4342
self.last_evaluation: EvaluationResult = EvaluationResult.FALSE
4443

4544
def __str__(self):

src/sflkit/model/event_file.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
from pickle import PickleError
23

34
from sflkitlib.events import event
@@ -7,7 +8,11 @@
78

89
class EventFile(object):
910
def __init__(
10-
self, path: str, run_id: int, mapping: EventMapping, failing: bool = False
11+
self,
12+
path: os.PathLike,
13+
run_id: int,
14+
mapping: EventMapping,
15+
failing: bool = False,
1116
):
1217
self.path = path
1318
self.run_id = run_id

src/sflkit/model/model.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import List
1+
from typing import Set
22

33
from sflkit.model.scope import Scope
44

@@ -68,7 +68,8 @@ def enter_scope(self):
6868
def exit_scope(self):
6969
self.variables = self.variables.exit()
7070

71-
def get_analysis(self) -> List:
71+
# noinspection PyUnresolvedReferences
72+
def get_analysis(self) -> Set["AnalysisObject"]:
7273
return self.factory.get_all()
7374

7475
def finalize(self, passed, failed):

tests/test_coverage.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from typing import List
2+
3+
from sflkit.analysis.analysis_type import AnalysisType
4+
from sflkit.analysis.spectra import Line
5+
from utils import BaseTest
6+
7+
8+
class TestCoverage(BaseTest):
9+
def test_coverage(self):
10+
analyzer = self.run_analysis(
11+
self.TEST_SUGGESTIONS,
12+
"line",
13+
"line",
14+
relevant=[["2", "1", "3"]],
15+
irrelevant=[["3", "2", "1"], ["3", "1", "2"]],
16+
)
17+
coverage: List[Line] = analyzer.get_coverage(AnalysisType.LINE)
18+
coverage = {line.line for line in coverage}
19+
self.assertEqual(coverage, {1, 5, 6, 7, 9, 10, 12, 13, 16, 19, 20})

0 commit comments

Comments
 (0)