diff --git a/README.md b/README.md index bb04ba8..54f0fcf 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,84 @@ # Overview -Library designed for retrieving properties set at application startup. +Library designed for retrieving properties set at application startup. If you don't use Spring Framework/Spring Boot but +like its configuration via yaml - you will find this library useful. + +# Advantages + +1) Lightweight, no need to pull lots of dependencies +2) No reflection and typecasts +3) Null safe and runtime exception free # Quick start + This library is distributed via [jitpack.io](https://jitpack.io/#ArtemGet/entrys) -# Supported properties +# Supported entries + 1) Properties passed via -D -2) Json files (strings, objects, arrays) +2) Environment variables +3) Json strings +4) Yaml files + +# Examples + +## Properties: + +```java +String prop=new EProp("your_prop_passed_via_-D").value(); +``` + +## Environment variables: + +```java +String env=new EEnv("my_env").value() +``` + +## Json strings: + +TODO add docs + +## Yaml files: + +1) Works similar to spring + framework [@Value](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Value.html) +2) Supports string, number, arrays, float, boolean as value +3) Supports default values and env injections +4) Default yaml file config is placed under "src/main/resources/application.yaml", but is configurable + +```yaml +sex: "male" +person: + name: "kekus" + languages: [ ru,en ] + age: ${AGE_ENV:123} +``` + +#### Getting attribute: + +```java +String sex=new EVal("sex").value(); +``` + +#### Getting nested attribute: + +```java +String name=new EVal("person.name").value(); +``` + +#### Getting array + +```java +List languages=new ESplit(new EVal("person.languages")).value(); +``` + +#### Getting env + +```java +String age=new EVal("person.age").value(); +``` -TODO: -1) Environment variables -2) Yaml files -3) Properties files +1) If there is a default value and env is not present - will return default value +2) If there is a default value and env is present - will return value from env +3) If default value is not present - will return value from env diff --git a/pom.xml b/pom.xml index 6817037..12158d5 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,17 @@ 21 + + com.amihaiemil.web + eo-yaml + 8.0.6 + + + javax.json + javax.json-api + + + org.glassfish jakarta.json @@ -27,7 +38,6 @@ org.cactoos cactoos 0.57.0 - provided org.hamcrest diff --git a/src/main/java/io/github/artemget/entrys/file/EFile.java b/src/main/java/io/github/artemget/entrys/file/EFile.java new file mode 100644 index 0000000..b2a7b7c --- /dev/null +++ b/src/main/java/io/github/artemget/entrys/file/EFile.java @@ -0,0 +1,63 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.file; + +import io.github.artemget.entrys.ESafe; +import io.github.artemget.entrys.EntryException; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * File's content entry. + * + * @since 0.4.0 + */ +public class EFile extends ESafe { + public EFile(final String path) { + this(path, StandardCharsets.UTF_8); + } + + public EFile(final String path, final Charset charset) { + super( + () -> { + try { + return Files.readString(Path.of(path), charset); + } catch (final IOException | SecurityException exception) { + throw new EntryException( + String.format( + "Failed to load contents of file for path: '%s'", + path + ), + exception + ); + } + }, + () -> String.format("Empty file for path: '%s'", path) + ); + } +} diff --git a/src/main/java/io/github/artemget/entrys/file/EVal.java b/src/main/java/io/github/artemget/entrys/file/EVal.java new file mode 100644 index 0000000..a6e131d --- /dev/null +++ b/src/main/java/io/github/artemget/entrys/file/EVal.java @@ -0,0 +1,134 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.file; + +import com.amihaiemil.eoyaml.Node; +import com.amihaiemil.eoyaml.Yaml; +import com.amihaiemil.eoyaml.YamlMapping; +import com.amihaiemil.eoyaml.YamlNode; +import io.github.artemget.entrys.ESafe; +import io.github.artemget.entrys.Entry; +import io.github.artemget.entrys.EntryException; +import io.github.artemget.entrys.operation.EContains; +import io.github.artemget.entrys.operation.EFork; +import io.github.artemget.entrys.operation.ESplit; +import io.github.artemget.entrys.operation.EUnwrap; +import io.github.artemget.entrys.system.EEnv; +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Configuration properties entry. + * By default gets entries from "src/main/resources/application.yaml" + * Supports all yaml types, default values and envs passed via ${ENV}. + * + * @since 0.4.0 + */ +public final class EVal extends ESafe { + + /** + * From yaml file at default dir. + * + * @param key Of entry + */ + public EVal(final String key) { + this(key, "src/main/resources/application.yaml"); + } + + /** + * From yaml file. + * + * @param key Of entry + * @param path To yaml file + */ + public EVal(final String key, final String path) { + this(key, new EFile(path)); + } + + /** + * Main ctor. + * + * @param key Of Entry + * @param content Yaml content + */ + @SuppressWarnings("PMD.ConstructorOnlyInitializesOrCallOtherConstructors") + public EVal(final String key, final Entry content) { + super( + () -> { + YamlMapping root; + try { + root = Yaml.createYamlInput(content.value()) + .readYamlMapping(); + } catch (final IOException | EntryException exception) { + throw new EntryException( + String.format("Failed to read yaml mapping for key: '%s'", key), + exception + ); + } + String res = null; + final List elements = new ESplit(() -> key, ".").value(); + for (int element = 0; element < elements.size(); ++element) { + if (element == elements.size() - 1) { + final YamlNode value = root.value(elements.get(element)); + if (Node.SCALAR == value.type()) { + res = EVal.ejected(value); + } else if (Node.SEQUENCE == value.type()) { + res = value.asSequence() + .children().stream() + .map(node -> node.asScalar().value()) + .collect(Collectors.joining(";")); + } + } + root = root.yamlMapping(elements.get(element)); + } + return res; + }, + () -> String.format("Attribute for key '%s' is null", key) + ); + } + + private static String ejected(final YamlNode node) throws EntryException { + final String scalar = node.asScalar().value(); + return new EFork<>( + () -> scalar.startsWith("${") && scalar.endsWith("}"), + new EFork<>( + () -> new ESplit(() -> scalar, ":").value().size() == 2, + new EFork<>( + new EContains(new EEnv(() -> EVal.selected(scalar, 0).trim())), + new EEnv(() -> EVal.selected(scalar, 0).trim()), + () -> EVal.selected(scalar, 1).trim() + ), + new EEnv(new EUnwrap(scalar, "${", "}")) + ), + () -> scalar + ).value(); + } + + private static String selected(final String scalar, final int pos) throws EntryException { + return new ESplit(new EUnwrap(scalar, "${", "}"), ":") + .value().get(pos); + } +} diff --git a/src/main/java/io/github/artemget/entrys/file/package-info.java b/src/main/java/io/github/artemget/entrys/file/package-info.java new file mode 100644 index 0000000..63f8894 --- /dev/null +++ b/src/main/java/io/github/artemget/entrys/file/package-info.java @@ -0,0 +1,28 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * Entries that read stuff from files. + */ +package io.github.artemget.entrys.file; diff --git a/src/main/java/io/github/artemget/entrys/operation/EContains.java b/src/main/java/io/github/artemget/entrys/operation/EContains.java new file mode 100644 index 0000000..f6c97c7 --- /dev/null +++ b/src/main/java/io/github/artemget/entrys/operation/EContains.java @@ -0,0 +1,61 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.operation; + +import io.github.artemget.entrys.ESafe; +import io.github.artemget.entrys.Entry; +import io.github.artemget.entrys.EntryException; + +/** + * Returns either entry is empty or not. + * + * @since 0.4.0 + */ +public final class EContains implements Entry { + /** + * Origin entry. + */ + private final Entry entry; + + /** + * Main ctor. + * + * @param entry To check + */ + public EContains(final Entry entry) { + this.entry = new ESafe<>(entry); + } + + @Override + public Boolean value() throws EntryException { + boolean contains = true; + try { + this.entry.value(); + } catch (final EntryException exception) { + contains = false; + } + return contains; + } +} diff --git a/src/main/java/io/github/artemget/entrys/operation/EFork.java b/src/main/java/io/github/artemget/entrys/operation/EFork.java new file mode 100644 index 0000000..a28ae8c --- /dev/null +++ b/src/main/java/io/github/artemget/entrys/operation/EFork.java @@ -0,0 +1,75 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.operation; + +import io.github.artemget.entrys.Entry; +import io.github.artemget.entrys.EntryException; + +/** + * Fork between origin and spare entries. + * + * @param Type + * @since 0.4.0 + */ +public final class EFork implements Entry { + /** + * Condition. + */ + private final Entry condition; + + /** + * Origin entry. + */ + private final Entry origin; + + /** + * Spare entry. + */ + private final Entry spare; + + /** + * Main ctor. + * + * @param condition To check + * @param origin Entry + * @param spare Entry + */ + public EFork(final Entry condition, final Entry origin, final Entry spare) { + this.condition = condition; + this.origin = origin; + this.spare = spare; + } + + @Override + public T value() throws EntryException { + final T value; + if (this.condition.value()) { + value = this.origin.value(); + } else { + value = this.spare.value(); + } + return value; + } +} diff --git a/src/main/java/io/github/artemget/entrys/operation/ESplit.java b/src/main/java/io/github/artemget/entrys/operation/ESplit.java new file mode 100644 index 0000000..ec26284 --- /dev/null +++ b/src/main/java/io/github/artemget/entrys/operation/ESplit.java @@ -0,0 +1,83 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.operation; + +import io.github.artemget.entrys.ESafe; +import io.github.artemget.entrys.Entry; +import io.github.artemget.entrys.EntryException; +import java.util.List; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +/** + * Split entry. + * @since 0.4.0 + */ +public final class ESplit implements Entry> { + /** + * Origin string entry. + */ + private final Entry origin; + + /** + * Split delimiter. + */ + private final String delimiter; + + /** + * Creates split entry with default ; delimiter. + * @param origin Entry + */ + public ESplit(final Entry origin) { + this(origin, ";"); + } + + /** + * Main ctor. + * @param origin Entry + * @param delimiter For splitting + */ + public ESplit(final Entry origin, final String delimiter) { + this.origin = new ESafe<>(origin); + this.delimiter = delimiter; + } + + @Override + public List value() throws EntryException { + final String value = this.origin.value(); + try { + return List.of(value.split(Pattern.quote(this.delimiter))); + } catch (final PatternSyntaxException exception) { + throw new EntryException( + String.format( + "Wrong pattern delimiter: %s for entry value: %s", + this.delimiter, + value + ), + exception + ); + } + } +} diff --git a/src/main/java/io/github/artemget/entrys/operation/EUnwrap.java b/src/main/java/io/github/artemget/entrys/operation/EUnwrap.java new file mode 100644 index 0000000..dd6a88f --- /dev/null +++ b/src/main/java/io/github/artemget/entrys/operation/EUnwrap.java @@ -0,0 +1,98 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.operation; + +import io.github.artemget.entrys.ESafe; +import io.github.artemget.entrys.Entry; +import io.github.artemget.entrys.EntryException; + +/** + * Unwraps value between prefix and suffix. + * + * @since 0.4.0 + */ +public final class EUnwrap implements Entry { + /** + * Origin entry. + */ + private final Entry origin; + + /** + * Ctor with default '{}' wraps. + * + * @param value String itself + */ + public EUnwrap(final String value) { + this(value, "{", "}"); + } + + /** + * Ctor with custom suffix and prefix. + * + * @param value String itself + * @param prefix Of string + * @param suffix Of string + */ + public EUnwrap(final String value, final String prefix, final String suffix) { + this( + new ESafe<>( + () -> { + final String unwrapped; + try { + final int start = value.indexOf(prefix) + prefix.length(); + unwrapped = value.substring( + start, + value.indexOf(suffix, start) + ); + } catch (final IndexOutOfBoundsException exception) { + throw new EntryException( + String.format( + "Failed to unwrap value:'%s' with prefix:'%s' and suffix:'%s'", + value, + prefix, + suffix + ), + exception + ); + } + return unwrapped; + } + ) + ); + } + + /** + * Main ctor. + * @param origin Entry + */ + private EUnwrap(final Entry origin) { + this.origin = origin; + } + + @Override + public String value() throws EntryException { + return this.origin.value(); + } +} diff --git a/src/main/java/io/github/artemget/entrys/operation/package-info.java b/src/main/java/io/github/artemget/entrys/operation/package-info.java new file mode 100644 index 0000000..70c2c96 --- /dev/null +++ b/src/main/java/io/github/artemget/entrys/operation/package-info.java @@ -0,0 +1,28 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * Entry operation directory. + */ +package io.github.artemget.entrys.operation; diff --git a/src/main/java/io/github/artemget/entrys/system/EEnv.java b/src/main/java/io/github/artemget/entrys/system/EEnv.java index c3bbb4f..6a426f6 100644 --- a/src/main/java/io/github/artemget/entrys/system/EEnv.java +++ b/src/main/java/io/github/artemget/entrys/system/EEnv.java @@ -25,6 +25,7 @@ package io.github.artemget.entrys.system; import io.github.artemget.entrys.ESafe; +import io.github.artemget.entrys.Entry; /** * Environment entry. @@ -32,13 +33,21 @@ */ public final class EEnv extends ESafe { + /** + * Entry ctor. + * @param name Entry + */ + public EEnv(final String name) { + this(() -> name); + } + /** * Main ctor. * @param name Of environment entry */ - public EEnv(final String name) { + public EEnv(final Entry name) { super( - () -> System.getenv(name), + () -> System.getenv(name.value()), () -> String.format("Empty environment entry for name %s", name) ); } diff --git a/src/test/java/io/github/artemget/entrys/file/EValTest.java b/src/test/java/io/github/artemget/entrys/file/EValTest.java new file mode 100644 index 0000000..7e221eb --- /dev/null +++ b/src/test/java/io/github/artemget/entrys/file/EValTest.java @@ -0,0 +1,212 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.file; + +import io.github.artemget.entrys.EntryException; +import io.github.artemget.entrys.fake.EFake; +import io.github.artemget.entrys.fake.EFakeErr; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import uk.org.webcompere.systemstubs.environment.EnvironmentVariables; + +/** + * Test cases for {@link io.github.artemget.entrys.json.EJsonArr}. + * @since 0.4.0 + */ +@SuppressWarnings({"PMD.AvoidDuplicateLiterals", "PMD.TooManyMethods"}) +final class EValTest { + + @Test + void throwsAtEmptyContent() { + Assertions.assertThrows( + EntryException.class, + () -> new EVal("abc", new EFakeErr<>()).value(), + "Didnt throw at error getting content" + ); + } + + @Test + void parsesString() throws EntryException { + Assertions.assertEquals( + "123", + new EVal("age", new EFake<>("age: \"123\"")).value(), + "String not parsed" + ); + } + + @Test + void parsesInteger() throws EntryException { + Assertions.assertEquals( + Integer.MAX_VALUE, + Integer.parseInt( + new EVal("age", new EFake<>(String.format("age: %s", Integer.MAX_VALUE))).value() + ), + "Integer not parsed" + ); + } + + @Test + void parsesLong() throws EntryException { + Assertions.assertEquals( + Long.MAX_VALUE, + Long.parseLong( + new EVal("age", new EFake<>(String.format("age: %s", Long.MAX_VALUE))).value() + ), + "Long not parsed" + ); + } + + @Test + void parsesFloat() throws EntryException { + Assertions.assertEquals( + Float.MAX_VALUE, + Float.parseFloat( + new EVal("age", new EFake<>(String.format("age: %s", Float.MAX_VALUE))).value() + ), + "Float not parsed" + ); + } + + @Test + void parsesBoolean() throws EntryException { + Assertions.assertTrue( + Boolean.parseBoolean(new EVal("age", new EFake<>("age: true")).value()), + "Boolean not parsed" + ); + } + + @Test + void throwsAtNullValue() { + Assertions.assertThrows( + EntryException.class, + () -> new EVal("age", new EFake<>("age: null")).value(), + "Didnt throw at null value" + ); + } + + @Test + void throwsAtNullAttribute() { + Assertions.assertThrows( + EntryException.class, + () -> new EVal("age", new EFake<>("age2: null")).value(), + "Didnt throw at null value" + ); + } + + @Test + void parsesInnerNode() throws EntryException { + Assertions.assertEquals( + "123", + new EVal( + "person.age", + new EFake<>("person:\n age: \"123\"") + ).value(), + "Inner node not parsed" + ); + } + + @Test + void parsesArray() throws EntryException { + Assertions.assertEquals( + "123;321", + new EVal("ages", new EFake<>("ages: [ 123, 321 ]")).value(), + "Array node not parsed" + ); + } + + @Test + void parsesEmptyArray() throws EntryException { + Assertions.assertEquals( + "", + new EVal( + "ages", + new EFake<>( + "ages: []" + ) + ).value(), + "Empty array not parsed" + ); + } + + @Test + void parsesAnotherArray() throws EntryException { + Assertions.assertEquals( + "123;321", + new EVal( + "ages", + new EFake<>("ages:\n - 123\n - 321") + ).value(), + "Array not parsed" + ); + } + + @Test + void parsesStringWrap() throws EntryException { + Assertions.assertEquals( + " First line.\n Second line.\n", + new EVal( + "description", + new EFake<>("description: >\n First line.\n Second line.") + ).value(), + "String wrap not parsed" + ); + } + + @Test + void parsesDefaultValueAtMissingEnv() throws EntryException { + Assertions.assertEquals( + "123", + new EVal( + "age", + new EFake<>( + "age: ${my_env:123}" + ) + ).value(), + "Not parsed default value" + ); + } + + @Test + void parsesEnv() throws Exception { + Assertions.assertEquals( + "321", + new EnvironmentVariables("my_env", "321").execute( + () -> new EVal("age", new EFake<>("age: ${my_env}")).value() + ), + "Not parsed default value" + ); + } + + @Test + void parsesEnvOverwritesDefaultValue() throws Exception { + Assertions.assertEquals( + "111", + new EnvironmentVariables("my_env", "111").execute( + () -> new EVal("age", new EFake<>("age: ${my_env:123}")).value() + ), + "Not parsed default value" + ); + } +} diff --git a/src/test/java/io/github/artemget/entrys/file/package-info.java b/src/test/java/io/github/artemget/entrys/file/package-info.java new file mode 100644 index 0000000..9821934 --- /dev/null +++ b/src/test/java/io/github/artemget/entrys/file/package-info.java @@ -0,0 +1,28 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * Tests for entries that read stuff from files. + */ +package io.github.artemget.entrys.file; diff --git a/src/test/java/io/github/artemget/entrys/operation/EContainsTest.java b/src/test/java/io/github/artemget/entrys/operation/EContainsTest.java new file mode 100644 index 0000000..7f28ffc --- /dev/null +++ b/src/test/java/io/github/artemget/entrys/operation/EContainsTest.java @@ -0,0 +1,62 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.operation; + +import io.github.artemget.entrys.EntryException; +import io.github.artemget.entrys.fake.EFake; +import io.github.artemget.entrys.fake.EFakeErr; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Test cases for {@link EContains}. + * @since 0.4.0 + */ +final class EContainsTest { + + @Test + void contains() throws EntryException { + Assertions.assertTrue( + new EContains(new EFake<>("123")).value(), + "Not contains" + ); + } + + @Test + void containsNot() throws EntryException { + Assertions.assertFalse( + new EContains(new EFakeErr<>()).value(), + "Contains" + ); + } + + @Test + void containsNotWhenNull() throws EntryException { + Assertions.assertFalse( + new EContains(new EFake<>(null)).value(), + "Contains" + ); + } +} diff --git a/src/test/java/io/github/artemget/entrys/operation/EForkTest.java b/src/test/java/io/github/artemget/entrys/operation/EForkTest.java new file mode 100644 index 0000000..e3a97e8 --- /dev/null +++ b/src/test/java/io/github/artemget/entrys/operation/EForkTest.java @@ -0,0 +1,63 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.operation; + +import io.github.artemget.entrys.EntryException; +import io.github.artemget.entrys.fake.EFake; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Test cases for {@link EFork}. + * @since 0.4.0 + */ +final class EForkTest { + + @Test + void returnsOrigin() throws EntryException { + Assertions.assertEquals( + "123", + new EFork<>( + () -> true, + new EFake<>("123"), + new EFake<>("321") + ).value(), + "Returned spare" + ); + } + + @Test + void returnsSpare() throws EntryException { + Assertions.assertEquals( + "321", + new EFork<>( + () -> false, + new EFake<>("123"), + new EFake<>("321") + ).value(), + "Returned origin" + ); + } +} diff --git a/src/test/java/io/github/artemget/entrys/operation/EUnwrapTest.java b/src/test/java/io/github/artemget/entrys/operation/EUnwrapTest.java new file mode 100644 index 0000000..2ee21ca --- /dev/null +++ b/src/test/java/io/github/artemget/entrys/operation/EUnwrapTest.java @@ -0,0 +1,82 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package io.github.artemget.entrys.operation; + +import io.github.artemget.entrys.EntryException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Test cases for {@link EUnwrap}. + * @since 0.4.0 + */ +@SuppressWarnings("PMD.AvoidDuplicateLiterals") +final class EUnwrapTest { + + @Test + void unwraps() throws EntryException { + Assertions.assertEquals( + "123", + new EUnwrap("{123}").value(), + "Not unwrap value with default wraps" + ); + } + + @Test + void unwrapsNotDefault() throws EntryException { + Assertions.assertEquals( + "123", + new EUnwrap("${123}", "${", "}").value(), + "Not unwrap value with custom wraps" + ); + } + + @Test + void unwrapsInside() throws EntryException { + Assertions.assertEquals( + "123", + new EUnwrap("blah-blah${123}blah-blah", "${", "}").value(), + "Not unwrap value with custom wraps inside bigger string" + ); + } + + @Test + void unwrapsFirst() throws EntryException { + Assertions.assertEquals( + "123", + new EUnwrap("${123}${321}", "${", "}").value(), + "Not unwrap first value with custom wraps inside bigger string" + ); + } + + @Test + void unwrapsNotWithoutWraps() { + Assertions.assertThrows( + EntryException.class, + () -> new EUnwrap("123").value(), + "Not thrown at value without wraps" + ); + } +} diff --git a/src/test/java/io/github/artemget/entrys/operation/package-info.java b/src/test/java/io/github/artemget/entrys/operation/package-info.java new file mode 100644 index 0000000..7507994 --- /dev/null +++ b/src/test/java/io/github/artemget/entrys/operation/package-info.java @@ -0,0 +1,28 @@ +/* + * MIT License + * + * Copyright (c) 2024-2025. Artem Getmanskii + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/** + * Test cases for entry operations. + */ +package io.github.artemget.entrys.operation;