Skip to content

Commit ad2537b

Browse files
Expand BytecodeInstructionIntegrationTest coverage (#4238)
* Expand BytecodeInstructionIntegrationTest to cover more ByteCodeTranslator methods Added tests for: - handleDefaultOutput - readFileAsStringBuilder - copyDir - replaceInFile - getFileType - handleIosOutput Updated vm/tests/pom.xml to include ByteCodeTranslator/src as test resource. Added helper to reset static ByteCodeClass state to fix flaky tests. Added helper to compile dummy main class for tests. * Expand BytecodeInstructionIntegrationTest to cover more ByteCodeTranslator methods Added tests for: - handleDefaultOutput - readFileAsStringBuilder - copyDir - replaceInFile - getFileType - handleIosOutput Updated vm/tests/pom.xml to include ByteCodeTranslator/src as test resource. Added helper to reset static ByteCodeClass state to fix flaky tests. Added helper to compile dummy main class for tests. --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent 079c50a commit ad2537b

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed

vm/tests/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
</dependencies>
3737

3838
<build>
39+
<testResources>
40+
<testResource>
41+
<directory>../ByteCodeTranslator/src</directory>
42+
</testResource>
43+
</testResources>
3944
<plugins>
4045
<plugin>
4146
<groupId>org.apache.maven.plugins</groupId>

vm/tests/src/test/java/com/codename1/tools/translator/BytecodeInstructionIntegrationTest.java

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.io.FilenameFilter;
1616
import java.lang.reflect.Constructor;
1717
import java.lang.reflect.Field;
18+
import java.lang.reflect.Method;
1819
import java.nio.charset.StandardCharsets;
1920
import java.nio.file.Files;
2021
import java.nio.file.Path;
@@ -624,4 +625,173 @@ private String nativeReportSource() {
624625
" printf(\"RESULT=%d\\n\", value);\n" +
625626
"}\n";
626627
}
628+
629+
@Test
630+
void handleDefaultOutputWritesOutput() throws Exception {
631+
Parser.cleanup();
632+
resetByteCodeClass();
633+
Path sourceDir = Files.createTempDirectory("default-output-source");
634+
Path outputDir = Files.createTempDirectory("default-output-dest");
635+
636+
Files.write(sourceDir.resolve("resource.txt"), "data".getBytes(StandardCharsets.UTF_8));
637+
compileDummyMainClass(sourceDir, "com.example", "MyAppDefault");
638+
639+
String[] args = new String[] {
640+
"csharp",
641+
sourceDir.toAbsolutePath().toString(),
642+
outputDir.toAbsolutePath().toString(),
643+
"MyAppDefault", "com.example", "My App", "1.0", "ios", "none"
644+
};
645+
646+
ByteCodeTranslator.OutputType originalOutput = ByteCodeTranslator.output;
647+
try {
648+
ByteCodeTranslator.main(args);
649+
650+
assertTrue(Files.exists(outputDir.resolve("resource.txt")), "Default output handler should copy resources");
651+
} finally {
652+
ByteCodeTranslator.output = originalOutput;
653+
Parser.cleanup();
654+
resetByteCodeClass();
655+
}
656+
}
657+
658+
@Test
659+
void readFileAsStringBuilderReadsContent() throws Exception {
660+
File temp = File.createTempFile("readfile", ".txt");
661+
Files.write(temp.toPath(), "Hello World".getBytes(StandardCharsets.UTF_8));
662+
663+
Method m = ByteCodeTranslator.class.getDeclaredMethod("readFileAsStringBuilder", File.class);
664+
m.setAccessible(true);
665+
StringBuilder sb = (StringBuilder) m.invoke(null, temp);
666+
667+
assertEquals("Hello World", sb.toString());
668+
temp.delete();
669+
}
670+
671+
@Test
672+
void replaceInFileModifiesContent() throws Exception {
673+
File temp = File.createTempFile("replace", ".txt");
674+
Files.write(temp.toPath(), "Hello World".getBytes(StandardCharsets.UTF_8));
675+
676+
Method m = ByteCodeTranslator.class.getDeclaredMethod("replaceInFile", File.class, String[].class);
677+
m.setAccessible(true);
678+
m.invoke(null, temp, new String[]{"World", "Universe"});
679+
680+
String content = new String(Files.readAllBytes(temp.toPath()), StandardCharsets.UTF_8);
681+
assertEquals("Hello Universe", content);
682+
temp.delete();
683+
}
684+
685+
@Test
686+
void getFileTypeReturnsCorrectTypes() throws Exception {
687+
Method m = ByteCodeTranslator.class.getDeclaredMethod("getFileType", String.class);
688+
m.setAccessible(true);
689+
690+
assertEquals("wrapper.framework", m.invoke(null, "foo.framework"));
691+
assertEquals("sourcecode.c.objc", m.invoke(null, "foo.m"));
692+
assertEquals("file", m.invoke(null, "foo.txt"));
693+
assertEquals("wrapper.plug-in", m.invoke(null, "foo.bundle"));
694+
}
695+
696+
@Test
697+
void copyDirRecursivelyCopies() throws Exception {
698+
Path src = Files.createTempDirectory("copydir-src");
699+
Path dest = Files.createTempDirectory("copydir-dest");
700+
701+
Files.createDirectories(src.resolve("subdir"));
702+
Files.write(src.resolve("file1.txt"), "content1".getBytes());
703+
Files.write(src.resolve("subdir/file2.txt"), "content2".getBytes());
704+
705+
Method m = ByteCodeTranslator.class.getDeclaredMethod("copyDir", File.class, File.class);
706+
m.setAccessible(true);
707+
ByteCodeTranslator instance = new ByteCodeTranslator();
708+
m.invoke(instance, src.toFile(), dest.toFile());
709+
710+
Path copiedRoot = dest.resolve(src.getFileName());
711+
assertTrue(Files.exists(copiedRoot));
712+
assertTrue(Files.exists(copiedRoot.resolve("file1.txt")));
713+
assertTrue(Files.exists(copiedRoot.resolve("subdir/file2.txt")));
714+
}
715+
716+
@Test
717+
void handleIosOutputGeneratesProjectStructure() throws Exception {
718+
Parser.cleanup();
719+
resetByteCodeClass();
720+
Path sourceDir = Files.createTempDirectory("ios-output-source");
721+
Path outputDir = Files.createTempDirectory("ios-output-dest");
722+
723+
Files.write(sourceDir.resolve("resource.txt"), "data".getBytes(StandardCharsets.UTF_8));
724+
compileDummyMainClass(sourceDir, "com.example", "MyAppIOS");
725+
726+
// Add a bundle to test copyDir invocation in execute loop
727+
Path bundleDir = sourceDir.resolve("test.bundle");
728+
Files.createDirectories(bundleDir);
729+
Files.write(bundleDir.resolve("info.txt"), "bundle info".getBytes(StandardCharsets.UTF_8));
730+
731+
String[] args = new String[] {
732+
"ios",
733+
sourceDir.toAbsolutePath().toString(),
734+
outputDir.toAbsolutePath().toString(),
735+
"MyAppIOS", "com.example", "My App", "1.0", "ios", "none"
736+
};
737+
738+
ByteCodeTranslator.OutputType originalOutput = ByteCodeTranslator.output;
739+
try {
740+
ByteCodeTranslator.main(args);
741+
742+
Path dist = outputDir.resolve("dist");
743+
assertTrue(Files.exists(dist));
744+
Path srcRoot = dist.resolve("MyAppIOS-src");
745+
assertTrue(Files.exists(srcRoot));
746+
assertTrue(Files.exists(srcRoot.resolve("resource.txt")));
747+
assertTrue(Files.exists(srcRoot.resolve("Images.xcassets")));
748+
assertTrue(Files.exists(dist.resolve("MyAppIOS.xcodeproj")));
749+
assertTrue(Files.exists(srcRoot.resolve("MyAppIOS-Info.plist")));
750+
751+
// Verify bundle copied
752+
assertTrue(Files.exists(srcRoot.resolve("test.bundle")));
753+
assertTrue(Files.exists(srcRoot.resolve("test.bundle/info.txt")));
754+
755+
} finally {
756+
ByteCodeTranslator.output = originalOutput;
757+
Parser.cleanup();
758+
resetByteCodeClass();
759+
}
760+
}
761+
762+
private void resetByteCodeClass() throws Exception {
763+
Field mainClassField = ByteCodeClass.class.getDeclaredField("mainClass");
764+
mainClassField.setAccessible(true);
765+
mainClassField.set(null, null);
766+
767+
Field arrayTypesField = ByteCodeClass.class.getDeclaredField("arrayTypes");
768+
arrayTypesField.setAccessible(true);
769+
((Set<?>) arrayTypesField.get(null)).clear();
770+
771+
Field writableFieldsField = ByteCodeClass.class.getDeclaredField("writableFields");
772+
writableFieldsField.setAccessible(true);
773+
((Set<?>) writableFieldsField.get(null)).clear();
774+
}
775+
776+
private void compileDummyMainClass(Path sourceDir, String packageName, String className) throws Exception {
777+
Path packageDir = sourceDir;
778+
for (String part : packageName.split("\\.")) {
779+
packageDir = packageDir.resolve(part);
780+
}
781+
Files.createDirectories(packageDir);
782+
Path javaFile = packageDir.resolve(className + ".java");
783+
String content = "package " + packageName + ";\n" +
784+
"public class " + className + " {\n" +
785+
" public static void main(String[] args) {}\n" +
786+
"}\n";
787+
Files.write(javaFile, content.getBytes(StandardCharsets.UTF_8));
788+
789+
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
790+
int result = compiler.run(null, null, null,
791+
"-source", "1.8",
792+
"-target", "1.8",
793+
"-d", sourceDir.toString(),
794+
javaFile.toString());
795+
assertEquals(0, result, "Compilation failed");
796+
}
627797
}

0 commit comments

Comments
 (0)