Skip to content

Commit 8d3b21f

Browse files
authored
Add String Implementation - StatisticsAggregator (#678)
* Add string output for statistics due to not implementation error * Add return type annotations * Empty commit
1 parent c6e53b7 commit 8d3b21f

File tree

2 files changed

+37
-18
lines changed

2 files changed

+37
-18
lines changed

detect_secrets/audit/analytics.py

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,14 @@ def _get_plugin_counter(self, secret_type: str) -> 'StatisticsCounter':
5858
return cast(StatisticsCounter, self.data[secret_type]['stats'])
5959

6060
def __str__(self) -> str:
61-
raise NotImplementedError
61+
output = ''
62+
63+
for secret_type, framework in self.data.items():
64+
output += f'Plugin: {get_mapping_from_secret_type_to_class()[secret_type].__name__}\n'
65+
for value in framework.values():
66+
output += f'Statistics: {value}\n\n'
67+
68+
return output
6269

6370
def json(self) -> Dict[str, Any]:
6471
output = {}
@@ -77,19 +84,36 @@ def __init__(self) -> None:
7784
self.incorrect: int = 0
7885
self.unknown: int = 0
7986

80-
def __repr__(self) -> str:
87+
def __str__(self) -> str:
8188
return (
82-
f'{self.__class__.__name__}(correct={self.correct}, '
83-
'incorrect={self.incorrect}, unknown={self.unknown},)'
89+
f'True Positives: {self.correct}, False Positives: {self.incorrect}, '
90+
f'Unknown: {self.unknown}, Precision: {self.calculate_precision()}, '
91+
f'Recall: {self.calculate_recall()}'
8492
)
8593

8694
def json(self) -> Dict[str, Any]:
95+
return {
96+
'raw': {
97+
'true-positives': self.correct,
98+
'false-positives': self.incorrect,
99+
'unknown': self.unknown,
100+
},
101+
'score': {
102+
'precision': self.calculate_precision(),
103+
'recall': self.calculate_recall(),
104+
},
105+
}
106+
107+
def calculate_precision(self) -> float:
87108
precision = (
88109
round(float(self.correct) / (self.correct + self.incorrect), 4)
89110
if (self.correct and self.incorrect)
90111
else 0.0
91112
)
92113

114+
return precision
115+
116+
def calculate_recall(self) -> float:
93117
# NOTE(2020-11-08|domanchi): This isn't the formal definition of `recall`, however,
94118
# this is the definition that we're going to attribute to it.
95119
#
@@ -124,14 +148,4 @@ def json(self) -> Dict[str, Any]:
124148
else 0.0
125149
)
126150

127-
return {
128-
'raw': {
129-
'true-positives': self.correct,
130-
'false-positives': self.incorrect,
131-
'unknown': self.unknown,
132-
},
133-
'score': {
134-
'precision': precision,
135-
'recall': recall,
136-
},
137-
}
151+
return recall

tests/audit/analytics_test.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,14 @@ def test_no_divide_by_zero(secret):
6666
main(['audit', f.name, '--stats', '--json'])
6767

6868

69-
@pytest.mark.skip(reason='TODO')
70-
def test_basic_statistics_str():
71-
pass
69+
def test_basic_statistics_str(printer):
70+
with labelled_secrets() as filename:
71+
main(['audit', filename, '--stats'])
72+
73+
assert printer.message == (
74+
'Plugin: BasicAuthDetector\nStatistics: True Positives: 1, ' +
75+
'False Positives: 2, Unknown: 1, Precision: 0.3333, Recall: 0.5\n\n\n'
76+
)
7277

7378

7479
@contextmanager

0 commit comments

Comments
 (0)