diff --git a/src/main/java/org/eolang/lints/LtTestComment.java b/src/main/java/org/eolang/lints/LtTestComment.java new file mode 100644 index 000000000..2a3d0c95f --- /dev/null +++ b/src/main/java/org/eolang/lints/LtTestComment.java @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com + * SPDX-License-Identifier: MIT + */ +package org.eolang.lints; + +import com.github.lombrozo.xnav.Xnav; +import com.jcabi.xml.XML; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import org.eolang.parser.OnDefault; + +/** + * Lint that warns if a comment is present at a test object. + * @since 0.0.59 + */ +final class LtTestComment implements Lint { + @Override + public Collection defects(final XML xmir) throws IOException { + final Collection defects = new ArrayList<>(0); + final Xnav xml = new Xnav(xmir.inner()); + final List objects = xml + .path("//o[@name and starts-with(@name, '+')]") + .collect(Collectors.toList()); + for (final Xnav object : objects) { + final List comments = object + .path(".//meta[@key='comment']") + .collect(Collectors.toList()); + if (!comments.isEmpty()) { + defects.add( + new Defect.Default( + "test-has-comment", + Severity.WARNING, + new OnDefault(xmir).get(), + Integer.parseInt(object.attribute("line").text().orElse("0")), + "Test object contains a comment. Prefer self-explanatory test names." + ) + ); + } + } + return defects; + } + + @Override + public String motive() throws IOException { + return "Avoid comments in test objects; use clear test names."; + } + + @Override + public String name() { + return "test-has-comment"; + } +} diff --git a/src/test/java/org/eolang/lints/LtByXslTest.java b/src/test/java/org/eolang/lints/LtByXslTest.java index dc9c810e2..712536a12 100644 --- a/src/test/java/org/eolang/lints/LtByXslTest.java +++ b/src/test/java/org/eolang/lints/LtByXslTest.java @@ -18,6 +18,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -359,7 +360,7 @@ void doesNotDuplicateDefectsWhenMultipleDefectsOnTheSameLine() throws Exception @SuppressWarnings("StreamResourceLeak") @Tag("deep") - @Timeout(180L) + @Timeout(value = 6, unit = TimeUnit.MINUTES) @Test void validatesEoPacksForErrors() throws IOException { Files.walk(Paths.get("src/test/resources/org/eolang/lints/packs/single")) diff --git a/src/test/java/org/eolang/lints/LtTestCommentTest.java b/src/test/java/org/eolang/lints/LtTestCommentTest.java new file mode 100644 index 000000000..336f8d4e0 --- /dev/null +++ b/src/test/java/org/eolang/lints/LtTestCommentTest.java @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com + * SPDX-License-Identifier: MIT + */ +package org.eolang.lints; + +import com.jcabi.xml.XML; +import com.jcabi.xml.XMLDocument; +import java.io.IOException; +import java.util.Collection; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +/** + * Test for {@link LtTestComment}. + * + * @since 0.0.1 + */ +final class LtTestCommentTest { + + @Test + void reportsNoDefectsWhenNoCommentPresent() throws IOException { + final XML xml = new XMLDocument( + "" + ); + final LtTestComment lint = new LtTestComment(); + final Collection defects = lint.defects(xml); + MatcherAssert.assertThat( + "Should not report defects when test object has no comment", + defects, + Matchers.empty() + ); + } + + @Test + void reportsNoDefectsWhenNoObjectPresent() throws IOException { + final XML xml = new XMLDocument( + "" + ); + final LtTestComment lint = new LtTestComment(); + final Collection defects = lint.defects(xml); + MatcherAssert.assertThat( + "Should not report defects when no test object is present", + defects, + Matchers.empty() + ); + } + + @Test + void containsGuidanceInMotive() throws IOException { + final LtTestComment lint = new LtTestComment(); + MatcherAssert.assertThat( + "Motive must discourage comments in test objects", + lint.motive(), + Matchers.containsString("Avoid comments in test objects; use clear test names") + ); + } + + @Test + void returnsStableId() { + final LtTestComment lint = new LtTestComment(); + MatcherAssert.assertThat( + "Rule id must be 'test-has-comment'", + lint.name(), + Matchers.equalTo("test-has-comment") + ); + } + +}