Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Code format

Your never need to worry about code formatting at all. Simply run `mvn formatter:format` before committing changes to make sure the new code follows this project's code formatting rules.
You never need to worry about code formatting at all. Simply run `mvn formatter:format` before committing changes to make sure the new code follows this project's code formatting rules. Make sure not to run `mvn formatter:format` separately before other Maven commands, to avoid concurrency issues.

All files must include the proper license header. When you add a new file, make sure to include the proper license header by running the `mvn license:update-file-header` command before committing (or even before trying the build and test, since the build will fail if a file doesn't include the proper license header).

Expand Down
43 changes: 28 additions & 15 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,26 @@
<build>
<plugins>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<id>add-compatibility-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>${project.basedir}/src/it/java</source>
</sources>
</configuration>
</execution>
Comment thread
bertysentry marked this conversation as resolved.
</executions>
</plugin>

<!--formatter -->
<plugin>
<groupId>net.revelc.code.formatter</groupId>
Expand All @@ -127,6 +147,7 @@
<directories>
<directory>${project.build.sourceDirectory}</directory>
<directory>${project.build.testSourceDirectory}</directory>
<directory>${project.basedir}/src/it/java</directory>
</directories>
<includes>
<include>**/*.java</include>
Expand All @@ -144,6 +165,7 @@
<includes>
<include>main/java/**/*.java</include>
<include>test/java/**/*.java</include>
<include>it/java/**/*.java</include>
</includes>
</configuration>
</plugin>
Expand All @@ -167,27 +189,18 @@
<!-- surefire -->
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*GawkTest.java</exclude>
<exclude>**/BwkPTest.java</exclude>
<exclude>**/BwkTTest.java</exclude>
<exclude>**/BwkMiscTest.java</exclude>
</excludes>
<workingDirectory>${project.build.directory}/surefire-workingdir</workingDirectory>
</configuration>
<configuration>
<workingDirectory>${project.build.directory}/surefire-workingdir</workingDirectory>
</configuration>
</plugin>

<!-- failsafe for compatibility tests -->
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<includes>
<include>**/BwkPTest.java</include>
<include>**/BwkTTest.java</include>
<include>**/BwkMiscTest.java</include>
<include>**/GawkTest.java</include>
</includes>
<includes>
<include>**/*IT.java</include>
</includes>
<testFailureIgnore>true</testFailureIgnore>
<workingDirectory>${project.build.directory}/failsafe-workingdir</workingDirectory>
Comment thread
bertysentry marked this conversation as resolved.
</configuration>
Expand Down
59 changes: 59 additions & 0 deletions src/it/java/io/jawk/AbstractGawkSuite.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.jawk;

/*-
* ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
* Jawk
* ჻჻჻჻჻჻
* Copyright 2006 - 2026 MetricsHub
* ჻჻჻჻჻჻
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
*/

import static org.junit.Assume.assumeTrue;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

/**
* Shared helpers for the explicit gawk compatibility integration suites.
*/
abstract class AbstractGawkSuite {

protected static final Path GAWK_DIRECTORY = CompatibilityTestResources
.resourceDirectory(AbstractGawkSuite.class, "gawk");
protected static final String NON_ZERO_TRANSCRIPT_REASON = "This case compares a non-zero gawk CLI transcript, which is intentionally skipped in the explicit AwkTestSupport.cliTest suite.";
protected static final String NON_UTF8_STDIN_REASON = "This case redirects stdin that is not valid UTF-8, which is intentionally skipped in the explicit AwkTestSupport.cliTest suite.";
protected static final String NON_UTF8_EXPECTED_REASON = "This case uses an expected .ok file that is not valid UTF-8, which is intentionally skipped in the explicit AwkTestSupport.cliTest suite.";
protected static final String MANUAL_SKIP_REASON = "Handwritten gawk case from Makefile.am not yet expressed as an AwkTestSupport.cliTest case.";

protected static Path gawkPath(String fileName) {
return GAWK_DIRECTORY.resolve(fileName);
}

protected static String gawkFile(String fileName) {
return gawkPath(fileName).toString();
}

protected static String gawkText(String fileName) throws IOException {
return new String(Files.readAllBytes(gawkPath(fileName)), StandardCharsets.UTF_8);
}

protected static void skip(String reason) {
assumeTrue(reason, false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@
* ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
*/

import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.junit.AfterClass;
Expand All @@ -40,90 +36,86 @@
import org.junit.runners.Parameterized.Parameters;

/**
* Test Suite based on unit and non-regression tests from bwk. Each AWK script
* in the src/test/resources/bwk.t/t.scripts directory will be executed against
* the corresponding *.in input, and its output will be compared to the
* corresponding *.ok file.
* Integration suite based on BWK miscellaneous compatibility tests. Each AWK
* script in the BWK compatibility resources executes against its corresponding
* input file and its output is compared with the recorded result.
*
* @see <a href="https://github.com/onetrueawk/awk">One True Awk</a>
*/
@RunWith(Parameterized.class)
public class BwkMiscTest {
public class BwkMiscIT {

private static final String BWK_MISC_PATH = "/bwk/misc";
private static File bwkMiscDirectory;
private static File scriptsDirectory;
private static Path bwkMiscDirectory;
private static Path scriptsDirectory;

/**
* Initialization of the tests
* Initializes the BWK miscellaneous integration suite.
*
* @throws Exception
* @throws Exception when resource discovery fails
*/
@BeforeClass
public static void beforeAll() throws Exception {}

/**
* @return the list of awk scripts in /src/test/resources/gawk
* @throws Exception
* Returns the BWK miscellaneous script names discovered from the
* integration-test resources.
*
* @return the parameter values for this suite
* @throws Exception when resource discovery fails
*/
@Parameters(name = "BWK.misc {0}")
public static Iterable<String> awkList() throws Exception {
// Get the /bwk resource directory
URL bwkTUrl = BwkTTest.class.getResource(BWK_MISC_PATH);
if (bwkTUrl == null) {
throw new IOException("Couldn't find resource " + BWK_MISC_PATH);
}
bwkMiscDirectory = new File(bwkTUrl.toURI());
if (!bwkMiscDirectory.isDirectory()) {
throw new IOException(BWK_MISC_PATH + " is not a directory");
bwkMiscDirectory = CompatibilityTestResources.resourceDirectory(BwkMiscIT.class, "bwk", "misc");
if (!bwkMiscDirectory.toFile().isDirectory()) {
throw new IOException(bwkMiscDirectory + " is not a directory");
}
scriptsDirectory = new File(bwkMiscDirectory, "scripts");
if (!scriptsDirectory.isDirectory()) {
scriptsDirectory = bwkMiscDirectory.resolve("scripts");
if (!scriptsDirectory.toFile().isDirectory()) {
throw new IOException("scripts is not a directory");
}
File[] scriptFiles = scriptsDirectory.toFile().listFiles();
if (scriptFiles == null) {
throw new IOException("Couldn't list files in " + scriptsDirectory);
}

return Arrays
.stream(scriptsDirectory.listFiles())
.filter(sf -> sf.getName().endsWith(".awk"))
.stream(scriptFiles)
.filter(scriptFile -> scriptFile.getName().endsWith(".awk"))
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Script discovery should filter to regular files (e.g., scriptFile.isFile()) in addition to checking the .awk suffix, to prevent directories or unexpected entries from being included and causing downstream failures.

Suggested change
.filter(scriptFile -> scriptFile.getName().endsWith(".awk"))
.filter(scriptFile -> scriptFile.isFile() && scriptFile.getName().endsWith(".awk"))

Copilot uses AI. Check for mistakes.
.map(File::getName)
Comment thread
bertysentry marked this conversation as resolved.
.sorted()
.collect(Collectors.toList());
}

/** Path to the AWK test script to execute */
/** Path to the AWK test script to execute. */
@Parameter
public String awkName;

/**
* Execute the AWK script stored in {@link #awkName}
* Executes one BWK miscellaneous script and compares its output with the
* expected result.
*
* @throws Exception
* @throws Exception when the test setup or execution fails unexpectedly
*/
@Test
public void test() throws Exception {
// Get the AWK script file
File awkFile = new File(scriptsDirectory, awkName);
Path awkFile = scriptsDirectory.resolve(awkName);
String shortName = awkName.substring(0, awkName.length() - 4);

// Get the input file (always the same)
File inputFile = new File(bwkMiscDirectory, "inputs/" + shortName + ".in");

// Get the file with the expected result
File okFile = new File(bwkMiscDirectory, "results/" + shortName + ".ok");
Path inputFile = bwkMiscDirectory.resolve("inputs/" + shortName + ".in");
Path okFile = bwkMiscDirectory.resolve("results/" + shortName + ".ok");

AwkTestSupport
.cliTest("BWK.misc " + awkName)
.argument("-f", awkFile.getAbsolutePath())
.operand(inputFile.getAbsolutePath())
.argument("-f", awkFile.toString())
.operand(inputFile.toString())
.expectLines(okFile)
.build()
.runAndAssert();
}

/**
* Initialization of the tests (create a temporary directory for some of the
* scripts)
* Finalizes the BWK miscellaneous integration suite.
*
* @throws Exception
* @throws Exception unused hook retained for suite symmetry
*/
@AfterClass
public static void afterAll() throws Exception {}
Expand Down
Loading
Loading