From 13dec7a276748d8b7ac32b84268acef0c4fd9043 Mon Sep 17 00:00:00 2001 From: Dmitry Krutskikh Date: Wed, 18 Mar 2020 22:14:20 +0300 Subject: [PATCH 1/7] update gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index dbef116d22..15139b0d4b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ doc/api/ *.js_ *.js.deps *.js.map + +coverage From 00c68d8fe5eba9d2d26520748151686edd5cf5a6 Mon Sep 17 00:00:00 2001 From: Dmitry Krutskikh Date: Wed, 18 Mar 2020 22:17:03 +0300 Subject: [PATCH 2/7] fix test name --- test/scope_ast_visitor_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/scope_ast_visitor_test.dart b/test/scope_ast_visitor_test.dart index b4d9069b18..455bfdc6df 100644 --- a/test/scope_ast_visitor_test.dart +++ b/test/scope_ast_visitor_test.dart @@ -7,7 +7,7 @@ import 'package:path/path.dart' as p; import 'package:test/test.dart'; void main() { - group('analyze file with ', () { + group('analyze file with', () { test('abstract class', () { final visitor = ScopeAstVisitor(); parseFile( From 52783679ac955ab7ccdc7ec44bf39051ce147027 Mon Sep 17 00:00:00 2001 From: Dmitry Krutskikh Date: Mon, 16 Mar 2020 08:31:33 +0300 Subject: [PATCH 3/7] move util function in separate file --- lib/src/metrics_analyzer.dart | 17 +---------------- lib/src/metrics_analyzer_utils.dart | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 lib/src/metrics_analyzer_utils.dart diff --git a/lib/src/metrics_analyzer.dart b/lib/src/metrics_analyzer.dart index aac19f6452..ce5aba07b7 100644 --- a/lib/src/metrics_analyzer.dart +++ b/lib/src/metrics_analyzer.dart @@ -1,31 +1,16 @@ import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/analysis/utilities.dart'; -import 'package:analyzer/dart/ast/ast.dart'; import 'package:built_collection/built_collection.dart'; import 'package:dart_code_metrics/src/cyclomatic_complexity/control_flow_ast_visitor.dart'; import 'package:dart_code_metrics/src/cyclomatic_complexity/cyclomatic_config.dart'; -import 'package:dart_code_metrics/src/cyclomatic_complexity/models/scoped_declaration.dart'; import 'package:dart_code_metrics/src/halstead_volume/halstead_volume_ast_visitor.dart'; import 'package:dart_code_metrics/src/lines_of_code/function_body_ast_visitor.dart'; import 'package:dart_code_metrics/src/metrics_analysis_recorder.dart'; +import 'package:dart_code_metrics/src/metrics_analyzer_utils.dart'; import 'package:dart_code_metrics/src/models/function_record.dart'; import 'package:dart_code_metrics/src/scope_ast_visitor.dart'; import 'package:path/path.dart' as p; -String getQualifiedName(ScopedDeclaration dec) { - final declaration = dec.declaration; - - if (declaration is FunctionDeclaration) { - return declaration.name.toString(); - } else if (declaration is ConstructorDeclaration) { - return '${dec.declarationIdentifier}.${declaration.name}'; - } else if (declaration is MethodDeclaration) { - return '${dec.declarationIdentifier}.${declaration.name}'; - } - - return null; -} - /// Performs code quality analysis on specified files /// See [MetricsAnalysisRunner] to get analysis info class MetricsAnalyzer { diff --git a/lib/src/metrics_analyzer_utils.dart b/lib/src/metrics_analyzer_utils.dart new file mode 100644 index 0000000000..bb9c0cb140 --- /dev/null +++ b/lib/src/metrics_analyzer_utils.dart @@ -0,0 +1,16 @@ +import 'package:analyzer/dart/ast/ast.dart'; +import 'package:dart_code_metrics/src/cyclomatic_complexity/models/scoped_declaration.dart'; + +String getQualifiedName(ScopedDeclaration dec) { + final declaration = dec.declaration; + + if (declaration is FunctionDeclaration) { + return declaration.name.toString(); + } else if (declaration is ConstructorDeclaration) { + return '${dec.declarationIdentifier}.${declaration.name}'; + } else if (declaration is MethodDeclaration) { + return '${dec.declarationIdentifier}.${declaration.name}'; + } + + return null; +} From 57bbc88b5f6c8b9a9b130e82f7c283041a677af0 Mon Sep 17 00:00:00 2001 From: Dmitry Krutskikh Date: Thu, 19 Mar 2020 15:08:13 +0300 Subject: [PATCH 4/7] refactor UtilitySelector.functionViolationLevel --- lib/src/reporters/utility_selector.dart | 17 ++++------- pubspec.yaml | 1 + test/reporters/utility_selector_test.dart | 35 +++++++++++++++++++++++ test/stubs_builders.dart | 18 ++++++++++++ 4 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 test/reporters/utility_selector_test.dart create mode 100644 test/stubs_builders.dart diff --git a/lib/src/reporters/utility_selector.dart b/lib/src/reporters/utility_selector.dart index 807f888d6a..b768324bc8 100644 --- a/lib/src/reporters/utility_selector.dart +++ b/lib/src/reporters/utility_selector.dart @@ -6,6 +6,7 @@ import 'package:dart_code_metrics/src/models/config.dart'; import 'package:dart_code_metrics/src/models/function_record.dart'; import 'package:dart_code_metrics/src/models/function_report.dart'; import 'package:dart_code_metrics/src/models/violation_level.dart'; +import 'package:quiver/iterables.dart' as quiver; double log2(num a) => log(a) / ln2; @@ -150,17 +151,11 @@ class UtilitySelector { static ViolationLevel functionViolationLevel(FunctionReport report) { final values = ViolationLevel.values.toList(); - final cyclomaticComplexityViolationLevelIndex = - values.indexOf(report.cyclomaticComplexityViolationLevel); - final linesOfCodeViolationLevelIndex = - values.indexOf(report.linesOfCodeViolationLevel); - final maintainabilityIndexViolationLevelIndex = - values.indexOf(report.maintainabilityIndexViolationLevel); - - final highestLevelIndex = max( - max(cyclomaticComplexityViolationLevelIndex, - linesOfCodeViolationLevelIndex), - maintainabilityIndexViolationLevelIndex); + final highestLevelIndex = quiver.max([ + report.cyclomaticComplexityViolationLevel, + report.linesOfCodeViolationLevel, + report.maintainabilityIndexViolationLevel, + ].map(values.indexOf)); return values.elementAt(highestLevelIndex); } diff --git a/pubspec.yaml b/pubspec.yaml index 057482f082..235700eaaa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: html: '>=0.13.0 < 1.0.0' meta: ^1.1.0 path: ^1.6.0 + quiver: ^2.1.0 resource: ^2.1.0 dev_dependencies: diff --git a/test/reporters/utility_selector_test.dart b/test/reporters/utility_selector_test.dart new file mode 100644 index 0000000000..d62d6b7f45 --- /dev/null +++ b/test/reporters/utility_selector_test.dart @@ -0,0 +1,35 @@ +@TestOn('vm') +import 'package:dart_code_metrics/src/models/violation_level.dart'; +import 'package:dart_code_metrics/src/reporters/utility_selector.dart'; +import 'package:test/test.dart'; + +import '../stubs_builders.dart'; + +void main() { + group('UtilitySelector', () { + test( + 'functionViolationLevel return aggregated violation level for function', + () { + expect( + UtilitySelector.functionViolationLevel(buildFunctionReportStub( + cyclomaticComplexityViolationLevel: ViolationLevel.warning, + linesOfCodeViolationLevel: ViolationLevel.noted, + maintainabilityIndexViolationLevel: ViolationLevel.none)), + ViolationLevel.warning); + + expect( + UtilitySelector.functionViolationLevel(buildFunctionReportStub( + cyclomaticComplexityViolationLevel: ViolationLevel.warning, + linesOfCodeViolationLevel: ViolationLevel.alarm, + maintainabilityIndexViolationLevel: ViolationLevel.none)), + ViolationLevel.alarm); + + expect( + UtilitySelector.functionViolationLevel(buildFunctionReportStub( + cyclomaticComplexityViolationLevel: ViolationLevel.none, + linesOfCodeViolationLevel: ViolationLevel.none, + maintainabilityIndexViolationLevel: ViolationLevel.noted)), + ViolationLevel.noted); + }); + }); +} diff --git a/test/stubs_builders.dart b/test/stubs_builders.dart new file mode 100644 index 0000000000..3193f0e7a9 --- /dev/null +++ b/test/stubs_builders.dart @@ -0,0 +1,18 @@ +import 'package:dart_code_metrics/src/models/function_report.dart'; +import 'package:dart_code_metrics/src/models/violation_level.dart'; + +FunctionReport buildFunctionReportStub( + {int cyclomaticComplexity = 0, + ViolationLevel cyclomaticComplexityViolationLevel = ViolationLevel.none, + int linesOfCode = 0, + ViolationLevel linesOfCodeViolationLevel = ViolationLevel.none, + double maintainabilityIndex = 0, + ViolationLevel maintainabilityIndexViolationLevel = + ViolationLevel.none}) => + FunctionReport( + cyclomaticComplexity: cyclomaticComplexity, + cyclomaticComplexityViolationLevel: cyclomaticComplexityViolationLevel, + linesOfCode: linesOfCode, + linesOfCodeViolationLevel: linesOfCodeViolationLevel, + maintainabilityIndex: maintainabilityIndex, + maintainabilityIndexViolationLevel: maintainabilityIndexViolationLevel); From e2b399c4914733c38c34648644fcd9479aa7b17e Mon Sep 17 00:00:00 2001 From: Dmitry Krutskikh Date: Thu, 19 Mar 2020 09:54:14 +0300 Subject: [PATCH 5/7] update console reporter --- lib/src/reporters/console_reporter.dart | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/src/reporters/console_reporter.dart b/lib/src/reporters/console_reporter.dart index 5edeb426cd..31587235de 100644 --- a/lib/src/reporters/console_reporter.dart +++ b/lib/src/reporters/console_reporter.dart @@ -46,11 +46,21 @@ class ConsoleReporter implements Reporter { final violationLevel = UtilitySelector.functionViolationLevel(report); if (reportAll || _isIssueLevel(violationLevel)) { + final violations = [ + if (reportAll || + report.cyclomaticComplexityViolationLevel != + ViolationLevel.none) + 'cyclomatic complexity: ${_colorPens[report.cyclomaticComplexityViolationLevel]('${report.cyclomaticComplexity}')}', + if (reportAll || + report.linesOfCodeViolationLevel != ViolationLevel.none) + 'lines of code: ${_colorPens[report.linesOfCodeViolationLevel]('${report.linesOfCode}')}', + if (reportAll || + report.maintainabilityIndexViolationLevel != + ViolationLevel.none) + 'maintainability index: ${_colorPens[report.maintainabilityIndexViolationLevel]('${report.maintainabilityIndex.toInt()}')}', + ]; lines.add( - '${_colorPens[violationLevel](_humanReadableLabel[violationLevel]?.padRight(8))}$source - ' - 'cyclomatic complexity: ${_colorPens[report.cyclomaticComplexityViolationLevel]('${report.cyclomaticComplexity}')}, ' - 'lines of code: ${_colorPens[report.linesOfCodeViolationLevel]('${report.linesOfCode}')}, ' - 'maintainability index: ${_colorPens[report.maintainabilityIndexViolationLevel]('${report.maintainabilityIndex.toInt()}')}, '); + '${_colorPens[violationLevel](_humanReadableLabel[violationLevel]?.padRight(8))}$source - ${violations.join(', ')}'); } }); From 07b52ecce9ace83466c9054c5b1287399651f9cd Mon Sep 17 00:00:00 2001 From: Dmitry Krutskikh Date: Fri, 20 Mar 2020 09:34:09 +0300 Subject: [PATCH 6/7] extract utility function isIssueLevel --- lib/src/reporters/console_reporter.dart | 5 +---- lib/src/reporters/utility_selector.dart | 3 +++ test/reporters/utility_selector_test.dart | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/src/reporters/console_reporter.dart b/lib/src/reporters/console_reporter.dart index 31587235de..36c71de067 100644 --- a/lib/src/reporters/console_reporter.dart +++ b/lib/src/reporters/console_reporter.dart @@ -45,7 +45,7 @@ class ConsoleReporter implements Reporter { UtilitySelector.functionReport(functionReport, reportConfig); final violationLevel = UtilitySelector.functionViolationLevel(report); - if (reportAll || _isIssueLevel(violationLevel)) { + if (reportAll || UtilitySelector.isIssueLevel(violationLevel)) { final violations = [ if (reportAll || report.cyclomaticComplexityViolationLevel != @@ -73,7 +73,4 @@ class ConsoleReporter implements Reporter { return reportStrings; } - - bool _isIssueLevel(ViolationLevel level) => - level == ViolationLevel.warning || level == ViolationLevel.alarm; } diff --git a/lib/src/reporters/utility_selector.dart b/lib/src/reporters/utility_selector.dart index b768324bc8..2b8429cd12 100644 --- a/lib/src/reporters/utility_selector.dart +++ b/lib/src/reporters/utility_selector.dart @@ -160,6 +160,9 @@ class UtilitySelector { return values.elementAt(highestLevelIndex); } + static bool isIssueLevel(ViolationLevel level) => + level == ViolationLevel.warning || level == ViolationLevel.alarm; + static ViolationLevel _violationLevel(int value, int warningLevel) { if (value > warningLevel * 2) { return ViolationLevel.alarm; diff --git a/test/reporters/utility_selector_test.dart b/test/reporters/utility_selector_test.dart index d62d6b7f45..7d0e42f7d3 100644 --- a/test/reporters/utility_selector_test.dart +++ b/test/reporters/utility_selector_test.dart @@ -31,5 +31,19 @@ void main() { maintainabilityIndexViolationLevel: ViolationLevel.noted)), ViolationLevel.noted); }); + test('isIssueLevel', () { + const violationsMapping = { + ViolationLevel.none: isFalse, + ViolationLevel.noted: isFalse, + ViolationLevel.warning: isTrue, + ViolationLevel.alarm: isTrue, + }; + + assert(violationsMapping.keys.length == ViolationLevel.values.length); + + violationsMapping.forEach((key, value) { + expect(UtilitySelector.isIssueLevel(key), value); + }); + }); }); } From c1b9538d2182cafa4ac162157585b6684aaadcb8 Mon Sep 17 00:00:00 2001 From: Dmitry Krutskikh Date: Fri, 20 Mar 2020 09:43:08 +0300 Subject: [PATCH 7/7] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ecd49d97f..dbddbf3cea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +#Unreleased + # 1.2.1 - Validate root-folder argument - Fix paths to analyze fail to validate with non-default root-folder