settings: use WpSpaJson to parse the settings

We need to use WpSpaJson to parse the values in WpSettings. This is because the
wireplumber configuration is written in JSON, so WpSettings should only hold
JSON values. To fix this, 2 API changes have been done:

- wp_settings_get_int() only accepts gint values, instead of gint64 values. This
is because the WpSpaJson API only parses int values, like spa_json_parse_int().

- wp_settings_get_string() now returns a newly allocated string, this is because
the string needs to be decoded in case it has quotes.
This commit is contained in:
Julian Bouzas
2022-08-11 11:30:10 -04:00
parent 9f2168e022
commit 2223cd47d4
8 changed files with 235 additions and 246 deletions

View File

@@ -174,19 +174,8 @@ gboolean
wp_settings_get_boolean (WpSettings *self, const gchar *setting,
gboolean *value)
{
g_return_val_if_fail (WP_IS_SETTINGS (self), FALSE);
g_return_val_if_fail (setting, FALSE);
if (!(wp_object_get_active_features (WP_OBJECT (self)) &
WP_OBJECT_FEATURES_ALL))
return false;
if (!wp_properties_get (self->settings, setting))
return false;
*value = spa_atob (wp_properties_get (self->settings, setting));
return true;
g_autoptr (WpSpaJson) json = wp_settings_get (self, setting);
return json && wp_spa_json_parse_boolean (json, value);
}
/*!
@@ -194,26 +183,14 @@ wp_settings_get_boolean (WpSettings *self, const gchar *setting,
* \ingroup wpsettings
* \param self the settings object
* \param setting name of the setting
* \param value (out): the string value of the setting
* \returns TRUE if the setting is defined, FALSE otherwise
* \returns (transfer full) (nullable): the string value of the setting, or NULL
* if the string could not be parsed
*/
gboolean
wp_settings_get_string (WpSettings *self, const gchar *setting,
const gchar **value)
gchar *
wp_settings_get_string (WpSettings *self, const gchar *setting)
{
g_return_val_if_fail (WP_IS_SETTINGS (self), FALSE);
g_return_val_if_fail (setting, FALSE);
if (!(wp_object_get_active_features (WP_OBJECT (self)) &
WP_OBJECT_FEATURES_ALL))
return FALSE;
if (!wp_properties_get (self->settings, setting))
return FALSE;
*value = wp_properties_get (self->settings, setting);
return TRUE;
g_autoptr (WpSpaJson) json = wp_settings_get (self, setting);
return json ? wp_spa_json_parse_string (json) : NULL;
}
/*!
@@ -221,27 +198,15 @@ wp_settings_get_string (WpSettings *self, const gchar *setting,
* \ingroup wpsettings
* \param self the settings object
* \param setting name of the setting
* \param val (out): the integer value of the setting
* \param value (out): the integer value of the setting
* \returns TRUE if the setting is defined, FALSE otherwise
*/
gboolean
wp_settings_get_int (WpSettings *self, const gchar *setting,
gint64 *val)
gint *value)
{
g_return_val_if_fail (WP_IS_SETTINGS (self), FALSE);
g_return_val_if_fail (setting, FALSE);
if (!(wp_object_get_active_features (WP_OBJECT (self)) &
WP_OBJECT_FEATURES_ALL))
return FALSE;
if (!wp_properties_get (self->settings, setting))
return FALSE;
*val = 0; /* ground the value */
spa_atoi64 (wp_properties_get (self->settings, setting), val, 0);
return TRUE;
g_autoptr (WpSpaJson) json = wp_settings_get (self, setting);
return json && wp_spa_json_parse_int (json, value);
}
/*!
@@ -249,25 +214,39 @@ wp_settings_get_int (WpSettings *self, const gchar *setting,
* \ingroup wpsettings
* \param self the settings object
* \param setting name of the setting
* \param val (out): the float value of the setting
* \param value (out): the float value of the setting
* \returns TRUE if the setting is defined, FALSE otherwise
*/
gboolean
wp_settings_get_float (WpSettings *self, const gchar *setting,
gfloat *val)
gfloat *value)
{
g_return_val_if_fail (WP_IS_SETTINGS (self), FALSE);
g_return_val_if_fail (setting, FALSE);
g_autoptr (WpSpaJson) json = wp_settings_get (self, setting);
return json && wp_spa_json_parse_float (json, value);
}
/*!
* \brief Gets the WpSpaJson of a setting
* \ingroup wpsettings
* \param self the settings object
* \param setting name of the setting
* \returns (transfer full) (nullable): The WpSpaJson of the setting, or NULL
* if the setting does not exist
*/
WpSpaJson *
wp_settings_get (WpSettings *self, const gchar *setting)
{
const gchar *value;
g_return_val_if_fail (WP_IS_SETTINGS (self), NULL);
g_return_val_if_fail (setting, NULL);
if (!(wp_object_get_active_features (WP_OBJECT (self)) &
WP_OBJECT_FEATURES_ALL))
return FALSE;
return NULL;
if (!wp_properties_get (self->settings, setting))
return FALSE;
spa_atof (wp_properties_get (self->settings, setting), val);
return TRUE;
value = wp_properties_get (self->settings, setting);
return value ? wp_spa_json_new_from_string (value) : NULL;
}
/*!

View File

@@ -10,6 +10,7 @@
#define __WIREPLUMBER_SETTINGS_H__
#include "object.h"
#include "spa-json.h"
G_BEGIN_DECLS
@@ -65,16 +66,18 @@ gboolean wp_settings_get_boolean (WpSettings *self, const gchar *setting,
gboolean *value);
WP_API
gboolean wp_settings_get_string (WpSettings *self, const gchar *setting,
const gchar **value);
gchar * wp_settings_get_string (WpSettings *self, const gchar *setting);
WP_API
gboolean wp_settings_get_int (WpSettings *self, const gchar *setting,
gint64 *val);
gint *value);
WP_API
gboolean wp_settings_get_float (WpSettings *self, const gchar *setting,
gfloat *val);
gfloat *value);
WP_API
WpSpaJson * wp_settings_get (WpSettings *self, const gchar *setting);
WP_API
gboolean wp_settings_apply_rule (WpSettings *self, const gchar *rule,

View File

@@ -739,11 +739,11 @@ wp_default_nodes_class_init (WpDefaultNodesClass * klass)
WP_PLUGIN_EXPORT gboolean
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
{
gint64 save_interval_ms = DEFAULT_SAVE_INTERVAL_MS;
gint save_interval_ms = DEFAULT_SAVE_INTERVAL_MS;
gboolean use_persistent_storage = DEFAULT_USE_PERSISTENT_STORAGE;
gboolean auto_echo_cancel = DEFAULT_AUTO_ECHO_CANCEL;
const gchar *echo_cancel_sink_name = DEFAULT_ECHO_CANCEL_SINK_NAME;
const gchar *echo_cancel_source_name = DEFAULT_ECHO_CANCEL_SOURCE_NAME;
g_autofree gchar *echo_cancel_sink_name = NULL;
g_autofree gchar *echo_cancel_source_name = NULL;
g_autoptr (WpSettings) settings = wp_settings_get_instance(core, NULL);
wp_settings_get_int (settings, "device.save-interval-ms",
@@ -752,19 +752,22 @@ wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
&use_persistent_storage);
wp_settings_get_boolean (settings, "device.auto-echo-cancel",
&auto_echo_cancel);
wp_settings_get_string (settings, "device.echo-cancel-sink-name",
&echo_cancel_sink_name);
wp_settings_get_string (settings, "device.echo-cancel-source-name",
&echo_cancel_source_name);
echo_cancel_sink_name = wp_settings_get_string (settings,
"device.echo-cancel-sink-name");
echo_cancel_source_name = wp_settings_get_string (settings,
"device.echo-cancel-source-name");
wp_plugin_register (g_object_new (wp_default_nodes_get_type (),
"name", NAME,
"core", core,
"save-interval-ms", save_interval_ms,
"save-interval-ms", save_interval_ms > 0 ?
(guint)save_interval_ms : DEFAULT_SAVE_INTERVAL_MS,
"use-persistent-storage", use_persistent_storage,
"auto-echo-cancel", auto_echo_cancel,
"echo-cancel-sink-name", echo_cancel_sink_name,
"echo-cancel-source-name", echo_cancel_source_name,
"echo-cancel-sink-name", echo_cancel_sink_name ?
echo_cancel_sink_name : DEFAULT_ECHO_CANCEL_SINK_NAME,
"echo-cancel-source-name", echo_cancel_source_name ?
echo_cancel_source_name : DEFAULT_ECHO_CANCEL_SOURCE_NAME,
NULL));
return TRUE;
}

View File

@@ -1472,8 +1472,8 @@ impl_module_new (lua_State *L)
}
}
static gboolean
get_boolean (lua_State *L)
static int
settings_get_boolean (lua_State *L)
{
const char *setting = luaL_checkstring (L, 1);
const char *m = NULL;
@@ -1483,21 +1483,19 @@ get_boolean (lua_State *L)
g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), m);
if (s)
{
if (s) {
gboolean value = 0;
if (wp_settings_get_boolean (s, setting, &value))
lua_pushboolean (L, value);
else
lua_pushnil (L);
}
else
} else
lua_pushnil (L);
return 1;
}
static gboolean
get_string (lua_State *L)
static int
settings_get_string (lua_State *L)
{
const char *setting = luaL_checkstring (L, 1);
const char *m = NULL;
@@ -1507,21 +1505,19 @@ get_string (lua_State *L)
g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), m);
if (s)
{
const gchar *value = NULL;
if (wp_settings_get_string (s, setting, &value))
if (s) {
g_autofree gchar *value = wp_settings_get_string (s, setting);
if (value)
lua_pushstring (L, value);
else
lua_pushnil (L);
}
else
} else
lua_pushnil (L);
return 1;
}
static gboolean
get_int (lua_State *L)
static int
settings_get_int (lua_State *L)
{
const char *setting = luaL_checkstring (L, 1);
const char *m = NULL;
@@ -1531,21 +1527,19 @@ get_int (lua_State *L)
g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), m);
if (s)
{
gint64 value = 0;
if (s) {
gint value = 0;
if (wp_settings_get_int (s, setting, &value))
lua_pushinteger (L, value);
else
lua_pushnil (L);
}
else
} else
lua_pushnil (L);
return 1;
}
static gboolean
get_float (lua_State *L)
static int
settings_get_float (lua_State *L)
{
const char *setting = luaL_checkstring (L, 1);
const char *m = NULL;
@@ -1555,21 +1549,41 @@ get_float (lua_State *L)
g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), m);
if (s)
{
if (s) {
gfloat value = 0;
if (wp_settings_get_float (s, setting, &value))
lua_pushnumber (L, value);
else
lua_pushnil (L);
}
else
} else
lua_pushnil (L);
return 1;
}
static gboolean
apply_rule (lua_State *L)
static int
settings_get (lua_State *L)
{
const char *setting = luaL_checkstring (L, 1);
const char *m = NULL;
if (lua_type (L, 2) == LUA_TSTRING)
m = luaL_checkstring (L, 2);
g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), m);
if (s) {
WpSpaJson *j = wp_settings_get (s, setting);
if (j)
wplua_pushboxed (L, WP_TYPE_SPA_JSON, j);
else
lua_pushnil (L);
} else
lua_pushnil (L);
return 1;
}
static int
settings_apply_rule (lua_State *L)
{
const char *r = luaL_checkstring (L, 1);
const char *m = NULL;
@@ -1581,8 +1595,7 @@ apply_rule (lua_State *L)
g_autoptr (WpSettings) s = wp_settings_get_instance (get_wp_core (L), m);
if (s)
{
if (s) {
gboolean value = wp_settings_apply_rule (s, r, cp, ap);
lua_pushboolean (L, value);
wplua_properties_to_table (L, ap);
@@ -1593,8 +1606,8 @@ apply_rule (lua_State *L)
return 1;
}
static gboolean
subscribe (lua_State *L)
static int
settings_subscribe (lua_State *L)
{
const gchar *pattern = luaL_checkstring (L, 1);
const gchar *m = NULL;
@@ -1614,8 +1627,8 @@ subscribe (lua_State *L)
}
static gboolean
unsubscribe (lua_State *L)
static int
settings_unsubscribe (lua_State *L)
{
guintptr sub_id = luaL_checkinteger (L, 1);
const gchar *m = NULL;
@@ -1632,13 +1645,14 @@ unsubscribe (lua_State *L)
}
static const luaL_Reg settings_methods[] = {
{ "get_boolean", get_boolean },
{ "get_string", get_string },
{ "get_int", get_int },
{ "get_float", get_float },
{ "apply_rule", apply_rule },
{ "subscribe", subscribe },
{ "unsubscribe", unsubscribe },
{ "get_boolean", settings_get_boolean },
{ "get_string", settings_get_string },
{ "get_int", settings_get_int },
{ "get_float", settings_get_float },
{ "get", settings_get },
{ "apply_rule", settings_apply_rule },
{ "subscribe", settings_subscribe },
{ "unsubscribe", settings_unsubscribe },
{ NULL, NULL }
};

View File

@@ -167,7 +167,7 @@ do_parse_settings (void *data, const char *location,
}
j = g_value_get_boxed (&item);
value = wp_spa_json_parse_string (j);
value = wp_spa_json_to_string (j);
len = wp_spa_json_get_size (j);
g_value_unset (&item);

View File

@@ -94,7 +94,7 @@ do_parse_settings (void *data, const char *location,
wp_iterator_next (iter, &item);
j = g_value_get_boxed (&item);
value = wp_spa_json_parse_string (j);
value = wp_spa_json_to_string (j);
g_value_unset (&item);
if (name && value) {
@@ -124,7 +124,7 @@ test_parsing_setup (TestSettingsFixture *self, gconstpointer user_data)
self->settings = g_steal_pointer (&settings);
/* total no.of settings in the conf file */
g_assert_cmpint (data.count, ==, 15);
g_assert_cmpint (data.count, ==, 12);
}
}
@@ -141,7 +141,7 @@ static void
test_parsing (TestSettingsFixture *self, gconstpointer data)
{
/* total no.of settings in the conf file */
g_assert_cmpint (wp_properties_get_count(self->settings), ==, 15);
g_assert_cmpint (wp_properties_get_count(self->settings), ==, 12);
}
static void
@@ -274,7 +274,7 @@ test_wpsettings (TestSettingsFixture *self, gconstpointer data)
}
{
gint64 value = 0;
gint value = 0;
/* _get_int () */
g_assert_false (wp_settings_get_int (s, "test-setting-undefined",
@@ -282,83 +282,43 @@ test_wpsettings (TestSettingsFixture *self, gconstpointer data)
g_assert_true (wp_settings_get_int (s, "test-setting3-int", &value));
g_assert_cmpint (value, ==, -20);
g_assert_true (wp_settings_get_int (s, "test-setting4-max-int", &value));
g_assert_cmpint (value, ==, G_MAXINT64);
g_assert_true (wp_settings_get_int (s, "test-setting4-min-int", &value));
g_assert_cmpint (value, ==, G_MININT64);
value = 0;
g_assert_true (wp_settings_get_int (s, "test-setting4-max-int-one-more",
&value));
g_assert_cmpint (value, ==, 0);
g_assert_true (wp_settings_get_int (s, "test-setting4-min-int-one-less",
&value));
g_assert_cmpint (value, ==, 0);
}
{
const gchar *value = NULL;
/* _get_string () */
g_assert_false (wp_settings_get_string (s, "test-setting-undefined",
&value));
{
g_autofree gchar *value = NULL;
value = wp_settings_get_string (s, "test-setting-undefined");
g_assert_null (value);
}
g_assert_true (wp_settings_get_string (s, "test-setting4-string",
&value));
{
g_autofree gchar *value = NULL;
value = wp_settings_get_string (s, "test-setting4-string");
g_assert_nonnull (value);
g_assert_cmpstr (value, ==, "blahblah");
}
g_assert_true (wp_settings_get_string (s, "test-setting2",
&value));
{
g_autofree gchar *value = NULL;
value = wp_settings_get_string (s, "test-setting2");
g_assert_nonnull (value);
g_assert_cmpstr (value, ==, "true");
}
g_assert_true (wp_settings_get_string (s, "test-setting3-int",
&value));
{
g_autofree gchar *value = NULL;
value = wp_settings_get_string (s, "test-setting3-int");
g_assert_nonnull (value);
g_assert_cmpstr (value, ==, "-20");
g_assert_true (wp_settings_get_string (s, "test-setting-json",
&value));
g_assert_cmpstr (value, ==, "[ a b c ]");
g_assert_true (wp_settings_get_string (s, "test-setting-strings",
&value));
g_assert_cmpstr (value, ==, "[\"test1\", \"test 2\", \"test three\", \"test-four\"]");
}
{
g_autofree gchar *s1 = NULL;
g_autofree gchar *s2 = NULL;
g_autofree gchar *s3 = NULL;
g_autofree gchar *s4 = NULL;
g_autoptr (WpSpaJson) json = wp_spa_json_new_from_string (value);
wp_spa_json_parse_array
(json, "s", &s1, "s", &s2, "s", &s3, "s", &s4, NULL);
g_assert_cmpstr (s1, ==, "test1");
g_assert_cmpstr (s2, ==, "test 2");
g_assert_cmpstr (s3, ==, "test three");
g_assert_cmpstr (s4, ==, "test-four");
g_autofree gchar *value = NULL;
value = wp_settings_get_string (s, "test-setting5-string-with-quotes");
g_assert_nonnull (value);
g_assert_cmpstr (value, ==, "a string with \"quotes\"");
}
{
gchar *sample_str[] = {
"test1",
"test 2",
"test three",
"test-four"
};
g_autoptr (WpSpaJson) json = wp_spa_json_new_from_string (value);
g_autoptr (WpIterator) it = wp_spa_json_new_iterator (json);
g_auto (GValue) item = G_VALUE_INIT;
for (int i = 0; wp_iterator_next (it, &item);
g_value_unset (&item), i++) {
WpSpaJson *s = g_value_get_boxed (&item);
g_autofree gchar *str = wp_spa_json_parse_string (s);
g_assert_cmpstr (str, ==, sample_str[i]);
}
}
}
{
@@ -391,6 +351,56 @@ test_wpsettings (TestSettingsFixture *self, gconstpointer data)
}
{
/* _get_json () */
{
g_autoptr (WpSpaJson) value = NULL;
value = wp_settings_get (s, "test-setting-json");
g_assert_nonnull (value);
g_assert_true (wp_spa_json_is_array (value));
g_assert_cmpstr (wp_spa_json_get_data (value), ==, "[1, 2, 3]");
}
{
g_autoptr (WpSpaJson) value = NULL;
value = wp_settings_get (s, "test-setting-json2");
g_assert_nonnull (value);
g_assert_true (wp_spa_json_is_array (value));
{
g_autofree gchar *s1 = NULL;
g_autofree gchar *s2 = NULL;
g_autofree gchar *s3 = NULL;
g_autofree gchar *s4 = NULL;
wp_spa_json_parse_array
(value, "s", &s1, "s", &s2, "s", &s3, "s", &s4, NULL);
g_assert_cmpstr (s1, ==, "test1");
g_assert_cmpstr (s2, ==, "test 2");
g_assert_cmpstr (s3, ==, "test three");
g_assert_cmpstr (s4, ==, "test-four");
}
{
gchar *sample_str[] = {
"test1",
"test 2",
"test three",
"test-four"
};
g_autoptr (WpIterator) it = wp_spa_json_new_iterator (value);
g_auto (GValue) item = G_VALUE_INIT;
for (int i = 0; wp_iterator_next (it, &item);
g_value_unset (&item), i++) {
WpSpaJson *s = g_value_get_boxed (&item);
g_autofree gchar *str = wp_spa_json_parse_string (s);
g_assert_cmpstr (str, ==, sample_str[i]);
}
}
}
}
{
g_autoptr (WpSettings) s4 =
wp_settings_get_instance (self->base.core, NULL);
@@ -579,18 +589,14 @@ void wp_settings_changed_callback (WpSettings *obj, const gchar *setting,
wp_settings_get_boolean (self->s, setting, &value);
g_assert_cmpint (value, ==, spa_atob (self->triggered_setting_value));
g_assert_cmpstr (raw_value, ==, self->triggered_setting_value);
}else if (self->setting_type == INTEGER) {
gint64 value = 0;
} else if (self->setting_type == INTEGER) {
gint value = 0;
wp_settings_get_int (self->s, setting, &value);
gint64 svalue = 0;
spa_atoi64 (self->triggered_setting_value, &svalue, 0);
g_assert_cmpint (value, ==, svalue);
g_assert_cmpint (value, ==, atoi (self->triggered_setting_value));
g_assert_cmpstr (raw_value, ==, self->triggered_setting_value);
} else if (self->setting_type == STRING) {
const gchar *value = NULL;
wp_settings_get_string (self->s, setting, &value);
g_autofree gchar *value = wp_settings_get_string (self->s, setting);
g_assert_nonnull (value);
g_assert_cmpstr (value, ==, self->triggered_setting_value);
g_assert_cmpstr (raw_value, ==, self->triggered_setting_value);
}

View File

@@ -64,14 +64,11 @@ context.modules = [
]
wireplumber.settings = {
test-setting1 = "false"
test-setting2 = "true"
test-setting3-int = "-20"
test-setting4-max-int = "9223372036854775807"
test-setting4-max-int-one-more = "9223372036854775808"
test-setting4-min-int = -9223372036854775808
test-setting4-min-int-one-less = -9223372036854775809
test-setting1 = false
test-setting2 = true
test-setting3-int = -20
test-setting4-string = "blahblah"
test-setting5-string-with-quotes = "a string with \"quotes\""
rule_one = [
{
matches = [
@@ -129,8 +126,8 @@ wireplumber.settings = {
}
}
]
test-setting-float1 = "3.14"
test-setting-float2 = "0.4"
test-setting-float1 = 3.14
test-setting-float2 = 0.4
rule_three = [
{
matches = [
@@ -144,7 +141,7 @@ wireplumber.settings = {
]
actions = {
update-props = {
prop.electrical.conductivity = "true"
prop.electrical.conductivity = true
prop.state = "solid"
prop.example = "ferrous"
}
@@ -160,13 +157,13 @@ wireplumber.settings = {
]
actions = {
update-props = {
prop.electrical.conductivity = "false"
prop.electrical.conductivity = false
prop.example = "neon"
prop.state = "gas"
}
}
}
]
test-setting-json = "[ a b c ]"
test-setting-strings = ["test1", "test 2", "test three", "test-four"]
test-setting-json = [1, 2, 3]
test-setting-json2 = ["test1", "test 2", "test three", "test-four"]
}

View File

@@ -29,20 +29,6 @@ value = Settings.get_int ("test-setting3-int", "test-settings")
assert ("number" == type (value))
assert (value == -20)
value = Settings.get_int ("test-setting4-max-int", "test-settings")
assert (value == 9223372036854775807)
value = Settings.get_int ("test-setting4-min-int", "test-settings")
assert (value == -9223372036854775808)
value = Settings.get_int ("test-setting4-max-int-one-more",
"test-settings")
assert (value == 0)
value = Settings.get_int ("test-setting4-min-int-one-less",
"test-settings")
assert (value == 0)
-- test settings _get_string ()
value = Settings.get_string ("test-setting-undefined", "test-settings")
assert (value == nil)
@@ -54,23 +40,6 @@ assert (value == "blahblah")
value = Settings.get_string ("test-setting3-int", "test-settings")
assert (value == "-20")
value = Settings.get_string ("test-setting-json", "test-settings")
assert (value == "[ a b c ]")
value = Settings.get_string ("test-setting-strings", "test-settings")
assert (value == "[\"test1\", \"test 2\", \"test three\", \"test-four\"]")
json = Json.Raw (value)
assert (json:is_array())
val = json:parse ()
assert (val[1] == "test1")
assert (val[2] == "test 2")
assert (val[3] == "test three")
assert (val[4] == "test-four")
assert (val[5] == nil)
assert (#val == 4)
assert (json:get_data() ==
"[\"test1\", \"test 2\", \"test three\", \"test-four\"]")
-- test settings _get_float ()
value = Settings.get_float ("test-setting-undefined", "test-settings")
assert (value == nil)
@@ -82,6 +51,24 @@ assert ((value - 3.14) < 0.00001)
value = Settings.get_float ("test-setting-float2", "test-settings")
assert ((value - 0.4) < 0.00001)
-- test settings _get ()
value = Settings.get ("test-setting-json", "test-settings")
assert (value ~= nil)
assert (value:is_array())
assert (value:get_data() == "[1, 2, 3]")
value = Settings.get ("test-setting-json2", "test-settings")
assert (value ~= nil)
assert (value:is_array())
assert (value:get_data() ==
"[\"test1\", \"test 2\", \"test three\", \"test-four\"]")
val = value:parse ()
assert (val[1] == "test1")
assert (val[2] == "test 2")
assert (val[3] == "test three")
assert (val[4] == "test-four")
assert (val[5] == nil)
assert (#val == 4)
-- test rules
-- test #1