@@ -8,15 +8,21 @@ use crate::*;
88/// The `Cyclomatic` metric.
99#[ derive( Debug , Clone ) ]
1010pub struct Stats {
11+ cyclomatic_sum : f64 ,
1112 cyclomatic : f64 ,
1213 n : usize ,
14+ cyclomatic_max : f64 ,
15+ cyclomatic_min : f64 ,
1316}
1417
1518impl Default for Stats {
1619 fn default ( ) -> Self {
1720 Self {
21+ cyclomatic_sum : 0. ,
1822 cyclomatic : 1. ,
1923 n : 1 ,
24+ cyclomatic_max : 0. ,
25+ cyclomatic_min : f64:: MAX ,
2026 }
2127 }
2228}
@@ -27,8 +33,10 @@ impl Serialize for Stats {
2733 S : Serializer ,
2834 {
2935 let mut st = serializer. serialize_struct ( "cyclomatic" , 2 ) ?;
30- st. serialize_field ( "sum" , & self . cyclomatic ( ) ) ?;
36+ st. serialize_field ( "sum" , & self . cyclomatic_sum ( ) ) ?;
3137 st. serialize_field ( "average" , & self . cyclomatic_average ( ) ) ?;
38+ st. serialize_field ( "min" , & self . cyclomatic_min ( ) ) ?;
39+ st. serialize_field ( "max" , & self . cyclomatic_max ( ) ) ?;
3240 st. end ( )
3341 }
3442}
@@ -37,31 +45,55 @@ impl fmt::Display for Stats {
3745 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
3846 write ! (
3947 f,
40- "sum: {}, average: {}" ,
41- self . cyclomatic( ) ,
42- self . cyclomatic_average( )
48+ "sum: {}, average: {}, min: {}, max: {}" ,
49+ self . cyclomatic_sum( ) ,
50+ self . cyclomatic_average( ) ,
51+ self . cyclomatic_min( ) ,
52+ self . cyclomatic_max( )
4353 )
4454 }
4555}
4656
4757impl Stats {
4858 /// Merges a second `Cyclomatic` metric into the first one
4959 pub fn merge ( & mut self , other : & Stats ) {
50- self . cyclomatic += other. cyclomatic ;
60+ //Calculate minimum and maximum values
61+ self . cyclomatic_max = self . cyclomatic_max . max ( other. cyclomatic_max ) ;
62+ self . cyclomatic_min = self . cyclomatic_min . min ( other. cyclomatic_min ) ;
63+
64+ self . cyclomatic_sum += other. cyclomatic_sum ;
5165 self . n += other. n ;
5266 }
5367
5468 /// Returns the `Cyclomatic` metric value
5569 pub fn cyclomatic ( & self ) -> f64 {
5670 self . cyclomatic
5771 }
72+ /// Returns the sum
73+ pub fn cyclomatic_sum ( & self ) -> f64 {
74+ self . cyclomatic_sum
75+ }
5876
5977 /// Returns the `Cyclomatic` metric average value
6078 ///
6179 /// This value is computed dividing the `Cyclomatic` value for the
6280 /// number of spaces.
6381 pub fn cyclomatic_average ( & self ) -> f64 {
64- self . cyclomatic ( ) / self . n as f64
82+ self . cyclomatic_sum ( ) / self . n as f64
83+ }
84+ /// Returns the `Cyclomatic` maximum value
85+ pub fn cyclomatic_max ( & self ) -> f64 {
86+ self . cyclomatic_max
87+ }
88+ /// Returns the `Cyclomatic` minimum value
89+ pub fn cyclomatic_min ( & self ) -> f64 {
90+ self . cyclomatic_min
91+ }
92+ /// Last step for computing minimum and maximum value and update cyclomatic_sum
93+ pub fn compute_minmax ( & mut self ) {
94+ self . cyclomatic_max = self . cyclomatic_max . max ( self . cyclomatic ) ;
95+ self . cyclomatic_min = self . cyclomatic_min . min ( self . cyclomatic ) ;
96+ self . cyclomatic_sum += self . cyclomatic ;
6597 }
6698}
6799
@@ -190,9 +222,11 @@ mod tests {
190222 "foo.py" ,
191223 PythonParser ,
192224 cyclomatic,
193- [ ( cyclomatic , 6 , usize ) ] ,
225+ [ ( cyclomatic_sum , 6 , usize ) ] ,
194226 [
195- ( cyclomatic_average, 3.0 ) // nspace = 2 (func and unit)
227+ ( cyclomatic_average, 3.0 ) , // nspace = 2 (func and unit)
228+ ( cyclomatic_max, 5.0 ) ,
229+ ( cyclomatic_min, 1.0 )
196230 ]
197231 ) ;
198232 }
@@ -207,9 +241,11 @@ mod tests {
207241 "foo.py" ,
208242 PythonParser ,
209243 cyclomatic,
210- [ ( cyclomatic , 4 , usize ) ] ,
244+ [ ( cyclomatic_sum , 4 , usize ) ] ,
211245 [
212- ( cyclomatic_average, 2.0 ) // nspace = 2 (func and unit)
246+ ( cyclomatic_average, 2.0 ) , // nspace = 2 (func and unit)
247+ ( cyclomatic_max, 3.0 ) ,
248+ ( cyclomatic_min, 1.0 )
213249 ]
214250 ) ;
215251 }
@@ -228,9 +264,11 @@ mod tests {
228264 "foo.rs" ,
229265 RustParser ,
230266 cyclomatic,
231- [ ( cyclomatic , 5 , usize ) ] ,
267+ [ ( cyclomatic_sum , 5 , usize ) ] ,
232268 [
233- ( cyclomatic_average, 2.5 ) // nspace = 2 (func and unit)
269+ ( cyclomatic_average, 2.5 ) , // nspace = 2 (func and unit)
270+ ( cyclomatic_max, 4.0 ) ,
271+ ( cyclomatic_min, 1.0 )
234272 ]
235273 ) ;
236274 }
@@ -257,9 +295,11 @@ mod tests {
257295 "foo.c" ,
258296 CppParser ,
259297 cyclomatic,
260- [ ( cyclomatic , 5 , usize ) ] ,
298+ [ ( cyclomatic_sum , 5 , usize ) ] ,
261299 [
262- ( cyclomatic_average, 2.5 ) // nspace = 2 (func and unit)
300+ ( cyclomatic_average, 2.5 ) , // nspace = 2 (func and unit)
301+ ( cyclomatic_max, 4.0 ) ,
302+ ( cyclomatic_min, 1.0 )
263303 ]
264304 ) ;
265305 }
@@ -282,9 +322,87 @@ mod tests {
282322 "foo.c" ,
283323 CppParser ,
284324 cyclomatic,
285- [ ( cyclomatic, 5 , usize ) ] ,
325+ [ ( cyclomatic_sum, 5 , usize ) ] ,
326+ [
327+ ( cyclomatic_average, 2.5 ) , // nspace = 2 (func and unit)
328+ ( cyclomatic_max, 4.0 ) ,
329+ ( cyclomatic_min, 1.0 )
330+ ]
331+ ) ;
332+ }
333+ #[ test]
334+ fn c_unit_before ( ) {
335+ check_metrics ! (
336+ "
337+ int a=42;
338+ if(a==42) //+2(+1 unit space)
339+ {
340+
341+ }
342+ if(a==34) //+1
343+ {
344+
345+ }
346+ int sumOfPrimes(int max) { // +1
347+ int total = 0;
348+ OUT: for (int i = 1; i <= max; ++i) { // +1
349+ for (int j = 2; j < i; ++j) { // +1
350+ if (i % j == 0) { // +1
351+ continue OUT;
352+ }
353+ }
354+ total += i;
355+ }
356+ return total;
357+ }" ,
358+ "foo.c" ,
359+ CppParser ,
360+ cyclomatic,
361+ [ ( cyclomatic_sum, 7 , usize ) ] ,
362+ [
363+ ( cyclomatic_average, 3.5 ) , // nspace = 2 (func and unit)
364+ ( cyclomatic_max, 4.0 ) ,
365+ ( cyclomatic_min, 3.0 )
366+ ]
367+ ) ;
368+ }
369+ /// Test to handle the case of min and max when merge happen before the final value of one module are setted.
370+ /// In this case the min value should be 3 because the unit space has 2 branches and a complexity of 3
371+ /// while the function sumOfPrimes has a complexity of 4.
372+ #[ test]
373+ fn c_unit_after ( ) {
374+ check_metrics ! (
375+ "
376+ int sumOfPrimes(int max) { // +1
377+ int total = 0;
378+ OUT: for (int i = 1; i <= max; ++i) { // +1
379+ for (int j = 2; j < i; ++j) { // +1
380+ if (i % j == 0) { // +1
381+ continue OUT;
382+ }
383+ }
384+ total += i;
385+ }
386+ return total;
387+ }
388+
389+ int a=42;
390+ if(a==42) //+2(+1 unit space)
391+ {
392+
393+ }
394+ if(a==34) //+1
395+ {
396+
397+ }" ,
398+ "foo.c" ,
399+ CppParser ,
400+ cyclomatic,
401+ [ ( cyclomatic_sum, 7 , usize ) ] ,
286402 [
287- ( cyclomatic_average, 2.5 ) // nspace = 2 (func and unit)
403+ ( cyclomatic_average, 3.5 ) , // nspace = 2 (func and unit)
404+ ( cyclomatic_max, 4.0 ) ,
405+ ( cyclomatic_min, 3.0 )
288406 ]
289407 ) ;
290408 }
0 commit comments