• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pmd / pmd / 830

25 Sep 2026 03:07PM UTC coverage: 79.731%. Remained the same
830

push

github

web-flow
chore: Replace system-lambda with system-stubs (#7114)

* chore: Replace system-lambda with system-stubs

* Update comment

---------

Co-authored-by: Sören Glimm <git@uncleowen.de>

20252 of 26446 branches covered (76.58%)

Branch coverage included in aggregate %.

0 of 3 new or added lines in 1 file covered. (0.0%)

43589 of 53624 relevant lines covered (81.29%)

0.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pmd-test/src/main/java/net/sourceforge/pmd/test/AbstractAntTestHelper.java
1
/*
2
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3
 */
4

5
package net.sourceforge.pmd.test;
6

7
import static java.io.File.separator;
8
import static org.hamcrest.MatcherAssert.assertThat;
9
import static org.hamcrest.Matchers.containsString;
10
import static org.hamcrest.Matchers.not;
11
import static uk.org.webcompere.systemstubs.SystemStubs.restoreSystemProperties;
12

13
import java.io.ByteArrayOutputStream;
14
import java.io.File;
15
import java.io.IOException;
16
import java.io.PrintStream;
17
import java.nio.file.Files;
18
import java.nio.file.Path;
19
import java.util.Locale;
20

21
import org.apache.tools.ant.BuildEvent;
22
import org.apache.tools.ant.DefaultLogger;
23
import org.apache.tools.ant.Project;
24
import org.apache.tools.ant.ProjectHelper;
25
import org.junit.jupiter.api.AfterAll;
26
import org.junit.jupiter.api.BeforeEach;
27
import org.junit.jupiter.api.io.TempDir;
28

29
import net.sourceforge.pmd.internal.Slf4jSimpleConfiguration;
30

31
import uk.org.webcompere.systemstubs.SystemStubs;
32
import uk.org.webcompere.systemstubs.ThrowingRunnable;
33

34
/**
35
 * Base test class for ant tests.
36
 *
37
 * <p>Usage template:
38
 *
39
 * <pre>
40
 * class MyPMDTaskTest extends AbstractAntTestHelper {
41
 *     MyPMDTaskTest() {
42
 *          antTestScriptFilename = "mypmdtasktest.xml";
43
 *     }
44
 *
45
 *     &#64;Test
46
 *     void myTest() {
47
 *         executeTarget("testMyTarget");
48
 *         assertOutputContaining("Expected Violation Message");
49
 *     }
50
 * }
51
 * </pre>
52
 *
53
 * @author Romain Pelisse &lt;belaran@gmail.com&gt;
54
 *
55
 */
56
public abstract class AbstractAntTestHelper {
57

58
    @TempDir
59
    private Path tempFolder;
60

61
    protected String pathToTestScript;
62
    protected String antTestScriptFilename;
63

64
    private Project antProject;
65
    private StringBuilder log = new StringBuilder();
×
66
    private String output;
67

68
    public AbstractAntTestHelper() {
×
69
        pathToTestScript = "target/test-classes/net/sourceforge/pmd/ant/xml";
×
70
    }
×
71

72
    @BeforeEach
73
    public void setUp() throws IOException {
74
        validatePostConstruct();
×
75
        // initialize Ant
76
        antProject = new Project();
×
77
        antProject.init();
×
78
        antProject.addBuildListener(new AntBuildListener());
×
79
        ProjectHelper.configureProject(antProject, new File(pathToTestScript + separator + antTestScriptFilename));
×
80

81
        // Each test case gets one temp file name, accessible with property ${tmpfile}
82
        Path tmpFile = Files.createTempFile(tempFolder, "pmd-ant-tests", null);
×
83
        // we delete the tmpfile again, since we only wanted to have a unique temp filename
84
        // the tmpfile is used for creating reports.
85
        Files.deleteIfExists(tmpFile);
×
86
        antProject.setProperty("tmpfile", tmpFile.toAbsolutePath().toString());
×
87
    }
×
88

89
    @AfterAll
90
    static void resetLogging() {
91
        Slf4jSimpleConfiguration.reconfigureDefaultLogLevel(null);
×
92
    }
×
93

94
    /**
95
     * Returns the current temporary file. Replaced by a fresh (inexistent)
96
     * file before each test.
97
     */
98
    public File currentTempFile() {
99
        String tmpname = antProject.getProperty("tmpfile");
×
100
        return tmpname == null ? null : new File(tmpname);
×
101
    }
102

103

104
    private void validatePostConstruct() {
105
        if (pathToTestScript == null || "".equals(pathToTestScript) || antTestScriptFilename == null
×
106
                || "".equals(antTestScriptFilename)) {
×
107
            throw new IllegalStateException("Unit tests for Ant script badly initialized");
×
108
        }
109
    }
×
110

111
    public String executeTarget(String target) {
112
        try {
113
            restoreLocale(() -> {
×
114
                // restoring system properties: Test might change file.encoding or might change logging properties
115
                // See Slf4jSimpleConfigurationForAnt and resetLogging
NEW
116
                restoreSystemProperties(() -> {
×
117
                    output = tapSystemOut(() -> {
×
118
                        antProject.executeTarget(target);
×
119
                    });
×
120
                });
×
121
            });
×
122
            return output;
×
123
        } catch (Exception e) {
×
124
            throw new RuntimeException(e);
×
125
        }
126
    }
127

128
    protected String getLog() {
129
        return log.toString();
×
130
    }
131

132
    public void assertOutputContaining(String text) {
133
        assertThat(output, containsString(text));
×
134
    }
×
135

136

137
    public void assertContains(String text, String toFind) {
138
        assertThat(text, containsString(toFind));
×
139
    }
×
140

141

142
    public void assertDoesntContain(String text, String toFind) {
143
        assertThat(text, not(containsString(toFind)));
×
144
    }
×
145

146
    private static void restoreLocale(ThrowingRunnable statement) throws Exception {
147
        Locale originalLocale = Locale.getDefault();
×
148
        try {
NEW
149
            statement.asCallable().call();
×
150
        } finally {
151
            Locale.setDefault(originalLocale);
×
152
        }
153
    }
×
154

155
    /**
156
     * This is similar to {@link SystemStubs#tapSystemOut(ThrowingRunnable)}. But this
157
     * method doesn't use the platform default charset as it was when the JVM started.
158
     * Instead, it uses the current system property {@code file.encoding}. This allows
159
     * tests to change the encoding.
160
     *
161
     * @param statement an arbitrary piece of code.
162
     * @return text that is written to stdout. Lineendings are normalized to {@code \n}.
163
     * @throws Exception any exception thrown by the statement
164
     */
165
    private static String tapSystemOut(ThrowingRunnable statement) throws Exception {
166
        @SuppressWarnings("PMD.CloseResource") // we don't want to close System.out
167
        PrintStream originalOut = System.out;
×
168
        ByteArrayOutputStream text = new ByteArrayOutputStream();
×
169
        String currentDefaultCharset = System.getProperty("file.encoding");
×
170
        try {
171
            PrintStream replacement = new PrintStream(text, true, currentDefaultCharset);
×
172
            System.setOut(replacement);
×
NEW
173
            statement.asCallable().call();
×
174
        } finally {
175
            System.setOut(originalOut);
×
176
        }
177
        String result = text.toString(currentDefaultCharset);
×
178
        return result.replace(System.lineSeparator(), "\n");
×
179
    }
180

181
    private final class AntBuildListener extends DefaultLogger {
182
        private AntBuildListener() {
×
183
            msgOutputLevel = Project.MSG_INFO;
×
184
        }
×
185

186
        @Override
187
        protected void printMessage(String message, PrintStream stream, int priority) {
188
            log.append(message);
×
189
        }
×
190

191
        @Override
192
        public void messageLogged(BuildEvent buildEvent) {
193
            if (buildEvent.getPriority() <= Project.MSG_INFO) {
×
194
                log.append(buildEvent.getMessage());
×
195
            }
196
        }
×
197
    }
198
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc