Sample

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

Human rating uses the original dataset scale.

Human3.72
Lines180

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
24.1Δ 17.5
Scalabrino0.7220–1; higher is more readable
43.5Δ 1.9
Dorn0.2670–1; higher is more readable
45.9Δ 4.3
Mi0.5880–1; higher is more readable
57.4Δ 15.8
LLOC89Logical lines; fewer is more readable
26.9Δ 14.7
DeepSeek V4 Pro170–20; mean of three runs
66.8Δ 25.2
GPT-6.1 Sol16.670–20; mean of three runs
48.0Δ 6.4
BTTF0.4620–1; higher is more readable
41.3Δ 0.3
Human3.721–4; original rating
41.6

Views

Source code

package org.junit.internal.runners; import junit.extensions.TestDecorator; import junit.framework.AssertionFailedError; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestListener; import junit.framework.TestResult; import junit.framework.TestSuite; import org.junit.runner.Describable; import org.junit.runner.Description; import org.junit.runner.Runner; import org.junit.runner.manipulation.Filter; import org.junit.runner.manipulation.Filterable; import org.junit.runner.manipulation.NoTestsRemainException; import org.junit.runner.manipulation.Sortable; import org.junit.runner.manipulation.Sorter; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunNotifier; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public class JUnit38ClassRunner extends Runner implements Filterable, Sortable { private static final class OldTestClassAdaptingListener implements TestListener { private final RunNotifier fNotifier; private OldTestClassAdaptingListener(RunNotifier notifier) { fNotifier = notifier; } public void endTest(Test test) { fNotifier.fireTestFinished(asDescription(test)); } public void startTest(Test test) { fNotifier.fireTestStarted(asDescription(test)); } // Implement junit.framework.TestListener public void addError(Test test, Throwable e) { Failure failure = new Failure(asDescription(test), e); fNotifier.fireTestFailure(failure); } private Description asDescription(Test test) { if (test instanceof Describable) { Describable facade = (Describable) test; return facade.getDescription(); } return Description.createTestDescription(getEffectiveClass(test), getName(test)); } private Class<? extends Test> getEffectiveClass(Test test) { return test.getClass(); } private String getName(Test test) { if (test instanceof TestCase) { return ((TestCase) test).getName(); } else { return test.toString(); } } public void addFailure(Test test, AssertionFailedError t) { addError(test, t); } } private volatile Test fTest; public JUnit38ClassRunner(Class<?> klass) { this(new TestSuite(klass.asSubclass(TestCase.class))); } public JUnit38ClassRunner(Test test) { super(); setTest(test); } @Override public void run(RunNotifier notifier) { TestResult result = new TestResult(); result.addListener(createAdaptingListener(notifier)); getTest().run(result); } public TestListener createAdaptingListener(final RunNotifier notifier) { return new OldTestClassAdaptingListener(notifier); } @Override public Description getDescription() { return makeDescription(getTest()); } private static Description makeDescription(Test test) { if (test instanceof TestCase) { TestCase tc = (TestCase) test; return Description.createTestDescription(tc.getClass(), tc.getName(), getAnnotations(tc)); } else if (test instanceof TestSuite) { TestSuite ts = (TestSuite) test; String name = ts.getName() == null ? createSuiteDescription(ts) : ts.getName(); Description description = Description.createSuiteDescription(name); int n = ts.testCount(); for (int i = 0; i < n; i++) { Description made = makeDescription(ts.testAt(i)); description.addChild(made); } return description; } else if (test instanceof Describable) { Describable adapter = (Describable) test; return adapter.getDescription(); } else if (test instanceof TestDecorator) { TestDecorator decorator = (TestDecorator) test; return makeDescription(decorator.getTest()); } else { // This is the best we can do in this case return Description.createSuiteDescription(test.getClass()); } } /** * Get the annotations associated with given TestCase. * @param test the TestCase. */ private static Annotation[] getAnnotations(TestCase test) { try { Method m = test.getClass().getMethod(test.getName()); return m.getDeclaredAnnotations(); } catch (SecurityException e) { } catch (NoSuchMethodException e) { } return new Annotation[0]; } private static String createSuiteDescription(TestSuite ts) { int count = ts.countTestCases(); String example = count == 0 ? "" : String.format(" [example: %s]", ts.testAt(0)); return String.format("TestSuite with %s tests%s", count, example); } public void filter(Filter filter) throws NoTestsRemainException { if (getTest() instanceof Filterable) { Filterable adapter = (Filterable) getTest(); adapter.filter(filter); } else if (getTest() instanceof TestSuite) { TestSuite suite = (TestSuite) getTest(); TestSuite filtered = new TestSuite(suite.getName()); int n = suite.testCount(); for (int i = 0; i < n; i++) { Test test = suite.testAt(i); if (filter.shouldRun(makeDescription(test))) { filtered.addTest(test); } } setTest(filtered); if (filtered.testCount() == 0) { throw new NoTestsRemainException(); } } } public void sort(Sorter sorter) { if (getTest() instanceof Sortable) { Sortable adapter = (Sortable) getTest(); adapter.sort(sorter); } } private void setTest(Test test) { fTest = test; } private Test getTest() { return fTest; } }

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.7678.99−253.407
Source linesThe number of non-empty source lines.180+72
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.341−6.511

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

Score0.722

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.181−5.372
Indentation frequencyHow rapidly indentation changes from line to line.175+5.316
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.175−3.595
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.179.926+2.105
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.92.972+0.696
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.92.917−0.27
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.093+0.041

Intercept 0.07 + feature contributions = -1.01 (log-odds).
Score = sigmoid(-1.01) = 0.267.

Score0.588
Score89
Run 1

The code is generally well-structured with clear separation of concerns, minimal nesting, and good use of descriptive method names. The listener adapter class is well-encapsulated, and the delegation patterns are straightforward. However, readability is slightly reduced by the empty catch blocks in getAnnotations, the somewhat convoluted conditional chain in makeDescription, and the mixed concern of the filter method needing to handle both Filterable and TestSuite cases. The blanket catch blocks silently swallowing exceptions also hurt intent clarity. Overall, the code is readable but could benefit from refactoring the getAnnotations method and the makeDescription branch logic.

Run 2

The code is well-structured and readable. It uses clear class and method names, follows consistent formatting, and maintains a logical separation of concerns. The JUnit38ClassRunner class is focused, delegating to helper methods and inner classes appropriately. Nesting is mostly shallow; the longest method (makeDescription) uses a clear if-else chain rather than deep nesting. Intent is generally clear, though some legacy naming (e.g., fNotifier, fTest) and the dual constructor approach require minor inference. Code length is reasonable, with concise one-action-per-line style. The reading flow is natural, moving from high-level run logic down to utility methods. Minor deductions: the getAnnotations method has empty catch blocks, and the createSuiteDescription logic is slightly dense. Overall, this is production-quality, maintainable code.

Run 3

The code is highly readable. It is well-structured, with clear separation of concerns between methods and a logical organization. Nesting is minimal and well-controlled; the deepest constructs are simple if-else chains rather than deeply nested blocks. Intent is clear: the class adapts JUnit 3.8 tests to the JUnit 4 Runner API, and method names reflect that purpose. Code length is appropriate, neither too verbose nor excessively terse. Action granularity is mostly one action per line, except for a few one-line if statements, which remain clear. Reading flow is natural, with private helper methods placed logically near their usage, though the `makeDescription` method is slightly long but still easy to follow. The only minor blemish is the empty `catch` blocks in `getAnnotations`, but this is a common pattern for reflection. Overall, the code is well-organized, self-explanatory, and maintainable.

Run 1

Code Structure: Responsibilities are logically separated into a listener adapter and focused methods for execution, descriptions, filtering, and sorting. Nesting: Generally shallow, though filtering contains a loop and nested condition, and description generation uses a lengthy type-dispatch chain. Clarity of intent: Method names clearly communicate purpose; abbreviated variables (tc, ts, n, m), legacy field prefixes, and unexplained empty exception handlers reduce clarity. Code length: Mostly concise, with some trivial wrappers and repeated type checks adding minor verbosity. Action granularity: Statements generally perform one action per line, making operations easy to follow. Reading flow: Consistent formatting and cohesive methods support natural reading, although the nested class appears before the runner's main functionality, and recursive description handling requires some backtracking.

Run 2

Code Structure: Well-organized methods separate listener adaptation, description generation, filtering, and sorting; the nested listener keeps related behavior together. Nesting: Generally shallow, although filtering combines conditional branches, a loop, and an inner condition. Clarity of intent: Descriptive method names and familiar JUnit types communicate purpose, but abbreviated variables, legacy f-prefixed fields, and unexplained empty catch blocks reduce clarity. Code length: Mostly concise, with some minor verbosity from trivial wrappers, repeated getTest() calls, and explicit casts. Action granularity: Statements generally perform one action per line; a few chained calls and ternary expressions modestly increase reading effort. Reading flow: Execution and delegation are easy to follow, though the lengthy instanceof chain in makeDescription and inconsistent import grouping slightly interrupt the flow.

Run 3

Code Structure: Well-organized methods separate listener adaptation, description creation, filtering, and sorting; the nested listener encapsulates related behavior. Nesting: Generally shallow, although filtering combines branching, iteration, and a conditional, and description creation uses a lengthy type-dispatch chain. Clarity of intent: Descriptive method names make the runner's purpose clear; abbreviated variables such as tc, ts, n, and m, legacy f-prefixed fields, and unexplained empty catch blocks reduce clarity. Code length: Mostly concise, with small focused methods, though trivial wrappers and repeated type checks add some verbosity. Action granularity: Statements generally perform one action per line, with only occasional compound expressions. Reading flow: Consistent formatting and cohesive methods support natural reading, but imports are not cleanly grouped, related description helpers are split between classes, and repeated casts slightly interrupt the flow.