View Javadoc
1   package io.jawk.onetrueawk;
2   
3   /*-
4    * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5    * Jawk
6    * ჻჻჻჻჻჻
7    * Copyright (C) 2006 - 2026 MetricsHub
8    * ჻჻჻჻჻჻
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   *
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   *
19   * You should have received a copy of the GNU General Lesser Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
23   */
24  
25  import java.io.File;
26  import java.io.IOException;
27  import java.nio.charset.StandardCharsets;
28  import java.nio.file.Files;
29  import java.nio.file.Path;
30  import java.util.Arrays;
31  import java.util.stream.Collectors;
32  import io.jawk.AwkTestSupport;
33  import io.jawk.CompatibilityTestResources;
34  import org.junit.AfterClass;
35  import org.junit.BeforeClass;
36  import org.junit.Test;
37  import org.junit.runner.RunWith;
38  import org.junit.runners.Parameterized;
39  import org.junit.runners.Parameterized.Parameter;
40  import org.junit.runners.Parameterized.Parameters;
41  
42  /**
43   * Integration suite based on the BWK text-processing tests vendored from the
44   * One True Awk upstream repository. Each AWK script executes against the shared
45   * BWK input file and its output is compared with the recorded result.
46   *
47   * @see <a href="https://github.com/onetrueawk/awk">BWK / One True Awk upstream repository</a>
48   */
49  @RunWith(Parameterized.class)
50  public class BwkTIT {
51  
52  	private static Path bwkTDirectory;
53  	private static Path scriptsDirectory;
54  
55  	/**
56  	 * Initializes the BWK.t integration suite.
57  	 *
58  	 * @throws Exception when resource discovery fails
59  	 */
60  	@BeforeClass
61  	public static void beforeAll() throws Exception {}
62  
63  	/**
64  	 * Returns the BWK.t script names discovered from the integration-test
65  	 * resources.
66  	 *
67  	 * @return the parameter values for this suite
68  	 * @throws Exception when resource discovery fails
69  	 */
70  	@Parameters(name = "BWK.t {0}")
71  	public static Iterable<String> awkList() throws Exception {
72  		bwkTDirectory = CompatibilityTestResources.resourceDirectory(BwkTIT.class, "bwk", "t");
73  		if (!bwkTDirectory.toFile().isDirectory()) {
74  			throw new IOException(bwkTDirectory + " is not a directory");
75  		}
76  		scriptsDirectory = bwkTDirectory.resolve("scripts");
77  		if (!scriptsDirectory.toFile().isDirectory()) {
78  			throw new IOException("scripts is not a directory");
79  		}
80  		File[] scriptFiles = scriptsDirectory.toFile().listFiles();
81  		if (scriptFiles == null) {
82  			throw new IOException("Couldn't list files in " + scriptsDirectory);
83  		}
84  
85  		return Arrays
86  				.stream(scriptFiles)
87  				.filter(scriptFile -> scriptFile.getName().startsWith("t."))
88  				.map(File::getName)
89  				.sorted()
90  				.collect(Collectors.toList());
91  	}
92  
93  	/** Path to the AWK test script to execute. */
94  	@Parameter
95  	public String awkName;
96  
97  	/**
98  	 * Executes one BWK.t script and compares its output with the expected result.
99  	 *
100 	 * @throws Exception when the test setup or execution fails unexpectedly
101 	 */
102 	@Test
103 	public void test() throws Exception {
104 		Path awkPath = scriptsDirectory.resolve(awkName);
105 		Path okPath = bwkTDirectory.resolve("results/" + awkName + ".ok");
106 		Path inputPath = bwkTDirectory.resolve("inputs/test.data");
107 
108 		int expectedCode = 0;
109 		if ("t.exit".equals(awkName)) {
110 			expectedCode = 1;
111 		} else if ("t.exit1".equals(awkName)) {
112 			expectedCode = 2;
113 		}
114 
115 		if ("t.in2".equals(awkName) || "t.intest2".equals(awkName)) {
116 			String expectedResult = Files
117 					.readAllLines(okPath, StandardCharsets.UTF_8)
118 					.stream()
119 					.sorted()
120 					.collect(Collectors.joining("\n"));
121 
122 			AwkTestSupport
123 					.awkTest("BWK.t " + awkName)
124 					.script(awkPath)
125 					.operand(inputPath.toString())
126 					.postProcessWith(output -> Arrays.stream(output.split("\\R")).sorted().collect(Collectors.joining("\n")))
127 					.expect(expectedResult)
128 					.expectExit(expectedCode)
129 					.build()
130 					.runAndAssert();
131 		} else {
132 			AwkTestSupport
133 					.awkTest("BWK.t " + awkName)
134 					.script(awkPath)
135 					.operand(inputPath.toString())
136 					.expectLines(okPath)
137 					.expectExit(expectedCode)
138 					.build()
139 					.runAndAssert();
140 		}
141 	}
142 
143 	/**
144 	 * Finalizes the BWK.t integration suite.
145 	 *
146 	 * @throws Exception unused hook retained for suite symmetry
147 	 */
148 	@AfterClass
149 	public static void afterAll() throws Exception {}
150 }