Sample

Schnappinger/junit4/org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters

Human rating uses the original dataset scale.

Human2.72
Lines143

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
28.4Δ 11.3
Scalabrino0.630–1; higher is more readable
26.4Δ 9.2
Dorn0.3630–1; higher is more readable
52.8Δ 35.6
Mi0.5090–1; higher is more readable
35.0Δ 17.8
LLOC57Logical lines; fewer is more readable
36.5Δ 19.3
DeepSeek V4 Pro16.330–20; mean of three runs
53.1Δ 36.0
GPT-6.1 Sol170–20; mean of three runs
55.3Δ 38.1
BTTF0.3380–1; higher is more readable
25.1Δ 7.9
Human2.721–4; original rating
17.2

Views

Source code

package org.junit.runners.parameterized; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.List; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.model.FrameworkField; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; /** * A {@link BlockJUnit4ClassRunner} with parameters support. Parameters can be * injected via constructor or into annotated fields. */ public class BlockJUnit4ClassRunnerWithParameters extends BlockJUnit4ClassRunner { private final Object[] fParameters; private final String fName; public BlockJUnit4ClassRunnerWithParameters(TestWithParameters test) throws InitializationError { super(test.getTestClass().getJavaClass()); fParameters = test.getParameters().toArray( new Object[test.getParameters().size()]); fName = test.getName(); } @Override public Object createTest() throws Exception { if (fieldsAreAnnotated()) { return createTestUsingFieldInjection(); } else { return createTestUsingConstructorInjection(); } } private Object createTestUsingConstructorInjection() throws Exception { return getTestClass().getOnlyConstructor().newInstance(fParameters); } private Object createTestUsingFieldInjection() throws Exception { List<FrameworkField> annotatedFieldsByParameter = getAnnotatedFieldsByParameter(); if (annotatedFieldsByParameter.size() != fParameters.length) { throw new Exception( "Wrong number of parameters and @Parameter fields." + " @Parameter fields counted: " + annotatedFieldsByParameter.size() + ", available parameters: " + fParameters.length + "."); } Object testClassInstance = getTestClass().getJavaClass().newInstance(); for (FrameworkField each : annotatedFieldsByParameter) { Field field = each.getField(); Parameter annotation = field.getAnnotation(Parameter.class); int index = annotation.value(); try { field.set(testClassInstance, fParameters[index]); } catch (IllegalArgumentException iare) { throw new Exception(getTestClass().getName() + ": Trying to set " + field.getName() + " with the value " + fParameters[index] + " that is not the right type (" + fParameters[index].getClass().getSimpleName() + " instead of " + field.getType().getSimpleName() + ").", iare); } } return testClassInstance; } @Override protected String getName() { return fName; } @Override protected String testName(FrameworkMethod method) { return method.getName() + getName(); } @Override protected void validateConstructor(List<Throwable> errors) { validateOnlyOneConstructor(errors); if (fieldsAreAnnotated()) { validateZeroArgConstructor(errors); } } @Override protected void validateFields(List<Throwable> errors) { super.validateFields(errors); if (fieldsAreAnnotated()) { List<FrameworkField> annotatedFieldsByParameter = getAnnotatedFieldsByParameter(); int[] usedIndices = new int[annotatedFieldsByParameter.size()]; for (FrameworkField each : annotatedFieldsByParameter) { int index = each.getField().getAnnotation(Parameter.class) .value(); if (index < 0 || index > annotatedFieldsByParameter.size() - 1) { errors.add(new Exception("Invalid @Parameter value: " + index + ". @Parameter fields counted: " + annotatedFieldsByParameter.size() + ". Please use an index between 0 and " + (annotatedFieldsByParameter.size() - 1) + ".")); } else { usedIndices[index]++; } } for (int index = 0; index < usedIndices.length; index++) { int numberOfUse = usedIndices[index]; if (numberOfUse == 0) { errors.add(new Exception("@Parameter(" + index + ") is never used.")); } else if (numberOfUse > 1) { errors.add(new Exception("@Parameter(" + index + ") is used more than once (" + numberOfUse + ").")); } } } } @Override protected Statement classBlock(RunNotifier notifier) { return childrenInvoker(notifier); } @Override protected Annotation[] getRunnerAnnotations() { return new Annotation[0]; } private List<FrameworkField> getAnnotatedFieldsByParameter() { return getTestClass().getAnnotatedFields(Parameter.class); } private boolean fieldsAreAnnotated() { return !getAnnotatedFieldsByParameter().isEmpty(); } }

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.5576.531−184.026
Source linesThe number of non-empty source lines.143+57.2
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.4.401−6.602

Intercept 8.87 + feature contributions = -124.557 (log-odds).
Score = sigmoid(-124.557) = 0.

Score0.63

Feature contributions

FeatureValueContribution
(log-odds)
Indentation frequencyHow rapidly indentation changes from line to line.140+4.105
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.144−4.062
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.140−2.792
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.142.916+1.588
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.94+0.712
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.93.993−0.316
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.083+0.131

Intercept 0.07 + feature contributions = -0.564 (log-odds).
Score = sigmoid(-0.564) = 0.363.

Score0.509
Score57
Run 1

The code is well-structured with clear separation of concerns and methods that each handle a single responsibility. It has some deep nesting in the field injection and validation methods, particularly with if-else and try-catch blocks, which slightly reduces readability. Intent is mostly clear—the class handles parameterized test runners—but some complex error messages make it harder to follow. Code length is reasonable for the functionality; no unnecessary verbosity. Action granularity is strong, with one main action per line. Reading flow is generally logical, though the nested validation loops and conditional logic disrupt smooth flow. Overall, it's readable and maintainable, with minor nesting and clarity issues.

Run 2

The code demonstrates solid structure with clear separation of responsibilities and logical method decomposition. It uses early returns in createTest() and avoids deep nesting. Class naming and field prefixes (fParameters, fName) are consistent. However, readability is slightly reduced by several factors: long parameter-contract validation error messages in createTestUsingFieldInjection() and validateFields() make those methods harder to scan; validation logic in validateFields() handles multiple concerns in one method with somewhat tangled loop logic; the constructor injection and field injection paths are straightforward but the error handling branches add moderate complexity. Most methods perform one action per line and flow naturally. The code relies on JUnit framework patterns that may be familiar to test runners but add implicit context. Overall, it is readable for experienced JUnit developers but slightly verbose in error message construction.

Run 3

The code is well-structured, with clear method separation and a logical flow. It uses descriptive method names that convey intent, and the single-responsibility principle is mostly respected. Nesting is minimal except for one deeply indented if/else block in validation, and the action granularity is generally good, though some lines are long due to string concatenations. The validation method is slightly repetitive but remains readable. Overall, the code is easy to follow and maintain, losing points mainly for minor verbosity and a few overly long lines.

Run 1

Code Structure: Well-organized methods separate constructor injection, field injection, validation, and runner behavior. Nesting: Mostly shallow, though validateFields combines conditionals and loops, and field injection nests exception handling inside a loop. Clarity of intent: Descriptive method names, annotations, and informative error messages make the purpose clear; legacy f-prefixed fields and names such as each and iare are less expressive. Code length: Generally concise, but repeated annotation lookups and lengthy error-message concatenations add visual bulk. Action granularity: Statements generally perform one action per line, although chained reflection calls require extra parsing. Reading flow: Consistent formatting and small helper methods support natural reading; wrapped expressions and reliance on inherited JUnit behavior slightly interrupt comprehension.

Run 2

Code Structure: Responsibilities are logically divided into clearly named methods for construction, injection, validation, and runner customization. Nesting: Mostly shallow, although validateFields combines an outer conditional, loops, and conditionals, increasing reading effort. Clarity of intent: Descriptive method names, explicit validation, and helpful error messages make the purpose clear; abbreviated names such as iare and legacy f-prefixed fields slightly reduce clarity. Code length: Generally appropriate, but repeated annotation lookups and verbose error-message concatenations add bulk. Action granularity: Statements usually perform one action each, with only a few chained reflection calls requiring extra interpretation. Reading flow: Consistent formatting and a natural progression from test creation to validation support readability, though long wrapped expressions interrupt the flow.

Run 3

Code Structure: Responsibilities are logically separated into constructor injection, field injection, validation, and runner overrides. Nesting: Most methods are flat, but validateFields contains moderately nested conditionals and loops. Clarity of intent: Descriptive method names and the class documentation clearly communicate parameterized test behavior; names such as each, iare, and fParameters are less expressive. Code length: Generally concise, though repeated annotation lookups and lengthy exception-message concatenations add verbosity. Action granularity: Statements typically perform one action per line, with some chained reflection calls requiring extra attention. Reading flow: Creation precedes validation and supporting helpers, providing a coherent progression. Wrapped expressions and dense validation logic occasionally interrupt scanning, but overall the code is easy to follow.