From 6df02abbe24dba9d935c65128ad3a82584cc63ed Mon Sep 17 00:00:00 2001 From: OliverSchlueter Date: Thu, 26 Sep 2024 11:17:29 +0200 Subject: [PATCH] Add JDB JSON storage and CI workflow --- .github/workflows/ci.yml | 39 ++ build.gradle.kts | 9 + src/main/java/de/oliver/fancylib/jdb/JDB.java | 117 ++++ .../de/oliver/fancylib/jdb/JDocument.java | 234 +++++++ .../java/de/oliver/fancylib/jdb/JDBTest.java | 195 ++++++ .../de/oliver/fancylib/jdb/JDocumentTest.java | 619 ++++++++++++++++++ 6 files changed, 1213 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 src/main/java/de/oliver/fancylib/jdb/JDB.java create mode 100644 src/main/java/de/oliver/fancylib/jdb/JDocument.java create mode 100644 src/test/java/de/oliver/fancylib/jdb/JDBTest.java create mode 100644 src/test/java/de/oliver/fancylib/jdb/JDocumentTest.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..19cbf66 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,39 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + + - name: Cache Gradle packages + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Grant execute permission for gradlew + run: chmod +x ./gradlew + + - name: Build with Gradle + run: ./gradlew build + + - name: Run tests + run: ./gradlew test \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 5c7de3d..f5f14ab 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,6 +25,11 @@ dependencies { // database drivers compileOnly("org.xerial:sqlite-jdbc:3.46.0.0") compileOnly("mysql:mysql-connector-java:8.0.33") + + // testing + testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.3") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.11.1") + testImplementation("com.google.code.gson:gson:2.11.0") } tasks { @@ -79,4 +84,8 @@ tasks { processResources { filteringCharset = Charsets.UTF_8.name() // We want UTF-8 for everything } + + test { + useJUnitPlatform() + } } diff --git a/src/main/java/de/oliver/fancylib/jdb/JDB.java b/src/main/java/de/oliver/fancylib/jdb/JDB.java new file mode 100644 index 0000000..711bcd6 --- /dev/null +++ b/src/main/java/de/oliver/fancylib/jdb/JDB.java @@ -0,0 +1,117 @@ +package de.oliver.fancylib.jdb; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.jetbrains.annotations.NotNull; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +/** + * The JDB class provides a simple JSON document-based storage system in a specified directory. + */ +public class JDB { + + private final static Gson GSON = new GsonBuilder() + .serializeNulls() + .setPrettyPrinting() + .create(); + + private final @NotNull String basePath; + private final @NotNull File baseFolder; + + /** + * Constructs a new JDB instance with the specified base path. + * + * @param basePath the base directory path where documents will be stored + */ + public JDB(@NotNull String basePath) { + this.basePath = basePath; + this.baseFolder = new File(basePath); + } + + /** + * Retrieves a document from the specified path, deserializing it into the given class type. + * + * @param the type of the object to be returned + * @param path the relative path (excluding .json extension) where the document is located + * @param clazz the class type to which the document should be deserialized + * @return a JDocument containing the deserialized object and its path, or null if the file does not exist + * @throws IOException if an I/O error occurs during file reading + */ + public T get(@NotNull String path, @NotNull Class clazz) throws IOException { + File file = new File(baseFolder, basePath + path + ".json"); + if (!file.exists()) { + return null; + } + + BufferedReader bufferedReader = Files.newBufferedReader(file.toPath()); + + return GSON.fromJson(bufferedReader, clazz); + } + + /** + * Retrieves all documents from the specified directory path, deserializing them into the given class type. + * + * @param the type of objects to be returned + * @param path the relative directory path containing the documents + * @param clazz the class type to which the documents should be deserialized + * @return a List of JDocument objects containing the deserialized objects and their paths, or null if the directory or files do not exist + * @throws IOException if an I/O error occurs during file reading + */ + public List getAll(@NotNull String path, @NotNull Class clazz) throws IOException { + File folder = new File(baseFolder, basePath + path); + if (!folder.exists()) { + return new ArrayList<>(); + } + + File[] files = folder.listFiles(); + if (files == null) { + return new ArrayList<>(); + } + + List documents = new ArrayList<>(files.length); + for (File file : files) { + documents.add(get(path + "/" + file.getName().replace(".json", ""), clazz)); + } + + return documents; + } + + /** + * Saves the given value as a document at the specified path. + * + * @param the type of the object to be saved + * @param path the relative path (excluding .json extension) where the document will be saved + * @param value the object to be saved as a JSON document + * @throws IOException if an I/O error occurs during file writing + */ + public void set(@NotNull String path, @NotNull T value) throws IOException { + File file = new File(baseFolder, basePath + path + ".json"); + + if (!file.exists()) { + file.getParentFile().mkdirs(); + file.createNewFile(); + } + + String json = GSON.toJson(value); + + Files.write(file.toPath(), json.getBytes()); + } + + /** + * Deletes the document(s) at the specified path. + * + * @param path the relative path (excluding .json extension) where the document(s) are located + */ + public void delete(@NotNull String path) { + File file = new File(baseFolder, basePath + path + ".json"); + if (file.exists()) { + file.delete(); + } + } +} diff --git a/src/main/java/de/oliver/fancylib/jdb/JDocument.java b/src/main/java/de/oliver/fancylib/jdb/JDocument.java new file mode 100644 index 0000000..62ce4a5 --- /dev/null +++ b/src/main/java/de/oliver/fancylib/jdb/JDocument.java @@ -0,0 +1,234 @@ +package de.oliver.fancylib.jdb; + +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Represents a document that holds a map of key-value pairs with support for nested keys. + */ +public class JDocument { + + private final @NotNull Map data; + + public JDocument(@NotNull Map data) { + this.data = data; + } + + /** + * Retrieves a value from the document using the given key. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return the value associated with the given key, or null if the key is not found + */ + public Object get(String key) { + String[] parts = key.split("\\."); + + Map current = data; + for (int i = 0; i < parts.length; i++) { + Object obj = current.get(parts[i]); + if (obj == null) { + return null; + } + + if (i == parts.length - 1) { + return obj; + } + + if (!(obj instanceof Map)) { + return null; + } + + current = (Map) obj; + } + + return null; + } + + /** + * Checks if the document contains a value associated with the given key. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return true if the given key exists in the document, otherwise false + */ + public boolean contains(String key) { + return get(key) != null; + } + + /** + * Retrieves the set of keys from a map value associated with a given key in the document. + * + * @param key the dot-separated key used to locate the map value in the document (e.g. "foo.bar.baz") + * @return a set of keys from the map associated with the given key, or an empty set if the key + * is not found or the value is not a map + */ + public Set getKeys(String key) { + Object obj = get(key); + if (obj == null) { + return new HashSet<>(); + } + + if (!isType(obj, Map.class)) { + return new HashSet<>(); + } + + Map map = (Map) data.get(key); + + return map.keySet(); + } + + /** + * Retrieves a string value from the document using the given key. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return the string value associated with the given key, or an empty string if the key is not found or the value is not a string + */ + public String getString(String key) { + Object obj = get(key); + if (obj == null) { + return ""; + } + + return (String) obj; + } + + /** + * Retrieves a boolean value associated with the given key. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return the boolean value associated with the given key, or false if the key is not found or the value is not a boolean + */ + public boolean getBoolean(String key) { + Object obj = get(key); + if (obj == null) { + return false; + } + + if (!isType(obj, Boolean.class)) { + return false; + } + + return (boolean) obj; + } + + /** + * Retrieves a byte value associated with the given key. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return the byte value associated with the given key, or 0 if the key is not found or the value is not a byte + */ + public byte getByte(String key) { + Object obj = get(key); + if (obj == null) { + return 0; + } + + if (!isType(obj, Byte.class)) { + return 0; + } + + return (byte) obj; + } + + /** + * Retrieves a short value associated with the given key. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return the short value associated with the given key, or 0 if the key is not found or the value is not a short + */ + public short getShort(String key) { + Object obj = get(key); + if (obj == null) { + return 0; + } + + if (!isType(obj, Short.class)) { + return 0; + } + + return (short) obj; + } + + /** + * Retrieves an integer value associated with the given key from the document. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return the integer value associated with the given key, or 0 if the key is not found or the value is not an integer + */ + public int getInt(String key) { + Object obj = get(key); + if (obj == null) { + return 0; + } + + if (!isType(obj, Integer.class)) { + return 0; + } + + return (int) obj; + } + + /** + * Retrieves a long value associated with the given key. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return the long value associated with the given key, or 0 if the key is not found or the value is not a long + */ + public long getLong(String key) { + Object obj = get(key); + if (obj == null) { + return 0; + } + + if (!isType(obj, Long.class)) { + return 0; + } + + return (long) obj; + } + + /** + * Retrieves a float value associated with the given key. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return the float value associated with the given key, or 0 if the key is not found + * or the value is not a float + */ + public float getFloat(String key) { + Object obj = get(key); + if (obj == null) { + return 0; + } + + if (!isType(obj, Float.class)) { + return 0; + } + + return (float) obj; + } + + /** + * Retrieves a double value associated with the given key. + * + * @param key the dot-separated key used to locate the value in the document (e.g. "foo.bar.baz") + * @return the double value associated with the given key, or 0 if the key is not found or the value is not a double + */ + public double getDouble(String key) { + Object obj = get(key); + if (obj == null) { + return 0; + } + + if (!isType(obj, Double.class)) { + return 0; + } + + return (double) obj; + } + + private boolean isType(@NotNull Object obj, Class clazz) { + return clazz.isInstance(obj); + } +} \ No newline at end of file diff --git a/src/test/java/de/oliver/fancylib/jdb/JDBTest.java b/src/test/java/de/oliver/fancylib/jdb/JDBTest.java new file mode 100644 index 0000000..ea843a8 --- /dev/null +++ b/src/test/java/de/oliver/fancylib/jdb/JDBTest.java @@ -0,0 +1,195 @@ +package de.oliver.fancylib.jdb; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +public class JDBTest { + + //This class tests the get operation of the JDB class, + //which is supposed to retrieve and deserialize a JSON document + //from a given path in the file system. + + private final String basePath = "./test_files/"; + + public static void cleanUpDirectory(String path) throws IOException { + Path directory = Paths.get(path); + if (Files.exists(directory)) { + Files.walkFileTree(directory, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } + } + + @BeforeEach + void setUp() throws IOException { + cleanUpDirectory(basePath); + } + + @AfterEach + void tearDown() throws IOException { + cleanUpDirectory(basePath); + } + + @Test + public void testGetObject() throws IOException { + // Prepare + String basePath = "./test_files/"; + JDB jdb = new JDB(basePath); + String path = "test_file"; + jdb.set(path, "Test message"); + + // Act + String result = jdb.get(path, String.class); + + // Assert + assertEquals("Test message", result); + } + + @Test + public void testGetObjectNonExisting() throws IOException { + // Prepare + JDB jdb = new JDB("./test_files/"); + String path = "does_not_exist"; + + // Act + Object result = jdb.get(path, Object.class); + + // Assert + assertNull(result); + } + + @Test + public void testGetAllObjects() throws IOException { + // Prepare + String basePath = "./test_files/"; + JDB jdb = new JDB(basePath); + String path = "test_files"; + jdb.set(path + "/obj1", "Test message 1"); + jdb.set(path + "/obj2", "Test message 2"); + jdb.set(path + "/obj3", "Test message 3"); + + // Act + List result = jdb.getAll(path, String.class); + + // Assert + assertEquals(3, result.size()); + assertTrue(result.contains("Test message 1")); + assertTrue(result.contains("Test message 2")); + assertTrue(result.contains("Test message 3")); + } + + @Test + public void testGetAllObjectsNonExisting() throws IOException { + // Prepare + JDB jdb = new JDB("./test_files/"); + String path = "does_not_exist"; + + // Act + List result = jdb.getAll(path, Object.class); + + // Assert + assertTrue(result.isEmpty()); + } + + @Test + public void testSetNewObject() throws IOException { + // Prepare + String basePath = "./test_files/"; + JDB jdb = new JDB(basePath); + String path = "new_object"; + String value = "New message"; + + // Act + jdb.set(path, value); + String result = jdb.get(path, String.class); + + // Assert + assertEquals(value, result); + } + + @Test + public void testSetExistingObject() throws IOException { + // Prepare + String basePath = "./test_files/"; + JDB jdb = new JDB(basePath); + String path = "existing_object"; + String value = "Existing message"; + jdb.set(path, "Old message"); + + // Act + jdb.set(path, value); + String result = jdb.get(path, String.class); + + // Assert + assertEquals(value, result); + } + + @Test + public void testSetObjectNull() throws IOException { + // Prepare + String basePath = "./test_files/"; + JDB jdb = new JDB(basePath); + String path = "null_object"; + + // Act + jdb.set(path, null); + String result = jdb.get(path, String.class); + + // Assert + assertNull(result); + } + + @Test + public void testDeleteWhenFileExists() throws IOException { + // Prepare + String basePath = "./test_files/"; + JDB jdb = new JDB(basePath); + String path = "existing_file"; + String value = "Test message"; + jdb.set(path, value); + + // Act + jdb.delete(path); + String result = jdb.get(path, String.class); + + // Assert + assertNull(result); + + File file = new File(basePath + path + ".json"); + assertFalse(file.exists()); + } + + @Test + public void testDeleteWhenFileNotExists() { + // Prepare + String basePath = "./test_files/"; + JDB jdb = new JDB(basePath); + String path = "non_existing_file"; + + // Act + jdb.delete(path); + + // Assert + File file = new File(basePath + path + ".json"); + assertFalse(file.exists()); + } +} diff --git a/src/test/java/de/oliver/fancylib/jdb/JDocumentTest.java b/src/test/java/de/oliver/fancylib/jdb/JDocumentTest.java new file mode 100644 index 0000000..a9baccc --- /dev/null +++ b/src/test/java/de/oliver/fancylib/jdb/JDocumentTest.java @@ -0,0 +1,619 @@ +package de.oliver.fancylib.jdb; + +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.*; + +public class JDocumentTest { + + /** + * The JDocumentTest class contains unit tests for the JDocument class. + * The get method in the JDocument class is being tested here. + */ + + @Test + public void testGet_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", "value1"); + JDocument jDocument = new JDocument(data); + + Object result = jDocument.get("key1"); + + assertNotNull(result); + assertEquals("value1", result.toString()); + } + + @Test + public void testGet_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + Object result = jDocument.get("key1"); + + assertNull(result); + } + + @Test + public void testGet_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", "value2"); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + Object result = jDocument.get("key1.key2"); + + assertNotNull(result); + assertEquals("value2", result.toString()); + } + + @Test + public void testGet_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", "value2"); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + Object result = jDocument.get("key1.key3"); + + assertNull(result); + } + + /** + * The contains method in the JDocument class is being tested here. + * It checks whether a given key is present in the JDocument's data or not. + */ + + @Test + public void testContains_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", "value1"); + JDocument jDocument = new JDocument(data); + + boolean result = jDocument.contains("key1"); + + assertTrue(result); + } + + @Test + public void testContains_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + boolean result = jDocument.contains("key1"); + + assertFalse(result); + } + + @Test + public void testContains_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", "value2"); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + boolean result = jDocument.contains("key1.key2"); + + assertTrue(result); + } + + @Test + public void testContains_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", "value2"); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + boolean result = jDocument.contains("key1.key3"); + + assertFalse(result); + } + + /** + * The getKeys method in the JDocument class is being tested here. + * It retrieves the keys of the nested Map present within the data. + */ + + @Test + public void testGetKeys_Success_SingleKey() { + Map innerData = new HashMap<>(); + innerData.put("innerKey1", "value1"); + + Map data = new HashMap<>(); + data.put("key1", innerData); + + JDocument jDocument = new JDocument(data); + + Set keys = jDocument.getKeys("key1"); + + assertNotNull(keys); + assertEquals(1, keys.size()); + assertTrue(keys.contains("innerKey1")); + } + + @Test + public void testGetKeys_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + Set keys = jDocument.getKeys("key1"); + + assertNotNull(keys); + assertTrue(keys.isEmpty()); + } + + @Test + public void testGetKeys_Success_MultipleKeys() { + Map innerData = new HashMap<>(); + innerData.put("innerKey1", "value1"); + innerData.put("innerKey2", "value2"); + + Map data = new HashMap<>(); + data.put("key1", innerData); + + JDocument jDocument = new JDocument(data); + + Set keys = jDocument.getKeys("key1"); + + assertNotNull(keys); + assertEquals(2, keys.size()); + assertTrue(keys.contains("innerKey1")); + assertTrue(keys.contains("innerKey2")); + } + + /** + * The getString method in the JDocument class is being tested here. + * It returns a String value of the specified key from the JDocument's data. + */ + + @Test + public void testGetString_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", "value1"); + JDocument jDocument = new JDocument(data); + + String result = jDocument.getString("key1"); + + assertNotNull(result); + assertEquals("value1", result); + } + + @Test + public void testGetString_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + String result = jDocument.getString("key1"); + + assertNotNull(result); + assertEquals("", result); + } + + @Test + public void testGetString_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", "value2"); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + String result = jDocument.getString("key1.key2"); + + assertNotNull(result); + assertEquals("value2", result); + } + + @Test + public void testGetString_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", "value2"); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + String result = jDocument.getString("key1.key3"); + + assertNotNull(result); + assertEquals("", result); + } + + /** + * The getBoolean method in the JDocument class is being tested here. + * It retrieves a boolean value of the specified key from the JDocument's data. + */ + + @Test + public void testGetBoolean_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", true); + JDocument jDocument = new JDocument(data); + + boolean result = jDocument.getBoolean("key1"); + + assertTrue(result); + } + + @Test + public void testGetBoolean_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + boolean result = jDocument.getBoolean("key1"); + + assertFalse(result); + } + + @Test + public void testGetBoolean_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", true); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + boolean result = jDocument.getBoolean("key1.key2"); + + assertTrue(result); + } + + @Test + public void testGetBoolean_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", true); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + boolean result = jDocument.getBoolean("key1.key3"); + + assertFalse(result); + } + + /** + * The getByte method in the JDocument class is being tested here. + * It retrieves a byte value of the specified key from the JDocument's data. + */ + + @Test + public void testGetByte_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", (byte) 1); + JDocument jDocument = new JDocument(data); + + byte result = jDocument.getByte("key1"); + + assertEquals((byte) 1, result); + } + + @Test + public void testGetByte_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + byte result = jDocument.getByte("key1"); + + assertEquals((byte) 0, result); + } + + @Test + public void testGetByte_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", (byte) 2); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + byte result = jDocument.getByte("key1.key2"); + + assertEquals((byte) 2, result); + } + + @Test + public void testGetByte_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", (byte) 2); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + byte result = jDocument.getByte("key1.key3"); + + assertEquals((byte) 0, result); + } + + /** + * The getShort method in the JDocument class is being tested here. + * It retrieves a short value of the specified key from the JDocument's data. + */ + + @Test + public void testGetShort_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", (short) 1); + JDocument jDocument = new JDocument(data); + + short result = jDocument.getShort("key1"); + + assertEquals((short) 1, result); + } + + @Test + public void testGetShort_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + short result = jDocument.getShort("key1"); + + assertEquals((short) 0, result); + } + + @Test + public void testGetShort_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", (short) 2); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + short result = jDocument.getShort("key1.key2"); + + assertEquals((short) 2, result); + } + + @Test + public void testGetShort_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", (short) 2); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + short result = jDocument.getShort("key1.key3"); + + assertEquals((short) 0, result); + } + + /** + * The getInt method in the JDocument class is being tested here. + * It retrieves an integer value of the specified key from the JDocument's data. + */ + + @Test + public void testGetInt_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", 123); + JDocument jDocument = new JDocument(data); + + int result = jDocument.getInt("key1"); + + assertEquals(123, result); + } + + @Test + public void testGetInt_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + int result = jDocument.getInt("key1"); + + assertEquals(0, result); + } + + @Test + public void testGetInt_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", 456); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + int result = jDocument.getInt("key1.key2"); + + assertEquals(456, result); + } + + @Test + public void testGetInt_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", 456); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + int result = jDocument.getInt("key1.key3"); + + assertEquals(0, result); + } + + /** + * The getLong method in the JDocument class is being tested here. + * It retrieves a long value of the specified key from the JDocument's data. + */ + + @Test + public void testGetLong_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", 123L); + JDocument jDocument = new JDocument(data); + + long result = jDocument.getLong("key1"); + + assertEquals(123L, result); + } + + @Test + public void testGetLong_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + long result = jDocument.getLong("key1"); + + assertEquals(0L, result); + } + + @Test + public void testGetLong_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", 456L); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + long result = jDocument.getLong("key1.key2"); + + assertEquals(456L, result); + } + + @Test + public void testGetLong_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", 456L); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + long result = jDocument.getLong("key1.key3"); + + assertEquals(0L, result); + } + + /** + * The getFloat method in the JDocument class is being tested here. + * It retrieves a float value of the specified key from the JDocument's data. + */ + @Test + public void testGetFloat_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", 1.23f); + JDocument jDocument = new JDocument(data); + + float result = jDocument.getFloat("key1"); + + assertEquals(1.23f, result); + } + + @Test + public void testGetFloat_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + float result = jDocument.getFloat("key1"); + + assertEquals(0f, result); + } + + @Test + public void testGetFloat_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", 4.56f); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + float result = jDocument.getFloat("key1.key2"); + + assertEquals(4.56f, result); + } + + @Test + public void testGetFloat_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", 4.56f); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + float result = jDocument.getFloat("key1.key3"); + + assertEquals(0f, result); + } + + /** + * The getDouble method in the JDocument class is being tested here. + * It retrieves a double value of the specified key from the JDocument's data. + */ + + @Test + public void testGetDouble_Success_SingleKey() { + Map data = new HashMap<>(); + data.put("key1", 1.23d); + JDocument jDocument = new JDocument(data); + + double result = jDocument.getDouble("key1"); + + assertEquals(1.23d, result); + } + + @Test + public void testGetDouble_Failure_KeyNotFound() { + JDocument jDocument = new JDocument(Collections.emptyMap()); + + double result = jDocument.getDouble("key1"); + + assertEquals(0d, result); + } + + @Test + public void testGetDouble_Success_NestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", 4.56d); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + double result = jDocument.getDouble("key1.key2"); + + assertEquals(4.56d, result); + } + + @Test + public void testGetDouble_Failure_NonExistentNestedKey() { + Map nestedData = new HashMap<>(); + nestedData.put("key2", 4.56d); + + Map data = new HashMap<>(); + data.put("key1", nestedData); + + JDocument jDocument = new JDocument(data); + + double result = jDocument.getDouble("key1.key3"); + + assertEquals(0d, result); + } +}