Skip to content

Commit

Permalink
add testcases
Browse files Browse the repository at this point in the history
  • Loading branch information
rPraml committed Feb 3, 2025
1 parent 558f17f commit c09c606
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 23 deletions.
4 changes: 4 additions & 0 deletions rhino/rhino-config-for-this-module.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This file is loaded by the RhinoPropertiesTest and can be used to modify values in this module

rhino.printTrees=true
rhino.printICode=true
7 changes: 7 additions & 0 deletions rhino/rhino-test.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# THIS FILE IS NOT USED BY DEFAULT
# There is a RhinoPropertiesLoader in this maven module
# If you want to reconfigure something, please use rhino-config-for-this-module.config (see RhinoPropertiesTest)

testconfig.bar=value4-mod
TESTCONFIG_BAZ=value5

30 changes: 20 additions & 10 deletions rhino/src/main/java/org/mozilla/javascript/config/RhinoConfig.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.mozilla.javascript.config;

import java.util.Locale;
import java.security.AccessController;
import java.security.PrivilegedAction;

/**
* With RhinoConfig, you can access the {@link RhinoProperties} in a typesafe way.
Expand All @@ -9,9 +10,13 @@
*/
public class RhinoConfig {

private static final RhinoProperties INSTANCE =
AccessController.doPrivileged(
(PrivilegedAction<RhinoProperties>) () -> RhinoProperties.init());

/** Returns the property as string. */
private static String get(String property, String defaultValue) {
Object ret = RhinoProperties.get(property);
Object ret = INSTANCE.get(property);
if (ret != null) {
return ret.toString();
}
Expand All @@ -25,31 +30,36 @@ public static String get(String property) {

/** Returns the property as enum. Note: default value must be specified */
public static <T extends Enum<T>> T get(String property, T defaultValue) {
Object ret = RhinoProperties.get(property);
Object ret = INSTANCE.get(property);
if (ret != null) {
Class<T> enumType = (Class<T>) defaultValue.getClass();
// We assume, that enums all are in UPPERCASES
return Enum.valueOf(enumType, ret.toString().toUpperCase(Locale.ROOT));
// We make a case insentive lookup here.
for (T enm : enumType.getEnumConstants()) {
if (enm.name().equalsIgnoreCase(ret.toString())) {
return enm;
}
}
}
return defaultValue;
}

/** Returns the property as boolean. */
public static boolean get(String property, boolean defaultValue) {
Object ret = RhinoProperties.get(property);
Object ret = INSTANCE.get(property);
if (ret instanceof Boolean) {
return (Boolean) ret;
} else {
return "1".equals(ret) || "true".equals(ret);
} else if (ret == null) {
return false;
}
return Boolean.parseBoolean(ret.toString());
}

/** Returns the property as integer. */
public static int get(String property, int defaultValue) {
Object ret = RhinoProperties.get(property);
Object ret = INSTANCE.get(property);
if (ret instanceof Number) {
return ((Number) ret).intValue();
} else {
} else if (ret != null) {
try {
return Integer.decode(ret.toString());
} catch (NumberFormatException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -51,9 +49,11 @@
public class RhinoProperties {

private static String[] CONFIG_FILES = {"rhino.config", "rhino-test.config"};
private static final RhinoProperties INSTANCE =
AccessController.doPrivileged((PrivilegedAction<RhinoProperties>) () -> init());

/**
* Initializes the default, used in RhinoConfig. If there is RhinoPropertiesLoader present, then
* this loader has full control. Ohterwise, properties are loaded from default locations.
*/
static RhinoProperties init() {
RhinoProperties props = new RhinoProperties();
Iterator<RhinoPropertiesLoader> loader =
Expand Down Expand Up @@ -96,7 +96,7 @@ public void loadFromFile(File config) {
addConfig(props);
} catch (IOException e) {
System.err.println(
"Error loading configuration from "
"Rhino: Error loading configuration from "
+ config.getAbsolutePath()
+ ": "
+ e.getMessage());
Expand All @@ -121,21 +121,21 @@ public void loadFromResource(URL resource) {
addConfig(props);
} catch (IOException e) {
System.err.println(
"Error loading configuration from " + resource + ": " + e.getMessage());
"Rhino: Error loading configuration from " + resource + ": " + e.getMessage());
}
}

/** Adds a config map */
/** Adds a config map. Later added configs are overriding previous ones */
public void addConfig(Map<?, ?> config) {
configs.add(config);
configs.add(0, config);
}

/**
* Tries to find the property in the maps. It tries the property first, then it tries the camel
* upper version.
*/
public static Object get(String property) {
for (Map<?, ?> map : INSTANCE.configs) {
public Object get(String property) {
for (Map<?, ?> map : configs) {
Object ret = map.get(property);
if (ret != null) {
return ret;
Expand All @@ -148,7 +148,7 @@ public static Object get(String property) {
return null;
}

private static String toCamelUpper(String property) {
private String toCamelUpper(String property) {
String s = property.replace('.', '_');
StringBuilder sb = new StringBuilder(s.length() + 5);
for (int i = 0; i < s.length(); ++i) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.mozilla.javascript.config;

/**
* Optional Loader interface for loading properties. You can override the
* DefaultRhinoPropertiesLoader by providing your implementation as service.
* Optional Loader interface for loading properties. You can override the default loading mechanism
* by providing your implementation as service.
*
* @author Roland Praml, Foconis Analytics GmbH
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package org.mozilla.javascript.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.File;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.mozilla.javascript.config.RhinoConfig;
import org.mozilla.javascript.config.RhinoProperties;
import org.mozilla.javascript.config.RhinoPropertiesLoader;

/**
* Testcase for various property loading mechanism. <br>
* Note: Testing is a bit difficult, so to test the serviceLoader mechanism, we have to register a
* RhinoPropertiesLoader in this maven module. Unfortunately, this means, that all other tests in
* this module will also use this loader. <br>
* The loader does NOT load the properties from the default locations as mentioned in the
* documentation. So, do not wonder, if setting config values in 'rhino.config' or
* 'rhino-test.config' do not take effect. Instead use `rhino-config-for-this-module.config`.
*
* @author Roland Praml, Foconis Analytics GmbH
*/
public class RhinoPropertiesTest {

/** This loader is used for all tests in this maven module! */
public static class Loader implements RhinoPropertiesLoader {

public static enum TestEnum {
valueA,
VALUEB,
valuec
}

@Override
public void load(RhinoProperties properties) {

properties.addConfig(Map.of("foo.bar", "baz1"));
properties.addConfig(
Map.of(
"foo.bar", "baz2",
"foo.someBoolean1", "true",
"foo.someBoolean2", "TRUE",
"foo.someBoolean3", "1",
"foo.someInteger1", "42",
"foo.someInteger2", 42,
"foo.someAValue", true,
"FOO_SOME_BVALUE", 42,
"FOO_ENUM1", "valuea"));
properties.addConfig(
Map.of(
"FOO_ENUM1", "valuea",
"FOO_ENUM2", "VALUEA",
"FOO_ENUM3", "VALUEB",
"FOO_ENUM4", "VALUEC",
"FOO_ENUM5", "VALUED"));
// load module independent file.
properties.loadFromFile(new File("rhino-config-for-this-module.config"));
}
}

/** Tests the loader initialization and all methods in RhinoConfig. */
@Test
void testLoaderInit() {
// override test
assertEquals("baz2", RhinoConfig.get("foo.bar"));

// normal getters (with correct type)
assertEquals(true, RhinoConfig.get("foo.someBoolean1", false));
assertEquals(true, RhinoConfig.get("foo.someBoolean2", false));
assertEquals(false, RhinoConfig.get("foo.someBoolean3", false));
assertEquals(false, RhinoConfig.get("foo.someOtherBoolean", false));

// integer test
assertEquals(42, RhinoConfig.get("foo.someInteger1", 21));
assertEquals(42, RhinoConfig.get("foo.someInteger2", 21));
assertEquals(21, RhinoConfig.get("foo.someOtherInteger", 21));

// camelCase-Tests
assertEquals(true, RhinoConfig.get("foo.someAValue", false));
assertEquals(42, RhinoConfig.get("foo.someBValue", 21));

// enums
assertEquals(Loader.TestEnum.valueA, RhinoConfig.get("foo.enum1", Loader.TestEnum.VALUEB));
assertEquals(Loader.TestEnum.valueA, RhinoConfig.get("foo.enum2", Loader.TestEnum.VALUEB));
assertEquals(Loader.TestEnum.VALUEB, RhinoConfig.get("foo.enum3", Loader.TestEnum.valueA));
assertEquals(Loader.TestEnum.valuec, RhinoConfig.get("foo.enum4", Loader.TestEnum.valueA));
assertEquals(Loader.TestEnum.valueA, RhinoConfig.get("foo.enum5", Loader.TestEnum.valueA));
assertEquals(Loader.TestEnum.valueA, RhinoConfig.get("foo.enum6", Loader.TestEnum.valueA));
}

/** Tests explicit loading a file from classpath. */
@Test
void testClasspathLoad() {
RhinoProperties properties = new RhinoProperties();
properties.loadFromClasspath(getClass().getClassLoader(), "rhino-testcase.config");
assertEquals("value1", properties.get("testconfig.foo"));
assertEquals("value2", properties.get("testconfig.bar"));
}

/** Tests explicit loading a file. */
@Test
void testFileLoad() {
RhinoProperties properties = new RhinoProperties();
properties.loadFromFile(new File("resources/rhino-testcase.config"));
assertEquals("value1", properties.get("testconfig.foo"));
assertEquals("value2", properties.get("testconfig.bar"));
}

@Test
void testDefaultLoad() {
System.setProperty("some.system.value", "value6");
try {
RhinoProperties properties = new RhinoProperties();
properties.loadDefaults();
assertEquals("value3", properties.get("testconfig.foo"));
assertEquals("value4-mod", properties.get("testconfig.bar"));
assertEquals("value5", properties.get("testconfig.baz"));
assertEquals("value6", properties.get("some.system.value"));
} finally {
System.clearProperty("some.system.value");
}
}

/** System properties */
@Test
void testSystemOverride() {
System.setProperty("testconfig.foo", "system-wins");
try {
RhinoProperties properties = new RhinoProperties();
properties.loadDefaults();
assertEquals("system-wins", properties.get("testconfig.foo"));
} finally {
System.clearProperty("testconfig.foo");
}
}

@Test
void testEnv() {
RhinoProperties properties = new RhinoProperties();
properties.loadDefaults();
// TODO: can/shoud we set an environment value. so check, if we can read PATH
assertNotNull(properties.get("path"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.mozilla.javascript.tests.RhinoPropertiesTest$Loader
2 changes: 2 additions & 0 deletions rhino/src/test/resources/rhino-testcase.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
testconfig.foo=value1
TESTCONFIG_BAR=value2
7 changes: 7 additions & 0 deletions rhino/src/test/resources/rhino.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# THIS FILE IS NOT USED BY DEFAULT
# There is a RhinoPropertiesLoader in this maven module
# If you want to reconfigure something, please see RhinoPropertiesTest

testconfig.foo=value3
TESTCONFIG_BAR=value4

0 comments on commit c09c606

Please sign in to comment.