Skip to content
This repository was archived by the owner on Jul 16, 2023. It is now read-only.

feat: add metric value unit type #580

Merged
merged 1 commit into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* feat: add support mixins, extensions and enums for `prefer-match-file-name` rule.
* fix: prefer conditional expressions rule breaks code with increment / decrement operators.
* fix: improve file metrics.
* feat: add metric value unit type.
* chore: restrict `analyzer` version to `>=2.4.0 <2.9.0`.
* chore: tune GitHub workflows.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,7 @@ class LinesOfCodeMetric extends FunctionMetric<int> {
(threshold != null && value > threshold)
? 'Consider breaking this $nodeType up into smaller parts.'
: null;

@override
String? unitType(int value) => value == 1 ? 'line' : 'lines';
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,7 @@ class NumberOfMethodsMetric extends ClassMetric<int> {
location: nodeLocation(node: func.declaration, source: source),
))
.toList(growable: false);

@override
String? unitType(int value) => value == 1 ? 'method' : 'methods';
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ class SourceLinesOfCodeMetric extends FunctionMetric<int> {
? 'Consider breaking this $nodeType up into smaller parts.'
: null;

@override
String? unitType(int value) => value == 1 ? 'line' : 'lines';

Iterable<ContextMessage> _context(
Iterable<int> linesWithCode,
InternalResolvedUnitResult source,
Expand Down
5 changes: 5 additions & 0 deletions lib/src/analyzers/lint_analyzer/metrics/models/metric.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ abstract class Metric<T extends num> {
metricsId: id,
documentation: documentation,
value: result.value,
unitType: unitType(result.value),
level: _levelComputer(result.value, threshold),
comment: commentMessage(type, result.value, threshold),
recommendation: recommendationMessage(type, result.value, threshold),
Expand Down Expand Up @@ -98,4 +99,8 @@ abstract class Metric<T extends num> {
Iterable<ScopedClassDeclaration> classDeclarations,
Iterable<ScopedFunctionDeclaration> functionDeclarations,
);

/// Returns the human readable unit type.
@protected
String? unitType(T value) => null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class MetricValue<T> {
/// The actual value computed by the metric.
final T value;

/// The human readable unit type.
final String? unitType;

/// The level of this value computed by the metric.
final MetricValueLevel level;

Expand All @@ -41,6 +44,7 @@ class MetricValue<T> {
required this.metricsId,
required this.documentation,
required this.value,
this.unitType,
required this.level,
required this.comment,
this.recommendation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ class LintConsoleReporterHelper {
final color = _colorPens[metric.level];

if (color != null) {
final value = metric.value.toInt();
final value = '${metric.value.toInt()} ${metric.unitType ?? ''}'.trim();

return '${metric.documentation.name.toLowerCase()}: ${color('$value')}';
return '${metric.documentation.name.toLowerCase()}: ${color(value)}';
}

throw StateError('Unexpected violation level.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Element renderDetailsTooltipMetric(MetricValue<num> metric) {
..attributes['rel'] = 'noopener noreferrer'
..attributes['title'] = metricName
..text = '$metricName:&nbsp;')
..append(Element.tag('span')..text = metric.value.round().toString()))
..append(Element.tag('span')
..text = '${metric.value.round()} ${metric.unitType ?? ''}'.trim()))
..append(Element.tag('p')
..classes.add('metrics-source-code__tooltip-text')
..append(Element.tag('span')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,13 @@ class LintJsonReporter
Iterable<MetricValue<num>> metrics,
) =>
metrics.map((metric) {
final unitType = metric.unitType;
final recommendation = metric.recommendation;

return {
'metricsId': metric.metricsId,
'value': metric.value,
if (unitType != null) 'unitType': unitType,
'level': metric.level.toString(),
'comment': metric.comment,
if (recommendation != null) 'recommendation': recommendation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Future<void> main() async {

expect(metricValue.metricsId, equals(metric.id));
expect(metricValue.value, equals(5));
expect(metricValue.unitType, equals('lines'));
expect(metricValue.level, equals(MetricValueLevel.noted));
expect(
metricValue.comment,
Expand All @@ -50,6 +51,7 @@ Future<void> main() async {

expect(metricValue.metricsId, equals(metric.id));
expect(metricValue.value, equals(2));
expect(metricValue.unitType, equals('lines'));
expect(metricValue.level, equals(MetricValueLevel.none));
expect(
metricValue.comment,
Expand All @@ -70,6 +72,7 @@ Future<void> main() async {

expect(metricValue.metricsId, equals(metric.id));
expect(metricValue.value, equals(12));
expect(metricValue.unitType, equals('lines'));
expect(metricValue.level, equals(MetricValueLevel.warning));
expect(
metricValue.comment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Future<void> main() async {

expect(metricValue.metricsId, equals(metric.id));
expect(metricValue.value, equals(1));
expect(metricValue.unitType, equals('line'));
expect(metricValue.level, equals(MetricValueLevel.none));
expect(
metricValue.comment,
Expand All @@ -56,6 +57,7 @@ Future<void> main() async {

expect(metricValue.metricsId, equals(metric.id));
expect(metricValue.value, equals(6));
expect(metricValue.unitType, equals('lines'));
expect(metricValue.level, equals(MetricValueLevel.warning));
expect(
metricValue.comment,
Expand All @@ -81,6 +83,7 @@ Future<void> main() async {

expect(metricValue.metricsId, equals(metric.id));
expect(metricValue.value, equals(4));
expect(metricValue.unitType, equals('lines'));
expect(metricValue.level, equals(MetricValueLevel.none));
expect(
metricValue.comment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,12 @@ void main() {

test('getMetricReport returns formatted message', () {
expect(
helper.getMetricReport(buildMetricValueStub(id: 'metricId', value: 12)),
equals('metricid: \x1B[38;5;7m12\x1B[0m'),
helper.getMetricReport(buildMetricValueStub(
id: 'metricId',
value: 12,
unitType: 'units',
)),
equals('metricid: \x1B[38;5;7m12 units\x1B[0m'),
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ void main() {
equals(
[
'test/resources/abstract_class.dart:',
'\x1B[38;5;11mWarning \x1B[0mmetric1: \x1B[38;5;11m100\x1B[0m',
'\x1B[38;5;11mWarning \x1B[0mmetric1: \x1B[38;5;11m100 units\x1B[0m',
'\x1B[38;5;9mAlarm \x1B[0mclass.constructor - metric2: \x1B[38;5;9m10\x1B[0m',
'',
'test/resources/class_with_factory_constructors.dart:',
'\x1B[38;5;11mWarning \x1B[0msimple message : 0:0 : id',
'\x1B[38;5;4mStyle \x1B[0msimple design message : 0:0 : designId',
'\x1B[38;5;11mWarning \x1B[0mfunction - metric4: \x1B[38;5;11m5\x1B[0m',
'\x1B[38;5;11mWarning \x1B[0mfunction - metric4: \x1B[38;5;11m5 units\x1B[0m',
'',
],
),
Expand All @@ -68,7 +68,7 @@ void main() {
equals(
[
'test/resources/abstract_class.dart:',
'\x1B[38;5;11mWarning \x1B[0mmetric1: \x1B[38;5;11m100\x1B[0m',
'\x1B[38;5;11mWarning \x1B[0mmetric1: \x1B[38;5;11m100 units\x1B[0m',
'\x1B[38;5;7m \x1B[0mclass - metric1: \x1B[38;5;7m0\x1B[0m',
'\x1B[38;5;9mAlarm \x1B[0mclass.constructor - metric2: \x1B[38;5;9m10\x1B[0m',
'\x1B[38;5;7m \x1B[0mclass.method - metric3: \x1B[38;5;7m1\x1B[0m',
Expand All @@ -77,7 +77,7 @@ void main() {
'\x1B[38;5;7m \x1B[0mmetric1: \x1B[38;5;7m0\x1B[0m, metric2: \x1B[38;5;7m1\x1B[0m',
'\x1B[38;5;11mWarning \x1B[0msimple message : 0:0 : id',
'\x1B[38;5;4mStyle \x1B[0msimple design message : 0:0 : designId',
'\x1B[38;5;11mWarning \x1B[0mfunction - metric4: \x1B[38;5;11m5\x1B[0m',
'\x1B[38;5;11mWarning \x1B[0mfunction - metric4: \x1B[38;5;11m5 units\x1B[0m',
'',
],
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ void main() {
'<div class="metrics-source-code__tooltip-section"><p class="metrics-source-code__tooltip-text"><a class="metrics-source-code__tooltip-link" href="https://dartcodemetrics.dev/docs/metrics/metric" target="_blank" rel="noopener noreferrer" title="metric">metric:&amp;nbsp;</a><span>10</span></p><p class="metrics-source-code__tooltip-text"><span class="metrics-source-code__tooltip-label">metric violation level:&amp;nbsp;</span><span class="metrics-source-code__tooltip-level metrics-source-code__tooltip-level--warning">warning</span></p></div>',
),
);

expect(
renderDetailsTooltipMetric(
buildMetricValueStub(
id: 'metric',
value: 10,
unitType: 'units',
level: MetricValueLevel.warning,
),
).outerHtml,
equals(
'<div class="metrics-source-code__tooltip-section"><p class="metrics-source-code__tooltip-text"><a class="metrics-source-code__tooltip-link" href="https://dartcodemetrics.dev/docs/metrics/metric" target="_blank" rel="noopener noreferrer" title="metric">metric:&amp;nbsp;</a><span>10 units</span></p><p class="metrics-source-code__tooltip-text"><span class="metrics-source-code__tooltip-label">metric violation level:&amp;nbsp;</span><span class="metrics-source-code__tooltip-level metrics-source-code__tooltip-level--warning">warning</span></p></div>',
),
);
},
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ void main() {
{
'metricsId': 'file-metric-id',
'value': 100,
'unitType': 'units',
'level': 'warning',
'comment': 'metric comment',
'context': <String>[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ final _file1Report = Report(
recomendedThreshold: 0,
),
value: 100,
unitType: 'units',
level: MetricValueLevel.warning,
comment: 'metric comment',
),
Expand Down Expand Up @@ -119,6 +120,7 @@ final _function3Report = Report(
recomendedThreshold: 0,
),
value: 5,
unitType: 'units',
level: MetricValueLevel.warning,
comment: 'metric comment',
),
Expand Down
2 changes: 2 additions & 0 deletions test/stubs_builders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class _DeclarationMock extends Mock implements Declaration {}
MetricValue<T> buildMetricValueStub<T>({
required String id,
required T value,
String? unitType,
EntityType type = EntityType.methodEntity,
MetricValueLevel level = MetricValueLevel.none,
}) =>
Expand All @@ -30,6 +31,7 @@ MetricValue<T> buildMetricValueStub<T>({
recomendedThreshold: 0,
),
value: value,
unitType: unitType,
level: level,
comment: '',
);
Expand Down
2 changes: 2 additions & 0 deletions website/docs/cli/analyze.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ The reporter prints a single JSON object containing meta information and the vio

- `metricsId` - an id of the computed metric
- `value` - an actual value computed by the metric
- `unitType` - a human readable unit type _(optional)_
- `level` - a level of the value computed by the metric
- `comment` - a message with information about the value
- `recommendation` - a message with information about how the user can improve the value _(optional)_
Expand All @@ -215,6 +216,7 @@ The reporter prints a single JSON object containing meta information and the vio
{
"metricsId": "number-of-methods",
"value": 14,
"unitType": "methods",
"level": "warning",
"comment": "This class has 14 methods, which exceeds the maximum of 10 allowed.",
"recommendation": "Consider breaking this class up into smaller parts.",
Expand Down