Sample

Schnappinger/junit4/org.junit.rules.TestWatcher

Human rating uses the original dataset scale.

Human4
Lines146

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
51.5Δ 48.2
Scalabrino0.7690–1; higher is more readable
54.5Δ 45.2
Dorn0.8380–1; higher is more readable
91.7Δ 7.9
Mi0.4710–1; higher is more readable
29.4Δ 70.3
LLOC39Logical lines; fewer is more readable
43.9Δ 55.8
DeepSeek V4 Pro16.670–20; mean of three runs
59.9Δ 39.8
GPT-6.1 Sol170–20; mean of three runs
55.3Δ 44.4
BTTF0.7120–1; higher is more readable
84.2Δ 15.5
Human41–4; original rating
99.7

Views

Source code

package org.junit.rules; import java.util.ArrayList; import java.util.List; import org.junit.internal.AssumptionViolatedException; import org.junit.runner.Description; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; /** * TestWatcher is a base class for Rules that take note of the testing * action, without modifying it. For example, this class will keep a log of each * passing and failing test: * * <pre> * public static class WatchmanTest { * private static String watchedLog; * * &#064;Rule * public TestWatcher watchman= new TestWatcher() { * &#064;Override * protected void failed(Throwable e, Description description) { * watchedLog+= description + &quot;\n&quot;; * } * * &#064;Override * protected void succeeded(Description description) { * watchedLog+= description + &quot; &quot; + &quot;success!\n&quot;; * } * }; * * &#064;Test * public void fails() { * fail(); * } * * &#064;Test * public void succeeds() { * } * } * </pre> * * @since 4.9 */ public abstract class TestWatcher implements TestRule { public Statement apply(final Statement base, final Description description) { return new Statement() { @Override public void evaluate() throws Throwable { List<Throwable> errors = new ArrayList<Throwable>(); startingQuietly(description, errors); try { base.evaluate(); succeededQuietly(description, errors); } catch (AssumptionViolatedException e) { errors.add(e); skippedQuietly(e, description, errors); } catch (Throwable e) { errors.add(e); failedQuietly(e, description, errors); } finally { finishedQuietly(description, errors); } MultipleFailureException.assertEmpty(errors); } }; } private void succeededQuietly(Description description, List<Throwable> errors) { try { succeeded(description); } catch (Throwable e) { errors.add(e); } } private void failedQuietly(Throwable e, Description description, List<Throwable> errors) { try { failed(e, description); } catch (Throwable e1) { errors.add(e1); } } private void skippedQuietly(AssumptionViolatedException e, Description description, List<Throwable> errors) { try { skipped(e, description); } catch (Throwable e1) { errors.add(e1); } } private void startingQuietly(Description description, List<Throwable> errors) { try { starting(description); } catch (Throwable e) { errors.add(e); } } private void finishedQuietly(Description description, List<Throwable> errors) { try { finished(description); } catch (Throwable e) { errors.add(e); } } /** * Invoked when a test succeeds */ protected void succeeded(Description description) { } /** * Invoked when a test fails */ protected void failed(Throwable e, Description description) { } /** * Invoked when a test is skipped due to a failed assumption. */ protected void skipped(AssumptionViolatedException e, Description description) { } /** * Invoked when a test is about to start */ protected void starting(Description description) { } /** * Invoked when a test method finishes (whether passing or failing) */ protected void finished(Description description) { } }

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.2682−88.506
Source linesThe number of non-empty source lines.146+58.4
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.357−6.536

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

Score0.769

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.147−4.168
Indentation frequencyHow rapidly indentation changes from line to line.102+2.791
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.145.886+1.629
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.85.823+0.58
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.1+0.398
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.06+0.364
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.86.959−0.018

Intercept 0.07 + feature contributions = 1.646 (log-odds).
Score = sigmoid(1.646) = 0.838.

Score0.471
Score39
Run 1

The code has a clear logical structure with good separation of concerns: a public `apply` method, private 'quietly' wrapper methods, and protected hook methods. Nesting is minimal except for a single anonymous inner class and a try-catch-finally block in `evaluate()`. Each 'quietly' method follows the same pattern — try-call-hook, catch-and-accumulate — making intent obvious. The code is concise; no obvious unnecessary length. Action granularity is mostly one action per line within the try/catch blocks. Reading flow is natural: setup, execution, outcome-specific handling, finally, and error assertion. The main weakness is some duplication across the 'quietly' methods, which slightly reduces readability due to repetition. The Javadoc example helps clarify usage despite a minor indentation issue. Overall, the code is readable and maintainable, with only modest opportunities for improvement such as extracting a common 'notifyQuietly' helper.

Run 2

The code is well-structured with clear separation of concerns. The main apply() method uses a single-level try-catch-finally block that is easy to follow. Each helper method (succeededQuietly, failedQuietly, etc.) has a single responsibility and wraps exceptions consistently. The class documentation with usage example improves clarity of intent significantly. The quiet helpers avoid nesting by delegating to protected methods, keeping error handling flat. One minor issue: the large Javadoc example adds some length but remains useful. Overall, the code reads naturally from setup → execution → handling → cleanup, and each line performs one logical action.

Run 3

The code demonstrates strong readability through clear structure and organization. The TestWatcher class has a single, well-defined responsibility with logical separation of concerns. The apply method uses a flat try-catch-finally structure with minimal nesting, and each lifecycle event is handled in its own clearly named method. The 'Quietly' helper methods follow a consistent pattern, wrapping callbacks with exception handling. Action granularity is excellent—each method performs one logical action. Reading flow is natural, progressing from setup through execution to completion. The Javadoc example, while verbose, provides helpful context. Minor deductions: the anonymous inner Statement class adds slight nesting, and some parameter alignments create visual noise. However, the code lacks excessive comments, keeps methods concise, and uses descriptive naming throughout. The only ambiguity is the purpose of error collection before the final assertEmpty call, though the MultipleFailureException makes this reasonably clear.

Run 1

Code Structure: Well-organized lifecycle orchestration, private exception-handling helpers, and protected extension hooks. Nesting: The anonymous Statement and try/catch introduce moderate nesting, but helper methods keep it manageable. Clarity of intent: Descriptive lifecycle names and documentation clearly communicate test observation and failure aggregation; 'Quietly' slightly obscures that exceptions are collected rather than ignored. Code length: Reasonably concise, though five similar wrappers and the lengthy documentation example add repetition. Action granularity: Each statement performs a single action, with no compressed multi-action lines. Reading flow: Evaluation follows a natural start, execute, outcome, finish sequence; helper and hook ordering does not fully match that lifecycle, and inconsistent formatting in the documentation example slightly interrupts readability.

Run 2

Code Structure: Well organized into lifecycle orchestration, exception-handling helpers, and documented extension hooks. Nesting: Moderate nesting from the anonymous Statement and try/catch/finally, but individual methods remain shallow. Clarity of intent: Descriptive lifecycle names and documentation clearly communicate test observation and error collection; generic exception names slightly reduce precision. Code length: Reasonably concise, though five similar helper methods repeat exception-handling logic and the lengthy example adds bulk. Action granularity: Each statement performs a single clear action, with no compressed multi-action lines. Reading flow: The evaluation sequence naturally follows start, execution, outcome, finish, and failure reporting. Minor inconsistencies in line wrapping and example indentation, plus separation between helpers and corresponding hooks, slightly interrupt readability.

Run 3

Code Structure: Well organized into lifecycle orchestration, exception-handling helpers, and overridable callbacks. Nesting: Moderate nesting from the anonymous Statement and try/catch blocks, but individual methods remain simple. Clarity of intent: Descriptive lifecycle names and documentation clearly explain test observation and error collection; generic exception names such as e1 are less informative. Code length: Reasonably concise, though five similar helper methods introduce repetition and the lengthy documentation example adds visual bulk. Action granularity: Each statement generally performs one action, making execution easy to track. Reading flow: The main method follows the natural start, execute, report outcome, finish sequence, followed by failure aggregation. Separating helpers from callbacks requires some navigation, and inconsistent formatting in the documentation example slightly reduces readability.