2727import org .junit .platform .commons .util .Preconditions ;
2828
2929/**
30- * Mutable descriptor for a test or container that has been discovered by a
31- * {@link TestEngine}.
30+ * A descriptor with a mutable hierarchy for a test or container that has been
31+ * discovered by a {@link TestEngine}.
3232 *
3333 * @since 1.0
3434 * @see TestEngine
@@ -42,6 +42,9 @@ public interface TestDescriptor {
4242 * <p>Uniqueness must be guaranteed across an entire test plan,
4343 * regardless of how many engines are used behind the scenes.
4444 *
45+ * <p>The implementation must treat this property as immutable after test
46+ * discovery has completed.
47+ *
4548 * @return the {@code UniqueId} for this descriptor; never {@code null}
4649 */
4750 UniqueId getUniqueId ();
@@ -77,6 +80,9 @@ default String getLegacyReportingName() {
7780 /**
7881 * Get the set of {@linkplain TestTag tags} associated with this descriptor.
7982 *
83+ * <p>The implementation must treat this property as immutable after test
84+ * discovery has completed.
85+ *
8086 * @return the set of tags associated with this descriptor; never {@code null}
8187 * but potentially empty
8288 * @see TestTag
@@ -87,6 +93,9 @@ default String getLegacyReportingName() {
8793 * Get the {@linkplain TestSource source} of the test or container described
8894 * by this descriptor, if available.
8995 *
96+ * <p>The implementation must treat this property as immutable after test
97+ * discovery has completed.
98+ *
9099 * @see TestSource
91100 */
92101 Optional <TestSource > getSource ();
@@ -106,6 +115,9 @@ default String getLegacyReportingName() {
106115 /**
107116 * Get the immutable set of <em>children</em> of this descriptor.
108117 *
118+ * <p>The implementation must be consistent with {@link #isContainer()} such that
119+ * {@code !x.container()} implies {@code x.getChildren().isEmpty()}.
120+ *
109121 * @return the set of children of this descriptor; neither {@code null}
110122 * nor mutable, but potentially empty
111123 * @see #getDescendants()
@@ -141,6 +153,9 @@ default Set<? extends TestDescriptor> getAncestors() {
141153 * <p>A <em>descendant</em> is a child of this descriptor or a child of one of
142154 * its children, recursively.
143155 *
156+ * <p>The implementation must be consistent with {@link #isContainer()} such that
157+ * {@code !x.container()} implies {@code x.getDescendants().isEmpty()}.
158+ *
144159 * @see #getChildren()
145160 */
146161 default Set <? extends TestDescriptor > getDescendants () {
@@ -223,14 +238,24 @@ default boolean isRoot() {
223238 /**
224239 * Determine the {@link Type} of this descriptor.
225240 *
241+ * <p>The implementation must treat this property as immutable after test
242+ * discovery has completed.
243+ *
226244 * @return the descriptor type; never {@code null}.
227245 * @see #isContainer()
228246 * @see #isTest()
229247 */
230248 Type getType ();
231249
232250 /**
233- * Determine if this descriptor describes a container.
251+ * Determine if this descriptor describes a <em>container</em>.
252+ *
253+ * <p>A test descriptor is a <em>container</em> when it may contain other
254+ * containers or tests as its children. In addition to being a
255+ * <em>container</em> this test descriptor may also be a <em>test</em>.
256+ *
257+ * <p>The implementation must be consistent with {@link #getType()} such
258+ * that {@code x.isContainer()} equals {@code x.getType().isContainer()}.
234259 *
235260 * <p>The default implementation delegates to {@link Type#isContainer()}.
236261 */
@@ -239,7 +264,14 @@ default boolean isContainer() {
239264 }
240265
241266 /**
242- * Determine if this descriptor describes a test.
267+ * Determine if this descriptor describes a <em>test</em>.
268+ *
269+ * <p>A test descriptor is a <em>test</em> when it verifies expected
270+ * behavior when executed. In addition to being a <em>test</em> this
271+ * test descriptor may also be a <em>container</em>.
272+ *
273+ * <p>The implementation must be consistent with {@link #getType()} such
274+ * that {@code x.isTest()} equals {@code x.getType().isTest()}.
243275 *
244276 * <p>The default implementation delegates to {@link Type#isTest()}.
245277 */
@@ -250,6 +282,10 @@ default boolean isTest() {
250282 /**
251283 * Determine if this descriptor may register dynamic tests during execution.
252284 *
285+ * <p>The implementation must treat this property as immutable after test
286+ * discovery has completed and must be consistent with {@link #isContainer()}
287+ * such that {@code !x.container()} implies {@code !x.mayRegisterTests()}.
288+ *
253289 * <p>The default implementation assumes tests are usually known during
254290 * discovery and thus returns {@code false}.
255291 */
@@ -259,7 +295,7 @@ default boolean mayRegisterTests() {
259295
260296 /**
261297 * Determine if the supplied descriptor (or any of its descendants)
262- * {@linkplain TestDescriptor#isTest() is a test} or
298+ * {@linkplain TestDescriptor#isTest() is a <em> test</em> } or
263299 * {@linkplain TestDescriptor#mayRegisterTests() may potentially register
264300 * tests dynamically}.
265301 *
@@ -355,12 +391,14 @@ static Visitor composite(Visitor... visitors) {
355391 enum Type {
356392
357393 /**
358- * Denotes that the {@link TestDescriptor} is for a <em>container</em>.
394+ * Denotes that the {@link TestDescriptor} is strictly for a
395+ * <em>container</em>. I.e. it is not also a <em>test</em>.
359396 */
360397 CONTAINER ,
361398
362399 /**
363- * Denotes that the {@link TestDescriptor} is for a <em>test</em>.
400+ * Denotes that the {@link TestDescriptor} is strictly for a
401+ * <em>test</em>. I.e. it is not also a <em>container</em>.
364402 */
365403 TEST ,
366404
0 commit comments