Sample

Schnappinger/junit4/org.junit.internal.runners.TestClass

Human rating uses the original dataset scale.

Human3.98
Lines109

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
34.1Δ 53.0
Scalabrino0.6180–1; higher is more readable
25.0Δ 62.1
Dorn0.3970–1; higher is more readable
55.4Δ 31.7
Mi0.3420–1; higher is more readable
21.5Δ 65.7
LLOC50Logical lines; fewer is more readable
39.4Δ 47.7
DeepSeek V4 Pro16.330–20; mean of three runs
53.1Δ 34.0
GPT-6.1 Sol170–20; mean of three runs
55.3Δ 31.8
BTTF0.5470–1; higher is more readable
49.5Δ 37.6
Human3.981–4; original rating
87.1

Views

Source code

package org.junit.internal.runners; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.internal.MethodSorter; import org.junit.runners.BlockJUnit4ClassRunner; /** * @deprecated Included for backwards compatibility with JUnit 4.4. Will be * removed in the next release. Please use * {@link BlockJUnit4ClassRunner} in place of {@link JUnit4ClassRunner}. */ @Deprecated public class TestClass { private final Class<?> fClass; public TestClass(Class<?> klass) { fClass = klass; } public List<Method> getTestMethods() { return getAnnotatedMethods(Test.class); } List<Method> getBefores() { return getAnnotatedMethods(BeforeClass.class); } List<Method> getAfters() { return getAnnotatedMethods(AfterClass.class); } public List<Method> getAnnotatedMethods(Class<? extends Annotation> annotationClass) { List<Method> results = new ArrayList<Method>(); for (Class<?> eachClass : getSuperClasses(fClass)) { Method[] methods = MethodSorter.getDeclaredMethods(eachClass); for (Method eachMethod : methods) { Annotation annotation = eachMethod.getAnnotation(annotationClass); if (annotation != null && !isShadowed(eachMethod, results)) { results.add(eachMethod); } } } if (runsTopToBottom(annotationClass)) { Collections.reverse(results); } return results; } private boolean runsTopToBottom(Class<? extends Annotation> annotation) { return annotation.equals(Before.class) || annotation.equals(BeforeClass.class); } private boolean isShadowed(Method method, List<Method> results) { for (Method each : results) { if (isShadowed(method, each)) { return true; } } return false; } private boolean isShadowed(Method current, Method previous) { if (!previous.getName().equals(current.getName())) { return false; } if (previous.getParameterTypes().length != current.getParameterTypes().length) { return false; } for (int i = 0; i < previous.getParameterTypes().length; i++) { if (!previous.getParameterTypes()[i].equals(current.getParameterTypes()[i])) { return false; } } return true; } private List<Class<?>> getSuperClasses(Class<?> testClass) { ArrayList<Class<?>> results = new ArrayList<Class<?>>(); Class<?> current = testClass; while (current != null) { results.add(current); current = current.getSuperclass(); } return results; } public Constructor<?> getConstructor() throws SecurityException, NoSuchMethodException { return fClass.getConstructor(); } public Class<?> getJavaClass() { return fClass; } public String getName() { return fClass.getName(); } }

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.3999.547−131.985
Source linesThe number of non-empty source lines.109+43.6
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.568−6.851

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

Score0.618

Feature contributions

FeatureValueContribution
(log-odds)
Indentation frequencyHow rapidly indentation changes from line to line.105+2.895
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.110−2.858
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.105−1.989
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.108.839+1.112
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.92+0.68
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.91.982−0.231
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.107−0.097

Intercept 0.07 + feature contributions = -0.419 (log-odds).
Score = sigmoid(-0.419) = 0.397.

Score0.342
Score50
Run 1

The code is well-structured and readable. It uses clear method names that express intent (e.g., 'getAnnotatedMethods', 'isShadowed', 'runsTopToBottom'), logical organization, and shallow nesting. Most actions are granular, with one operation per line, especially in loops and method chains. The 'isShadowed' method is slightly verbose but clear. Field naming ('fClass') is dated but consistent with older JUnit style. Overall, the flow is natural and easy to follow, with no major ambiguities.

Run 2

The code is generally readable with a clear structure: fields, constructors, public methods, then private helpers. Methods are small and focused, with mostly one action per line. Naming is mostly clear (e.g., `isShadowed`, `getSuperClasses`). However, there are some readability issues: the `isShadowed(Method, Method)` method uses repetitive array comparison instead of `Arrays.equals`, making it longer than necessary. The `runsTopToBottom` method hardcodes annotation types, which is not obvious from the method name. The `getBefores` and `getAfters` methods are misleadingly named—they actually return `@BeforeClass` and `@AfterClass` methods, not `@Before`/`@After`. The import of `org.junit.Before` is unused, and the use of the outdated `f` prefix for fields (e.g., `fClass`) is a minor style inconsistency. Overall, the code is understandable but could be improved with clearer naming and less verbose helper methods.

Run 3

The code is well-structured with clear separation of concerns and logical method grouping. Nesting is minimal (max 3 levels), and intent is obvious from method names like `getAnnotatedMethods` and `isShadowed`. Length is appropriate—each method is concise and focused. Action granularity is good: most lines perform one operation, though the `if` condition in `getAnnotatedMethods` combines two checks. Reading flow is natural—methods are ordered logically, with helper methods placed after their callers. Minor deductions: the deprecated `@deprecated` Javadoc formatting is awkward, and `getBefores()` returning `BeforeClass` methods (not `Before`) is potentially misleading without deeper context. Overall, highly readable legacy code.

Run 1

Code Structure: Well organized into small, focused methods, separating annotation discovery, shadowing checks, hierarchy traversal, and accessors. Nesting: Mostly shallow, although annotation discovery uses two nested loops and a conditional. Clarity of intent: Descriptive method names make the overall purpose clear, but getBefores/getAfters do not explicitly indicate class-level hooks, and superclass ordering and shadowing semantics require inference. Code length: Concise overall; repeated parameter-type retrieval adds minor verbosity. Action granularity: Statements generally perform one action per line, with readable conditions and early returns. Reading flow: Consistent formatting and straightforward control flow support easy scanning, though legacy naming such as fClass and each slightly reduces natural readability.

Run 2

Code Structure: Well-organized into small methods separating annotation discovery, shadow detection, hierarchy traversal, and accessors. Nesting: Mostly shallow; annotation discovery has two loops and a conditional, but remains manageable. Clarity of intent: Method names generally communicate purpose, although getBefores/getAfters obscure their class-level scope, and annotation ordering and shadowing rules lack explanation. Generic names such as results and each slightly reduce precision. Code length: Concise overall, though repeated parameter-type retrieval adds verbosity. Action granularity: Statements generally perform one action per line, making operations easy to follow. Reading flow: Consistent formatting, early returns, and straightforward control flow support natural reading; overloaded isShadowed methods require some cross-referencing.

Run 3

Code Structure: Well-organized, short methods separate annotation discovery, shadow detection, superclass traversal, and accessors. Nesting: Generally shallow; annotation discovery uses two nested loops and a conditional, which remains manageable. Clarity of intent: Descriptive method names make the reflection-based purpose clear, though fClass and each are less informative, and getBefores/getAfters do not explicitly indicate class-level hooks. Code length: Mostly concise, with some repetitive parameter-type access in shadow detection. Action granularity: Statements generally perform one action per line, making individual operations easy to follow. Reading flow: Discovery proceeds naturally through filtering and ordering, supported by nearby helper methods; early returns simplify signature comparisons. The reason for reversing execution order and the precise shadowing semantics require some JUnit knowledge.