Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify writer outputs against 3rd-party readers #54

Merged
merged 10 commits into from
Aug 26, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
- Added IntelliJ IDEA migration map reader and writer
- Added `MappingFormat#features()` to allow for more fine-grained programmatic querying of format capabilities
- Added tests to validate our writer outputs against 3rd-party readers
- Overhauled the internal `ColumnFileReader` to behave more consistently
- Made handling of the `NEEDS_MULTIPLE_PASSES` flag more consistent, reducing memory usage in a few cases
- Made some internal methods in Enigma and TSRG readers actually private
Expand Down
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ allprojects {
implementation "org.ow2.asm:asm:${project.asm_version}"
compileOnly "org.jetbrains:annotations:${project.jetbrains_annotations_version}"

testImplementation "net.neoforged:srgutils:${srgutils_version}"
testImplementation "org.cadixdev:lorenz:${lorenz_version}"
testImplementation "org.cadixdev:lorenz-io-enigma:${lorenz_version}"
testImplementation "org.cadixdev:lorenz-io-jam:${lorenz_version}"
testImplementation "org.junit.jupiter:junit-jupiter:${junit_jupiter_version}"
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
testCompileOnly "org.jetbrains:annotations:${project.jetbrains_annotations_version}"
Expand Down
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ tiny_remapper_version = 0.8.0
jetbrains_annotations_version = 24.0.1
checkstyle_tool_version = 10.12.4
junit_jupiter_version = 5.10.0
srgutils_version = 1.0.9
lorenz_version = 0.5.8
62 changes: 62 additions & 0 deletions src/test/java/net/fabricmc/mappingio/TestHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

import net.neoforged.srgutils.IMappingFile;
import org.cadixdev.lorenz.io.MappingFormats;
import org.jetbrains.annotations.Nullable;

import net.fabricmc.mappingio.format.MappingFormat;
Expand Down Expand Up @@ -74,6 +76,66 @@ public static String getFileName(MappingFormat format) {
}
}

@Nullable
public static org.cadixdev.lorenz.io.MappingFormat toLorenzFormat(MappingFormat format) {
switch (format) {
case SRG_FILE:
return MappingFormats.SRG;
case XSRG_FILE:
return MappingFormats.XSRG;
case CSRG_FILE:
return MappingFormats.CSRG;
case TSRG_FILE:
return MappingFormats.TSRG;
case ENIGMA_FILE:
return MappingFormats.byId("enigma");
case JAM_FILE:
return MappingFormats.byId("jam");
case TINY_FILE:
case TINY_2_FILE:
case ENIGMA_DIR:
case TSRG_2_FILE:
case PROGUARD_FILE:
case INTELLIJ_MIGRATION_MAP_FILE:
case RECAF_SIMPLE_FILE:
case JOBF_FILE:
return null;
default:
throw new IllegalArgumentException("Unknown format: " + format);
}
}

@Nullable
public static IMappingFile.Format toSrgUtilsFormat(MappingFormat format) {
switch (format) {
case TINY_FILE:
return IMappingFile.Format.TINY1;
case TINY_2_FILE:
return IMappingFile.Format.TINY;
case SRG_FILE:
return IMappingFile.Format.SRG;
case XSRG_FILE:
return IMappingFile.Format.XSRG;
case CSRG_FILE:
return IMappingFile.Format.CSRG;
case TSRG_FILE:
return IMappingFile.Format.TSRG;
case TSRG_2_FILE:
return IMappingFile.Format.TSRG2;
case PROGUARD_FILE:
return IMappingFile.Format.PG;
case ENIGMA_FILE:
case ENIGMA_DIR:
case JAM_FILE:
case INTELLIJ_MIGRATION_MAP_FILE:
case RECAF_SIMPLE_FILE:
case JOBF_FILE:
return null;
default:
throw new IllegalArgumentException("Unknown format: " + format);
}
}

public static Path writeToDir(MappingTreeView tree, Path dir, MappingFormat format) throws IOException {
Path path = dir.resolve(getFileName(format));
tree.accept(MappingWriter.create(path, format));
Expand Down
54 changes: 49 additions & 5 deletions src/test/java/net/fabricmc/mappingio/write/WriteTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,24 @@

package net.fabricmc.mappingio.write;

import java.io.IOException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

import net.neoforged.srgutils.IMappingFile;
import net.neoforged.srgutils.INamedMappingFile;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import net.fabricmc.mappingio.MappedElementKind;
import net.fabricmc.mappingio.MappingReader;
import net.fabricmc.mappingio.SubsetAssertingVisitor;
import net.fabricmc.mappingio.TestHelper;
import net.fabricmc.mappingio.adapter.FlatAsRegularMappingVisitor;
import net.fabricmc.mappingio.adapter.ForwardingMappingVisitor;
import net.fabricmc.mappingio.adapter.MappingNsCompleter;
import net.fabricmc.mappingio.format.MappingFormat;
import net.fabricmc.mappingio.tree.MappingTreeView;
import net.fabricmc.mappingio.tree.MemoryMappingTree;
Expand All @@ -35,12 +43,19 @@ public class WriteTest {
@TempDir
private static Path dir;
private static MappingTreeView validTree;
private static Map<String, String> treeNsAltMap = new HashMap<>();
private static MappingTreeView validWithHolesTree;
private static Map<String, String> treeWithHolesNsAltMap = new HashMap<>();

@BeforeAll
public static void setup() throws Exception {
validTree = TestHelper.createTestTree();
treeNsAltMap.put(validTree.getDstNamespaces().get(0), validTree.getSrcNamespace());
treeNsAltMap.put(validTree.getDstNamespaces().get(1), validTree.getSrcNamespace());

validWithHolesTree = TestHelper.createTestTreeWithHoles();
treeWithHolesNsAltMap.put(validWithHolesTree.getDstNamespaces().get(0), validWithHolesTree.getSrcNamespace());
treeWithHolesNsAltMap.put(validWithHolesTree.getDstNamespaces().get(1), validWithHolesTree.getSrcNamespace());
}

@Test
Expand Down Expand Up @@ -114,17 +129,46 @@ public void jobfFile() throws Exception {
}

private void check(MappingFormat format) throws Exception {
dogfood(validTree, dir, format);
dogfood(validWithHolesTree, dir, format);
Path path = TestHelper.writeToDir(validTree, dir, format);
readWithMio(validTree, path, format);
readWithLorenz(path, format);
readWithSrgUtils(validTree, format, treeNsAltMap);

path = TestHelper.writeToDir(validWithHolesTree, dir, format);
readWithMio(validWithHolesTree, path, format);
readWithLorenz(path, format);
readWithSrgUtils(validWithHolesTree, format, treeWithHolesNsAltMap);
}

private void dogfood(MappingTreeView origTree, Path outputPath, MappingFormat outputFormat) throws Exception {
outputPath = TestHelper.writeToDir(origTree, dir, outputFormat);
private void readWithMio(MappingTreeView origTree, Path outputPath, MappingFormat outputFormat) throws Exception {
VisitableMappingTree writtenTree = new MemoryMappingTree();

MappingReader.read(outputPath, outputFormat, writtenTree);

writtenTree.accept(new FlatAsRegularMappingVisitor(new SubsetAssertingVisitor(origTree, null, outputFormat)));
origTree.accept(new FlatAsRegularMappingVisitor(new SubsetAssertingVisitor(writtenTree, outputFormat, null)));
}

private void readWithLorenz(Path path, MappingFormat format) throws Exception {
org.cadixdev.lorenz.io.MappingFormat lorenzFormat = TestHelper.toLorenzFormat(format);
if (lorenzFormat == null) return;
lorenzFormat.read(path);
}

private void readWithSrgUtils(MappingTreeView tree, MappingFormat format, Map<String, String> nsAltMap) throws Exception {
IMappingFile.Format srgUtilsFormat = TestHelper.toSrgUtilsFormat(format);
if (srgUtilsFormat == null) return;

// SrgUtils can't handle empty dst names
VisitableMappingTree dstNsCompTree = new MemoryMappingTree();
tree.accept(new MappingNsCompleter(new ForwardingMappingVisitor(dstNsCompTree) {
@Override
public boolean visitElementContent(MappedElementKind targetKind) throws IOException {
// SrgUtil's Tiny v2 reader crashes on var sub-elements
return !(format == MappingFormat.TINY_2_FILE && targetKind == MappedElementKind.METHOD_VAR);
}
}, nsAltMap));

Path path = TestHelper.writeToDir(dstNsCompTree, dir, format);
INamedMappingFile.load(path.toFile());
}
}
Loading