diff --git a/build.gradle b/build.gradle index f49bff1..530d4fa 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,8 @@ dependencies { compileOnly "org.projectlombok:lombok:$lombokVersion" testImplementation "org.junit.jupiter:junit-jupiter-api:5.10.3" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.10.3" + testImplementation 'org.mockito:mockito-core:5.5.0' + testImplementation 'org.mockito:mockito-junit-jupiter:3.6.0' api "com.badlogicgames.gdx-controllers:gdx-controllers-core:$gdxControllersVersion" api "com.badlogicgames.gdx:gdx-ai:$aiVersion" diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/pixelgamelibrary/backend/libgdx/storage/DesktopAndroidStorage.java b/src/main/java/com/pixelgamelibrary/backend/libgdx/storage/DesktopAndroidStorage.java index 4ae58fe..cc70177 100644 --- a/src/main/java/com/pixelgamelibrary/backend/libgdx/storage/DesktopAndroidStorage.java +++ b/src/main/java/com/pixelgamelibrary/backend/libgdx/storage/DesktopAndroidStorage.java @@ -139,12 +139,12 @@ public abstract class DesktopAndroidStorage implements Storage { @Override public byte[] readBytes(String path) { - try { path = convertToAbsolutePathIfNeeded(path); - InputStream is = createLibGdxFileHandle(path).read(); - return is.readAllBytes(); - } catch (IOException ex) { + // Use FileHandle's readBytes() method directly, as GWT supports it + com.badlogic.gdx.files.FileHandle fileHandle = createLibGdxFileHandle(path); + return fileHandle.readBytes(); + } catch (Exception ex) { Pixel.app().error(ex.getMessage()); throw new StorageException(ex.getMessage()); } @@ -241,15 +241,18 @@ public abstract class DesktopAndroidStorage implements Storage { public static boolean isTextFile(com.badlogic.gdx.files.FileHandle file) { try { String content = file.readString(); - // Check if the content contains non-printable characters (indicating binary) - for (char c : content.toCharArray()) { - if (Character.isISOControl(c) && !Character.isWhitespace(c)) { - return false; // It's likely binary if it contains control characters + // Check if the content contains any non-printable characters + for (int i = 0; i < content.length(); i++) { + char c = content.charAt(i); + // In GWT, use a simpler check for control characters + if (c < 32 && !Character.isWhitespace(c)) { + return false; // Likely a binary file due to control characters } } return true; } catch (Exception e) { - return false; // Unable to read as text, so it's likely binary + // If there's an exception while reading the file as a string, assume it's binary + return false; } } diff --git a/src/test/java/com/pixelgamelibrary/backend/libgdx/storage/DesktopAndroidStorageTest.java b/src/test/java/com/pixelgamelibrary/backend/libgdx/storage/DesktopAndroidStorageTest.java new file mode 100644 index 0000000..d55f1b7 --- /dev/null +++ b/src/test/java/com/pixelgamelibrary/backend/libgdx/storage/DesktopAndroidStorageTest.java @@ -0,0 +1,165 @@ +package com.pixelgamelibrary.backend.libgdx.storage; + +import com.badlogic.gdx.files.FileHandle; +import com.pixelgamelibrary.api.Pixel; +import com.pixelgamelibrary.api.Platform; +import com.pixelgamelibrary.api.storage.RegularFileType; +import com.pixelgamelibrary.api.storage.StorageException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class DesktopAndroidStorageTest { + + private DesktopAndroidStorage storage; + private FileHandle mockFileHandle; + + @BeforeEach + void setUp() { + mockFileHandle = mock(FileHandle.class); + storage = new DesktopAndroidStorage("testStorage") { + protected FileHandle createLibGdxFileHandle(String path) { + return mockFileHandle; + } + + @Override + public Platform getPlatform() { + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + } + }; + } + + @Test + void testConstructor_NullStorageName_ShouldThrowException() { + Exception exception = assertThrows(StorageException.class, () -> new DesktopAndroidStorage(null) { + + protected FileHandle createLibGdxFileHandle(String path) { + return mock(FileHandle.class); + } + + @Override + public Platform getPlatform() { + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + } + }); + assertEquals("storageName == null || storageName.trim().isEmpty()", exception.getMessage()); + } + + @Test + void testChangeDirectory_NonExistingDirectory_ShouldReturnErrorMessage() { + when(mockFileHandle.exists()).thenReturn(false); + String result = storage.changeDirectory("nonExistingDir"); + assertEquals("Directory does not exist: nonExistingDir", result); + } + + @Test + void testCreateDirectory_ExistingDirectory_ShouldReturnWarning() { + when(mockFileHandle.exists()).thenReturn(true); + String result = storage.createDirectory("existingDir"); + assertEquals("Directory already exists: existingDir", result); + } + + @Test + void testCreateDirectory_NewDirectory_ShouldCreateDirectory() { + when(mockFileHandle.exists()).thenReturn(false); + String result = storage.createDirectory("newDir"); + assertEquals("", result); + verify(mockFileHandle).mkdirs(); + } + + @Test + void testTouch_ShouldCreateFile() { + String result = storage.touch("testFile.txt"); + assertEquals("", result); + verify(mockFileHandle).writeString("", false); + } + + @Test + void testRemove_ShouldDeleteFile() { + when(mockFileHandle.delete()).thenReturn(true); + boolean result = storage.remove("testFile.txt"); + assertTrue(result); + verify(mockFileHandle).delete(); + } + + @Test + void testMove_ShouldMoveFile() { + storage.move("sourceFile.txt", "targetFile.txt"); + verify(mockFileHandle).moveTo(mockFileHandle); + } + + @Test + void testReadString_ShouldReturnFileContent() { + when(mockFileHandle.readString()).thenReturn("File content"); + String result = storage.readString("testFile.txt"); + assertEquals("File content", result); + } + + @Test + void testReadBytes_ShouldReturnFileBytes() throws IOException { + InputStream mockInputStream = mock(InputStream.class); + when(mockFileHandle.read()).thenReturn(mockInputStream); + when(mockInputStream.readAllBytes()).thenReturn(new byte[]{1, 2, 3}); + + byte[] result = storage.readBytes("testFile.bin"); + assertArrayEquals(new byte[]{1, 2, 3}, result); + } + + @Test + void testWriteString_ShouldWriteToFile() { + String result = storage.writeString("testFile.txt", "Hello World"); + assertEquals("", result); + verify(mockFileHandle).writeString("Hello World", false); + } + + @Test + void testExists_ShouldReturnTrueIfFileExists() { + when(mockFileHandle.exists()).thenReturn(true); + assertTrue(storage.exists("testFile.txt")); + } + + @Test + void testIsDirectory_ShouldReturnTrueForDirectory() { + when(mockFileHandle.isDirectory()).thenReturn(true); + assertTrue(storage.isDirectory("testDir")); + } + + @Test + void testIsFile_ShouldReturnTrueForFile() { + when(mockFileHandle.isDirectory()).thenReturn(false); + assertTrue(storage.isFile("testFile.txt")); + } + + @Test + void testDebug_ShouldReturnFileTree() { + when(mockFileHandle.isDirectory()).thenReturn(true); + when(mockFileHandle.name()).thenReturn("root"); + + String result = storage.debug(); + assertEquals("root\n", result); + } + + @Test + void testRemoveDirectory_ShouldReturnTrueIfDirectoryDeleted() { + when(mockFileHandle.deleteDirectory()).thenReturn(true); + assertTrue(storage.removeDirectory("testDir")); + } + + @Test + void testGetRegularFileType_ShouldReturnTextForTextFile() { + when(mockFileHandle.readString()).thenReturn("This is text"); + assertEquals(RegularFileType.TEXT, storage.getRegularFileType("testFile.txt")); + } + + @Test + void testGetRegularFileType_ShouldReturnBinaryForBinaryFile() { + when(mockFileHandle.readString()).thenThrow(new RuntimeException()); + assertEquals(RegularFileType.BINARY, storage.getRegularFileType("testFile.bin")); + } +}