Sample

Schnappinger/junit4/org.junit.experimental.theories.Theories

Human rating uses the original dataset scale.

Human2.01
Lines255

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
20.1Δ 14.1
Scalabrino0.6560–1; higher is more readable
29.5Δ 23.5
Dorn0.0960–1; higher is more readable
32.3Δ 26.4
Mi0.0290–1; higher is more readable
4.0Δ 2.0
LLOC110Logical lines; fewer is more readable
22.1Δ 16.2
DeepSeek V4 Pro140–20; mean of three runs
29.9Δ 23.9
GPT-6.1 Sol150–20; mean of three runs
25.7Δ 19.8
BTTF0.2910–1; higher is more readable
19.8Δ 13.9
Human2.011–4; original rating
5.9

Views

Source code

package org.junit.experimental.theories; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import org.junit.Assert; import org.junit.Assume; import org.junit.experimental.theories.internal.Assignments; import org.junit.experimental.theories.internal.ParameterizedAssertionError; import org.junit.internal.AssumptionViolatedException; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; public class Theories extends BlockJUnit4ClassRunner { public Theories(Class<?> klass) throws InitializationError { super(klass); } @Override protected void collectInitializationErrors(List<Throwable> errors) { super.collectInitializationErrors(errors); validateDataPointFields(errors); validateDataPointMethods(errors); } private void validateDataPointFields(List<Throwable> errors) { Field[] fields = getTestClass().getJavaClass().getDeclaredFields(); for (Field field : fields) { if (field.getAnnotation(DataPoint.class) == null && field.getAnnotation(DataPoints.class) == null) { continue; } if (!Modifier.isStatic(field.getModifiers())) { errors.add(new Error("DataPoint field " + field.getName() + " must be static")); } if (!Modifier.isPublic(field.getModifiers())) { errors.add(new Error("DataPoint field " + field.getName() + " must be public")); } } } private void validateDataPointMethods(List<Throwable> errors) { Method[] methods = getTestClass().getJavaClass().getDeclaredMethods(); for (Method method : methods) { if (method.getAnnotation(DataPoint.class) == null && method.getAnnotation(DataPoints.class) == null) { continue; } if (!Modifier.isStatic(method.getModifiers())) { errors.add(new Error("DataPoint method " + method.getName() + " must be static")); } if (!Modifier.isPublic(method.getModifiers())) { errors.add(new Error("DataPoint method " + method.getName() + " must be public")); } } } @Override protected void validateConstructor(List<Throwable> errors) { validateOnlyOneConstructor(errors); } @Override protected void validateTestMethods(List<Throwable> errors) { for (FrameworkMethod each : computeTestMethods()) { if (each.getAnnotation(Theory.class) != null) { each.validatePublicVoid(false, errors); each.validateNoTypeParametersOnArgs(errors); } else { each.validatePublicVoidNoArg(false, errors); } for (ParameterSignature signature : ParameterSignature.signatures(each.getMethod())) { ParametersSuppliedBy annotation = signature.findDeepAnnotation(ParametersSuppliedBy.class); if (annotation != null) { validateParameterSupplier(annotation.value(), errors); } } } } private void validateParameterSupplier(Class<? extends ParameterSupplier> supplierClass, List<Throwable> errors) { Constructor<?>[] constructors = supplierClass.getConstructors(); if (constructors.length != 1) { errors.add(new Error("ParameterSupplier " + supplierClass.getName() + " must have only one constructor (either empty or taking only a TestClass)")); } else { Class<?>[] paramTypes = constructors[0].getParameterTypes(); if (!(paramTypes.length == 0) && !paramTypes[0].equals(TestClass.class)) { errors.add(new Error("ParameterSupplier " + supplierClass.getName() + " constructor must take either nothing or a single TestClass instance")); } } } @Override protected List<FrameworkMethod> computeTestMethods() { List<FrameworkMethod> testMethods = new ArrayList<FrameworkMethod>(super.computeTestMethods()); List<FrameworkMethod> theoryMethods = getTestClass().getAnnotatedMethods(Theory.class); testMethods.removeAll(theoryMethods); testMethods.addAll(theoryMethods); return testMethods; } @Override public Statement methodBlock(final FrameworkMethod method) { return new TheoryAnchor(method, getTestClass()); } public static class TheoryAnchor extends Statement { private int successes = 0; private FrameworkMethod fTestMethod; private TestClass fTestClass; private List<AssumptionViolatedException> fInvalidParameters = new ArrayList<AssumptionViolatedException>(); public TheoryAnchor(FrameworkMethod method, TestClass testClass) { fTestMethod = method; fTestClass = testClass; } private TestClass getTestClass() { return fTestClass; } @Override public void evaluate() throws Throwable { runWithAssignment(Assignments.allUnassigned( fTestMethod.getMethod(), getTestClass())); //if this test method is not annotated with Theory, then no successes is a valid case boolean hasTheoryAnnotation = fTestMethod.getAnnotation(Theory.class) != null; if (successes == 0 && hasTheoryAnnotation) { Assert .fail("Never found parameters that satisfied method assumptions. Violated assumptions: " + fInvalidParameters); } } protected void runWithAssignment(Assignments parameterAssignment) throws Throwable { if (!parameterAssignment.isComplete()) { runWithIncompleteAssignment(parameterAssignment); } else { runWithCompleteAssignment(parameterAssignment); } } protected void runWithIncompleteAssignment(Assignments incomplete) throws Throwable { for (PotentialAssignment source : incomplete .potentialsForNextUnassigned()) { runWithAssignment(incomplete.assignNext(source)); } } protected void runWithCompleteAssignment(final Assignments complete) throws Throwable { new BlockJUnit4ClassRunner(getTestClass().getJavaClass()) { @Override protected void collectInitializationErrors( List<Throwable> errors) { // do nothing } @Override public Statement methodBlock(FrameworkMethod method) { final Statement statement = super.methodBlock(method); return new Statement() { @Override public void evaluate() throws Throwable { try { statement.evaluate(); handleDataPointSuccess(); } catch (AssumptionViolatedException e) { handleAssumptionViolation(e); } catch (Throwable e) { reportParameterizedError(e, complete .getArgumentStrings(nullsOk())); } } }; } @Override protected Statement methodInvoker(FrameworkMethod method, Object test) { return methodCompletesWithParameters(method, complete, test); } @Override public Object createTest() throws Exception { Object[] params = complete.getConstructorArguments(); if (!nullsOk()) { Assume.assumeNotNull(params); } return getTestClass().getOnlyConstructor().newInstance(params); } }.methodBlock(fTestMethod).evaluate(); } private Statement methodCompletesWithParameters( final FrameworkMethod method, final Assignments complete, final Object freshInstance) { return new Statement() { @Override public void evaluate() throws Throwable { final Object[] values = complete.getMethodArguments(); if (!nullsOk()) { Assume.assumeNotNull(values); } method.invokeExplosively(freshInstance, values); } }; } protected void handleAssumptionViolation(AssumptionViolatedException e) { fInvalidParameters.add(e); } protected void reportParameterizedError(Throwable e, Object... params) throws Throwable { if (params.length == 0) { throw e; } throw new ParameterizedAssertionError(e, fTestMethod.getName(), params); } private boolean nullsOk() { Theory annotation = fTestMethod.getMethod().getAnnotation( Theory.class); if (annotation == null) { return false; } return annotation.nullsAccepted(); } protected void handleDataPointSuccess() { successes++; } } }

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.10713.552−353.547
Source linesThe number of non-empty source lines.255+102
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.289−6.434

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

Score0.656

Feature contributions

FeatureValueContribution
(log-odds)
Indentation frequencyHow rapidly indentation changes from line to line.253+8.014
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.255−7.992
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.253−5.385
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.254.95+3.154
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.117.949−1.331
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.118+1.099
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 = -2.24 (log-odds).
Score = sigmoid(-2.24) = 0.096.

Score0.029
Score110
Run 1

The code is generally well-structured with clear method separation and purpose. It uses flat control flow in most places and maintains reasonable action granularity. However, readability is reduced by some long lines (especially validation error messages), redundant checks in validateDataPointFields/Methods, and the nested anonymous class inside TheoryAnchor.runWithCompleteAssignment which creates a complex reading flow. The TheoryAnchor inner class has somewhat unclear field naming (prefix 'f') and mixed responsibility, but overall intent is understandable. Some methods like computeTestMethods use non-obvious reordering logic that could benefit from a comment.

Run 2

The code has clear method names and logical separation of validation concerns, but it suffers from readability issues. The `TheoryAnchor` inner class creates an anonymous `BlockJUnit4ClassRunner` inside `runWithCompleteAssignment`, adding deep nesting and making the flow hard to follow. The `evaluate` method contains nested anonymous `Statement` classes that obscure the control flow. Several methods break the single-responsibility principle (`runWithCompleteAssignment` does too much), and some lines are overly long. The validation methods for DataPoint fields and methods are repetitive, violating DRY principles. While basic structure and naming are good, the complex nested callbacks and anonymous classes hurt clarity.

Run 3

The code has a logical structure with clear method separation, but suffers from several readability issues. The nesting in `runWithCompleteAssignment` is deep (4-5 levels), making it hard to follow the flow. The anonymous inner classes add complexity and obscure intent. Some methods like `validateParameterSupplier` are clear, while others mix validation and execution concerns. The action granularity is generally good - one operation per line - but long method signatures and chained calls reduce readability. Variable names like `fTestMethod` and `fInvalidParameters` use outdated Hungarian notation. The reading flow is disrupted by the deeply nested anonymous classes and scattered validation logic. While the code is maintainable, it requires careful reading to understand the theory testing mechanism, particularly the anonymous `BlockJUnit4ClassRunner` instantiation.

Run 1

Code Structure: Validation and execution responsibilities are separated into well-named methods, although the nested runner mixes orchestration, construction, and exception handling. Nesting: Most methods are shallow, but anonymous runner and Statement classes create substantial nesting in runWithCompleteAssignment. Clarity of intent: Descriptive method names and explicit exception handling communicate purpose; legacy f-prefixed fields and the awkward constructor-parameter condition reduce clarity. Code length: Generally justified, though field/method validation duplicates logic and anonymous-class boilerplate adds bulk. Action granularity: Statements generally perform one action per line, making individual operations easy to follow. Reading flow: Validation precedes execution in a logical order, and assignment handling is cleanly decomposed; inconsistent line wrapping, chained anonymous-class execution, and framework callbacks make the execution path harder to trace.

Run 2

Code Structure: Validation and execution responsibilities are organized into focused methods and a dedicated nested class, though anonymous runner customization adds complexity. Nesting: Most methods are shallow, but nested anonymous classes, overrides, and exception handling make runWithCompleteAssignment harder to follow. Clarity of intent: Descriptive method names and explicit error messages communicate purpose well; legacy f-prefixed fields and the negated constructor condition reduce clarity. Code length: Generally proportionate to functionality, although field/method validation duplicates logic and anonymous-class boilerplate adds verbosity. Action granularity: Statements generally perform one action per line, with only a few chained expressions demanding extra attention. Reading flow: Validation proceeds naturally into execution, and helper methods support navigation. However, inconsistent line wrapping, recursive assignment processing, and transitions between runner and statement contexts interrupt the flow and require familiarity with JUnit internals.

Run 3

Code Structure: Well-separated validation and execution methods provide logical organization, though the large inner class and anonymous runner concentrate complexity. Nesting: Most validation is shallow, but nested anonymous classes, overrides, and exception handling make execution harder to follow. Clarity of intent: Descriptive method names and explicit error messages communicate purpose; legacy f-prefixed fields and the awkward constructor-condition expression reduce clarity. Code length: Generally justified, but duplicated field/method validation and verbose anonymous classes add bulk. Action granularity: Statements usually perform one action per line, with clearly separated checks and updates. Reading flow: Validation progresses naturally into test discovery and execution, but recursive assignment processing, overridden runner behavior, and inconsistent line wrapping interrupt the flow.