Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a displayName for each metric #136

Merged
merged 1 commit into from
Nov 15, 2024
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
72 changes: 39 additions & 33 deletions src/main/java/edu/hm/hafner/coverage/Metric.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,38 +27,38 @@ public enum Metric {
* Nodes that can have children. These notes compute their coverage values on the fly based on their children's
* coverage.
*/
CONTAINER(new CoverageOfChildrenEvaluator()),
MODULE(new CoverageOfChildrenEvaluator()),
PACKAGE(new CoverageOfChildrenEvaluator()),
FILE(new CoverageOfChildrenEvaluator()),
CLASS(new CoverageOfChildrenEvaluator()),
METHOD(new CoverageOfChildrenEvaluator()),
CONTAINER("Container Coverage", new CoverageOfChildrenEvaluator()),
MODULE("Module Coverage", new CoverageOfChildrenEvaluator()),
PACKAGE("Package Coverage", new CoverageOfChildrenEvaluator()),
FILE("File Coverage", new CoverageOfChildrenEvaluator()),
CLASS("Class Coverage", new CoverageOfChildrenEvaluator()),
METHOD("Method Coverage", new CoverageOfChildrenEvaluator()),

/** Coverage values that are leaves in the tree. */
LINE(new ValuesAggregator()),
BRANCH(new ValuesAggregator()),
INSTRUCTION(new ValuesAggregator()),
MCDC_PAIR(new ValuesAggregator()),
FUNCTION_CALL(new ValuesAggregator()),
LINE("Line Coverage", new ValuesAggregator()),
BRANCH("Branch Coverage", new ValuesAggregator()),
INSTRUCTION("Instruction Coverage", new ValuesAggregator()),
MCDC_PAIR("Modified Condition and Decision Coverage", new ValuesAggregator()),
FUNCTION_CALL("Function Call Coverage", new ValuesAggregator()),

/** Additional coverage values obtained from mutation testing. */
MUTATION(new ValuesAggregator()),
TEST_STRENGTH(new ValuesAggregator()),

CYCLOMATIC_COMPLEXITY(new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METHOD_METRIC),
LOC(new LocEvaluator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METRIC),
TESTS(new ValuesAggregator(), MetricTendency.LARGER_IS_BETTER, MetricValueType.CLASS_METRIC),
NCSS(new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METRIC),
COGNITIVE_COMPLEXITY(new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METHOD_METRIC),
NPATH_COMPLEXITY(new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METHOD_METRIC),
ACCESS_TO_FOREIGN_DATA(new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METRIC),
COHESION(new ValuesAggregator(Value::max, "maximum"),
MUTATION("Mutation Coverage", new ValuesAggregator()),
TEST_STRENGTH("Test Strength", new ValuesAggregator()),

CYCLOMATIC_COMPLEXITY("Cyclomatic Complexity", new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METHOD_METRIC),
LOC("Lines of Code", new LocEvaluator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METRIC),
TESTS("Number of Tests", new ValuesAggregator(), MetricTendency.LARGER_IS_BETTER, MetricValueType.CLASS_METRIC),
NCSS("Non Commenting Source Statements", new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METRIC),
COGNITIVE_COMPLEXITY("Cognitive Complexity", new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METHOD_METRIC),
NPATH_COMPLEXITY("N-Path Complexity", new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METHOD_METRIC),
ACCESS_TO_FOREIGN_DATA("Access to Foreign Data", new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METRIC),
COHESION("Class Cohesion", new ValuesAggregator(Value::max, "maximum"),
MetricTendency.LARGER_IS_BETTER, MetricValueType.CLASS_METRIC, new PercentageFormatter()),
FAN_OUT(new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METRIC),
NUMBER_OF_ACCESSORS(new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.CLASS_METRIC),
WEIGHT_OF_CLASS(new ValuesAggregator(Value::max, "maximum"),
FAN_OUT("Fan Out", new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.METRIC),
NUMBER_OF_ACCESSORS("Number of Accessors", new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.CLASS_METRIC),
WEIGHT_OF_CLASS("Weight of Class", new ValuesAggregator(Value::max, "maximum"),
MetricTendency.LARGER_IS_BETTER, MetricValueType.CLASS_METRIC, new PercentageFormatter()),
WEIGHED_METHOD_COUNT(new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.CLASS_METRIC);
WEIGHED_METHOD_COUNT("Weighted Method Count", new ValuesAggregator(), MetricTendency.SMALLER_IS_BETTER, MetricValueType.CLASS_METRIC);

/**
* Returns the metric that belongs to the specified tag.
Expand Down Expand Up @@ -101,32 +101,38 @@ private static String normalize(final String name) {
return name.toUpperCase(Locale.ENGLISH).replaceAll("[-_]", "");
}

private final String displayName;
@SuppressFBWarnings("SE_BAD_FIELD")
private final MetricEvaluator evaluator;
private final MetricTendency tendency;
private final MetricValueType type;
private final MetricFormatter formatter;

Metric(final MetricEvaluator evaluator) {
this(evaluator, MetricTendency.LARGER_IS_BETTER);
Metric(final String displayName, final MetricEvaluator evaluator) {
this(displayName, evaluator, MetricTendency.LARGER_IS_BETTER);
}

Metric(final MetricEvaluator evaluator, final MetricTendency tendency) {
this(evaluator, tendency, MetricValueType.COVERAGE);
Metric(final String displayName, final MetricEvaluator evaluator, final MetricTendency tendency) {
this(displayName, evaluator, tendency, MetricValueType.COVERAGE);
}

Metric(final MetricEvaluator evaluator, final MetricTendency tendency, final MetricValueType type) {
this(evaluator, tendency, type, new IntegerFormatter());
Metric(final String displayName, final MetricEvaluator evaluator, final MetricTendency tendency, final MetricValueType type) {
this(displayName, evaluator, tendency, type, new IntegerFormatter());
}

Metric(final MetricEvaluator evaluator, final MetricTendency tendency, final MetricValueType type,
Metric(final String displayName, final MetricEvaluator evaluator, final MetricTendency tendency, final MetricValueType type,
final MetricFormatter formatter) {
this.displayName = displayName;
this.evaluator = evaluator;
this.tendency = tendency;
this.type = type;
this.formatter = formatter;
}

public String getDisplayName() {
return displayName;
}

public MetricTendency getTendency() {
return tendency;
}
Expand Down
21 changes: 14 additions & 7 deletions src/test/java/edu/hm/hafner/coverage/MetricTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ class MetricTest {
"cyclomatic-complexity", "cyclomatic_complexity", "CYCLOMATIC_COMPLEXITY"})
@ParameterizedTest(name = "{0} should be converted to metric COMPLEXITY")
void shouldMapFromName(final String name) {
assertThat(Metric.fromName(name)).isSameAs(Metric.CYCLOMATIC_COMPLEXITY);
assertThat(Metric.fromName(name)).isSameAs(Metric.CYCLOMATIC_COMPLEXITY)
.hasTendency(MetricTendency.SMALLER_IS_BETTER)
.isNotCoverage()
.isNotContainer()
.hasDisplayName("Cyclomatic Complexity");
}

@Test
Expand Down Expand Up @@ -70,9 +74,9 @@ void shouldGetCoverageMetrics() {
*/
@Test
void shouldCorrectlyImplementIsContainer() {
assertThat(Metric.MODULE.isContainer()).isTrue();
assertThat(Metric.LINE.isContainer()).isFalse();
assertThat(Metric.LOC.isContainer()).isFalse();
assertThat(Metric.MODULE).isContainer().isCoverage().hasDisplayName("Module Coverage");
assertThat(Metric.FILE).isContainer().isCoverage().hasDisplayName("File Coverage");
assertThat(Metric.LINE).isNotContainer().isCoverage().hasDisplayName("Line Coverage");
}

@Test
Expand All @@ -99,7 +103,8 @@ void shouldFormatMetricValues() {
root.createClassNode("class").createMethodNode("method", "()");

var complexity = Metric.CYCLOMATIC_COMPLEXITY;
assertThat(complexity).hasTendency(MetricTendency.SMALLER_IS_BETTER);
assertThat(complexity).hasTendency(MetricTendency.SMALLER_IS_BETTER)
.isNotContainer().isNotCoverage().hasDisplayName("Cyclomatic Complexity");
assertThat(complexity.format(355)).isEqualTo("355");
assertThat(complexity.formatMean(355)).isEqualTo("355.00");
assertThat(complexity.getAggregationType()).isEqualTo("total");
Expand All @@ -111,7 +116,8 @@ void shouldFormatMetricValues() {
.first().extracting(Node::getName).isEqualTo("method()");

var cohesion = Metric.COHESION;
assertThat(cohesion).hasTendency(MetricTendency.LARGER_IS_BETTER);
assertThat(cohesion).hasTendency(MetricTendency.LARGER_IS_BETTER)
.isNotContainer().isNotCoverage().hasDisplayName("Class Cohesion");
assertThat(cohesion.format(0.355)).isEqualTo("35.50%");
assertThat(cohesion.formatMean(0.355)).isEqualTo("35.50%");
assertThat(cohesion.getAggregationType()).isEqualTo("maximum");
Expand All @@ -123,7 +129,8 @@ void shouldFormatMetricValues() {
.first().extracting(Node::getName).isEqualTo("class");

var coverage = Metric.PACKAGE;
assertThat(coverage).hasTendency(MetricTendency.LARGER_IS_BETTER);
assertThat(coverage).hasTendency(MetricTendency.LARGER_IS_BETTER)
.isContainer().isCoverage().hasDisplayName("Package Coverage");
assertThat(coverage.getAggregationType()).isEmpty();
assertThat(coverage.getType()).isEqualTo(MetricValueType.COVERAGE);
assertThat(coverage.getTargetNodes(root)).hasSize(1)
Expand Down