add transform_object_properties in jerryx/arg (#1879)

Add a function in jerryx/arg.
jerryx_arg_transform_object_properties, it will validate the properties of a JS object, and convert those properties into native type.

JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang zidong.jiang@intel.com
This commit is contained in:
Zidong Jiang
2017-06-19 19:51:08 -05:00
committed by GitHub
parent 7cc9d65c09
commit e4eecc2019
6 changed files with 424 additions and 15 deletions
+160 -10
View File
@@ -31,6 +31,30 @@ typedef struct
- [jerryx_arg_function](#jerryx_arg_function) - [jerryx_arg_function](#jerryx_arg_function)
- [jerryx_arg_native_pointer](#jerryx_arg_native_pointer) - [jerryx_arg_native_pointer](#jerryx_arg_native_pointer)
- [jerryx_arg_ignore](#jerryx_arg_ignore) - [jerryx_arg_ignore](#jerryx_arg_ignore)
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_object_props_t
**Summary**
The structure is used in `jerryx_arg_object_properties`. It provides the properties' names,
its corresponding JS-to-C mapping and other related information.
**Prototype**
```c
typedef struct
{
const jerry_char_t **name_p; /**< property name list of the JS object */
jerry_length_t name_cnt; /**< count of the name list */
const jerryx_arg_t *c_arg_p; /**< points to the array of transformation steps */
jerry_length_t c_arg_cnt; /**< the count of the `c_arg_p` array */
} jerryx_arg_object_props_t;
```
**See also**
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_transform_func_t ## jerryx_arg_transform_func_t
@@ -128,7 +152,7 @@ jerryx_arg_transform_this_and_args (const jerry_value_t this_val,
**Example** **Example**
```c ```c
// JS signature: function (requiredBool, requiredString, optionalNumber) /* JS signature: function (requiredBool, requiredString, optionalNumber) */
static jerry_value_t my_external_handler (const jerry_value_t function_obj, static jerry_value_t my_external_handler (const jerry_value_t function_obj,
const jerry_value_t this_val, const jerry_value_t this_val,
const jerry_value_t args_p[], const jerry_value_t args_p[],
@@ -138,10 +162,10 @@ static jerry_value_t my_external_handler (const jerry_value_t function_obj,
char required_str[16]; char required_str[16];
double optional_num = 1234.567; // default value double optional_num = 1234.567; // default value
// "mapping" defines the steps to transform input arguments to C variables: /* "mapping" defines the steps to transform input arguments to C variables. */
const jerryx_arg_t mapping[] = const jerryx_arg_t mapping[] =
{ {
// `this` is the first value. No checking needed on `this` for this function. /* `this` is the first value. No checking needed on `this` for this function. */
jerryx_arg_ignore (), jerryx_arg_ignore (),
jerryx_arg_boolean (&required_bool, JERRYX_ARG_NO_COERCE, JERRYX_ARG_REQUIRED), jerryx_arg_boolean (&required_bool, JERRYX_ARG_NO_COERCE, JERRYX_ARG_REQUIRED),
@@ -149,22 +173,24 @@ static jerry_value_t my_external_handler (const jerry_value_t function_obj,
jerryx_arg_number (&optional_num, JERRYX_ARG_NO_COERCE, JERRYX_ARG_OPTIONAL), jerryx_arg_number (&optional_num, JERRYX_ARG_NO_COERCE, JERRYX_ARG_OPTIONAL),
}; };
// Validate and transform: /* Validate and transform. */
const jerry_value_t rv = jerryx_arg_transform_this_and_args (this_val, const jerry_value_t rv = jerryx_arg_transform_this_and_args (this_val,
args_p, args_p,
args_count, args_count,
mapping, mapping,
ARRAY_LENGTH (mapping)); 4);
if (jerry_value_has_error_flag (rv)) if (jerry_value_has_error_flag (rv))
{ {
// Handle error /* Handle error. */
return rv; return rv;
} }
// Validated and tranformed successfully! /*
// required_bool, required_str and optional_num can now be used. * Validated and transformed successfully!
// ... * required_bool, required_str and optional_num can now be used.
*/
...
} }
``` ```
@@ -177,6 +203,7 @@ static jerry_value_t my_external_handler (const jerry_value_t function_obj,
- [jerryx_arg_function](#jerryx_arg_function) - [jerryx_arg_function](#jerryx_arg_function)
- [jerryx_arg_native_pointer](#jerryx_arg_native_pointer) - [jerryx_arg_native_pointer](#jerryx_arg_native_pointer)
- [jerryx_arg_custom](#jerryx_arg_custom) - [jerryx_arg_custom](#jerryx_arg_custom)
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
## jerryx_arg_transform_args ## jerryx_arg_transform_args
@@ -206,6 +233,41 @@ jerryx_arg_transform_args (const jerry_value_t *js_arg_p,
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args) - [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_transform_object_properties
**Summary**
Validate the properties of a JS object and assign them to the native arguments.
*Note*: This function transforms properties of a single JS object into native C values.
To transform multiple objects in one pass (for example when converting multiple arguments
to an external handler), please use `jerryx_arg_object_properties` together with
`jerryx_arg_transform_this_and_args` or `jerryx_arg_transform_args`.
**Prototype**
```c
jerry_value_t
jerryx_arg_transform_object_properties (const jerry_value_t obj_val,
const jerry_char_t **name_p,
const jerry_length_t name_cnt,
const jerryx_arg_t *c_arg_p,
jerry_length_t c_arg_cnt);
```
- `obj_val` - the JS object.
- `name_p` - points to the array of property names.
- `name_cnt` - the count of the `name_p` array.
- `c_arg_p` - points to the array of validation/transformation steps
- `c_arg_cnt` - the count of the `c_arg_p` array.
- return value - a `jerry_value_t` representing `undefined` if all validators passed or an `Error` if a validator failed.
**See also**
- [jerryx_arg_object_properties](#jerryx_arg_object_properties)
# Helpers for commonly used validations # Helpers for commonly used validations
## jerryx_arg_number ## jerryx_arg_number
@@ -314,7 +376,7 @@ jerryx_arg_function (jerry_value_t *dest,
**Summary** **Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `Object` JS argument that is 'backed' with a native pointer with consume one `object` JS argument that is 'backed' with a native pointer with
a given type info. In case the native pointer info matches, the transform a given type info. In case the native pointer info matches, the transform
will succeed and the object's native pointer will be assigned to `*dest`. will succeed and the object's native pointer will be assigned to `*dest`.
@@ -335,6 +397,94 @@ jerryx_arg_native_pointer (void **dest,
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args) - [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
## jerryx_arg_object_properties
**Summary**
Create a validation/transformation step (`jerryx_arg_t`) that expects to
consume one `object` JS argument and call `jerryx_arg_transform_object_properties` inside
to transform its properties to native arguments.
User should prepare the `jerryx_arg_object_props_t` instance, and pass it to this function.
**Prototype**
```c
static inline jerryx_arg_t
jerryx_arg_object_properties (const jerryx_arg_object_props_t *object_props_p,
jerryx_arg_optional_t opt_flag);
```
- return value - the created `jerryx_arg_t` instance.
- `object_props_p` - provides information for properties transform.
- `opt_flag` - whether the argument is optional.
**Example**
```c
/**
* The binding function expects args_p[0] is an object, which has 3 properties:
* "enable": boolean
* "data": number
* "extra_data": number, optional
*/
static jerry_value_t my_external_handler (const jerry_value_t function_obj,
const jerry_value_t this_val,
const jerry_value_t args_p[],
const jerry_length_t args_count)
{
bool required_bool;
double required_num;
double optional_num = 1234.567; // default value
/* "prop_name_p" defines the name list of the expected properties' names. */
const char *prop_name_p[] = { "enable", "data", "extra_data" };
/* "prop_mapping" defines the steps to transform properties to C variables. */
const jerryx_arg_t prop_mapping[] =
jerryx_arg_boolean (&required_bool, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&required_num, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&optional_num, JERRYX_ARG_COERCE, JERRYX_ARG_OPTIONAL)
};
/* Prepare the jerryx_arg_object_props_t instance. */
const jerryx_arg_object_props_t prop_info =
{
.name_p = (const jerry_char_t **) prop_name_p,
.name_cnt = 3,
.c_arg_p = prop_mapping,
.c_arg_cnt = 3
};
/* It is the mapping used in the jerryx_arg_transform_args. */
const jerryx_arg_t mapping[] =
{
jerryx_arg_object_properties (&prop_info, JERRYX_ARG_REQUIRED)
};
/* Validate and transform. */
const jerry_value_t rv = jerryx_arg_transform_args (args_p,
args_count,
mapping,
1);
if (jerry_value_has_error_flag (rv))
{
/* Handle error. */
return rv;
}
/*
* Validated and transformed successfully!
* required_bool, required_num and optional_num can now be used.
*/
...
}
```
**See also**
- [jerryx_arg_transform_this_and_args](#jerryx_arg_transform_this_and_args)
- [jerryx_arg_transform_object_properties](#jerryx_arg_transform_object_properties)
# Functions to create custom validations # Functions to create custom validations
+24 -2
View File
@@ -63,7 +63,7 @@ jerryx_arg_transform_number_strict (jerryx_arg_js_iterator_t *js_arg_iter_p, /**
} /* jerryx_arg_transform_number_strict */ } /* jerryx_arg_transform_number_strict */
/** /**
* Tranform a JS argument to a double. Type coercion is allowed. * Transform a JS argument to a double. Type coercion is allowed.
* *
* @return jerry undefined: the transformer passes, * @return jerry undefined: the transformer passes,
* jerry error: the transformer fails. * jerry error: the transformer fails.
@@ -251,7 +251,7 @@ jerryx_arg_transform_native_pointer (jerryx_arg_js_iterator_t *js_arg_iter_p, /*
if (!jerry_value_is_object (js_arg)) if (!jerry_value_is_object (js_arg))
{ {
return jerry_create_error (JERRY_ERROR_TYPE, return jerry_create_error (JERRY_ERROR_TYPE,
(jerry_char_t *) "It is not a object."); (jerry_char_t *) "It is not an object.");
} }
const jerry_object_native_info_t *expected_info_p; const jerry_object_native_info_t *expected_info_p;
@@ -269,6 +269,27 @@ jerryx_arg_transform_native_pointer (jerryx_arg_js_iterator_t *js_arg_iter_p, /*
return jerry_create_undefined (); return jerry_create_undefined ();
} /* jerryx_arg_transform_native_pointer */ } /* jerryx_arg_transform_native_pointer */
/**
* Check whether the JS object's properties have expected types, and transform them into native args.
*
* @return jerry undefined: the transformer passes,
* jerry error: the transformer fails.
*/
jerry_value_t
jerryx_arg_transform_object_props (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
const jerryx_arg_t *c_arg_p) /**< the native arg */
{
jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
const jerryx_arg_object_props_t *object_props = (const jerryx_arg_object_props_t *) c_arg_p->extra_info;
return jerryx_arg_transform_object_properties (js_arg,
object_props->name_p,
object_props->name_cnt,
object_props->c_arg_p,
object_props->c_arg_cnt);
} /* jerryx_arg_transform_object_props */
/** /**
* Define transformer for optional argument. * Define transformer for optional argument.
*/ */
@@ -288,6 +309,7 @@ JERRYX_ARG_TRANSFORM_OPTIONAL (string)
JERRYX_ARG_TRANSFORM_OPTIONAL (string_strict) JERRYX_ARG_TRANSFORM_OPTIONAL (string_strict)
JERRYX_ARG_TRANSFORM_OPTIONAL (function) JERRYX_ARG_TRANSFORM_OPTIONAL (function)
JERRYX_ARG_TRANSFORM_OPTIONAL (native_pointer) JERRYX_ARG_TRANSFORM_OPTIONAL (native_pointer)
JERRYX_ARG_TRANSFORM_OPTIONAL (object_props)
/** /**
* Ignore the JS argument. * Ignore the JS argument.
+49 -1
View File
@@ -81,8 +81,56 @@ jerryx_arg_transform_this_and_args (const jerry_value_t this_val, /**< the this_
{ {
jerry_release_value (ret); jerry_release_value (ret);
return jerry_create_error (JERRY_ERROR_TYPE, (jerry_char_t *) "'this' validation failed"); return jerry_create_error (JERRY_ERROR_TYPE, (jerry_char_t *) "'this' validation failed.");
} }
return jerryx_arg_transform_args (js_arg_p, js_arg_cnt, c_arg_p + 1, c_arg_cnt - 1); return jerryx_arg_transform_args (js_arg_p, js_arg_cnt, c_arg_p + 1, c_arg_cnt - 1);
} /* jerryx_arg_transform_this_and_args */ } /* jerryx_arg_transform_this_and_args */
/**
* Validate the `obj_val`'s properties,
* and assign them to the native arguments.
*
* @return jerry undefined: all validators passed,
* jerry error: a validator failed.
*/
jerry_value_t
jerryx_arg_transform_object_properties (const jerry_value_t obj_val,/**< the JS object */
const jerry_char_t **name_p, /**< property name list of the JS object */
const jerry_length_t name_cnt, /**< count of the name list */
const jerryx_arg_t *c_arg_p, /**< points to the array of transformation steps */
jerry_length_t c_arg_cnt) /**< the count of the `c_arg_p` array */
{
if (!jerry_value_is_object (obj_val))
{
return jerry_create_error (JERRY_ERROR_TYPE, (jerry_char_t *) "Not an object.");
}
jerry_value_t prop[name_cnt];
for (jerry_length_t i = 0; i < name_cnt; i++, name_p++)
{
const jerry_value_t name_str = jerry_create_string (*name_p);
prop[i] = jerry_get_property (obj_val, name_str);
jerry_release_value (name_str);
if (jerry_value_has_error_flag (prop[i]))
{
for (jerry_length_t j = 0; j < i; j++)
{
jerry_release_value (prop[j]);
}
return prop[i];
}
}
const jerry_value_t ret = jerryx_arg_transform_args (prop, name_cnt, c_arg_p, c_arg_cnt);
for (jerry_length_t i = 0; i < name_cnt; i++)
{
jerry_release_value (prop[i]);
}
return ret;
} /* jerryx_arg_transform_object_properties */
+19 -1
View File
@@ -16,7 +16,6 @@
#ifndef JERRYX_ARG_H #ifndef JERRYX_ARG_H
#define JERRYX_ARG_H #define JERRYX_ARG_H
#include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@@ -43,6 +42,17 @@ typedef struct jerryx_arg_js_iterator_t jerryx_arg_js_iterator_t;
typedef jerry_value_t (*jerryx_arg_transform_func_t) (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */ typedef jerry_value_t (*jerryx_arg_transform_func_t) (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
const jerryx_arg_t *c_arg_p); /**< native arg */ const jerryx_arg_t *c_arg_p); /**< native arg */
/**
* The structure used in jerryx_arg_object_properties
*/
typedef struct
{
const jerry_char_t **name_p; /**< property name list of the JS object */
jerry_length_t name_cnt; /**< count of the name list */
const jerryx_arg_t *c_arg_p; /**< points to the array of transformation steps */
jerry_length_t c_arg_cnt; /**< the count of the `c_arg_p` array */
} jerryx_arg_object_props_t;
/** /**
* The structure defining a single validation & transformation step. * The structure defining a single validation & transformation step.
*/ */
@@ -64,6 +74,12 @@ jerry_value_t jerryx_arg_transform_args (const jerry_value_t *js_arg_p,
const jerryx_arg_t *c_arg_p, const jerryx_arg_t *c_arg_p,
jerry_length_t c_arg_cnt); jerry_length_t c_arg_cnt);
jerry_value_t jerryx_arg_transform_object_properties (const jerry_value_t obj_val,
const jerry_char_t **name_p,
const jerry_length_t name_cnt,
const jerryx_arg_t *c_arg_p,
jerry_length_t c_arg_cnt);
/** /**
* Indicates whether an argument is allowed to be coerced into the expected JS type. * Indicates whether an argument is allowed to be coerced into the expected JS type.
*/ */
@@ -105,6 +121,8 @@ static inline jerryx_arg_t
jerryx_arg_ignore (void); jerryx_arg_ignore (void);
static inline jerryx_arg_t static inline jerryx_arg_t
jerryx_arg_custom (void *dest, uintptr_t extra_info, jerryx_arg_transform_func_t func); jerryx_arg_custom (void *dest, uintptr_t extra_info, jerryx_arg_transform_func_t func);
static inline jerryx_arg_t
jerryx_arg_object_properties (const jerryx_arg_object_props_t *object_props_p, jerryx_arg_optional_t opt_flag);
jerry_value_t jerry_value_t
jerryx_arg_transform_optional (jerryx_arg_js_iterator_t *js_arg_iter_p, jerryx_arg_transform_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
+33 -1
View File
@@ -51,6 +51,10 @@ jerry_value_t jerryx_arg_transform_native_pointer_optional (jerryx_arg_js_iterat
const jerryx_arg_t *c_arg_p); const jerryx_arg_t *c_arg_p);
jerry_value_t jerryx_arg_transform_ignore (jerryx_arg_js_iterator_t *js_arg_iter_p, jerry_value_t jerryx_arg_transform_ignore (jerryx_arg_js_iterator_t *js_arg_iter_p,
const jerryx_arg_t *c_arg_p); const jerryx_arg_t *c_arg_p);
jerry_value_t jerryx_arg_transform_object_props (jerryx_arg_js_iterator_t *js_arg_iter_p,
const jerryx_arg_t *c_arg_p);
jerry_value_t jerryx_arg_transform_object_props_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
const jerryx_arg_t *c_arg_p);
/** /**
* Create a validation/transformation step (`jerryx_arg_t`) that expects to * Create a validation/transformation step (`jerryx_arg_t`) that expects to
@@ -213,7 +217,7 @@ jerryx_arg_function (jerry_value_t *dest, /**< pointer to the jerry_value_t wher
/** /**
* Create a validation/transformation step (`jerryx_arg_t`) that expects to * Create a validation/transformation step (`jerryx_arg_t`) that expects to
* consume one `Object` JS argument that is 'backed' with a native pointer with * consume one `object` JS argument that is 'backed' with a native pointer with
* a given type info. In case the native pointer info matches, the transform * a given type info. In case the native pointer info matches, the transform
* will succeed and the object's native pointer will be assigned to *dest. * will succeed and the object's native pointer will be assigned to *dest.
* *
@@ -275,4 +279,32 @@ jerryx_arg_custom (void *dest, /**< pointer to the native argument where the res
}; };
} /* jerryx_arg_custom */ } /* jerryx_arg_custom */
/**
* Create a jerryx_arg_t instance for object properties.
*
* @return a jerryx_arg_t instance.
*/
static inline jerryx_arg_t
jerryx_arg_object_properties (const jerryx_arg_object_props_t *object_props, /**< pointer to object property mapping */
jerryx_arg_optional_t opt_flag) /**< whether the argument is optional */
{
jerryx_arg_transform_func_t func;
if (opt_flag == JERRYX_ARG_OPTIONAL)
{
func = jerryx_arg_transform_object_props_optional;
}
else
{
func = jerryx_arg_transform_object_props;
}
return (jerryx_arg_t)
{
.func = func,
.dest = NULL,
.extra_info = (uintptr_t) object_props
};
} /* jerryx_arg_object_properties */
#endif /* !JERRYX_ARG_IMPL_H */ #endif /* !JERRYX_ARG_IMPL_H */
+139
View File
@@ -22,6 +22,7 @@
#include "test-common.h" #include "test-common.h"
#include <string.h> #include <string.h>
#include <jerryscript-ext/arg.h>
const char *test_source = ( const char *test_source = (
"var arg1 = true;" "var arg1 = true;"
@@ -40,6 +41,15 @@ const char *test_source = (
"test_validator2.call(obj_a, 5);" "test_validator2.call(obj_a, 5);"
"test_validator2.call(obj_b, 5);" "test_validator2.call(obj_b, 5);"
"test_validator2.call(obj_a, 1);" "test_validator2.call(obj_a, 1);"
"var obj1 = {prop1:true, prop2:'1.5'};"
"test_validator_prop1(obj1);"
"test_validator_prop2(obj1);"
"test_validator_prop2();"
"var obj2 = {prop1:true};"
"Object.defineProperty(obj2, 'prop2', {"
" get: function() { throw new TypeError('prop2 error') }"
"});"
"test_validator_prop3(obj2);"
); );
static const jerry_object_native_info_t thing_a_info = static const jerry_object_native_info_t thing_a_info =
@@ -68,6 +78,8 @@ static my_type_b_t my_thing_b;
static int validator1_count = 0; static int validator1_count = 0;
static int validator2_count = 0; static int validator2_count = 0;
static int validator_prop_count = 0;
/** /**
* The handler should have following arguments: * The handler should have following arguments:
* this: Ignore. * this: Ignore.
@@ -211,6 +223,129 @@ test_validator2_handler (const jerry_value_t func_obj_val __attribute__((unused)
return jerry_create_undefined (); return jerry_create_undefined ();
} /* test_validator2_handler */ } /* test_validator2_handler */
/**
* Calling jerryx_arg_transform_object_properties directly.
*/
static jerry_value_t
test_validator_prop1_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */
const jerry_value_t this_val __attribute__((unused)), /**< this value */
const jerry_value_t args_p[], /**< arguments list */
const jerry_length_t args_cnt __attribute__((unused))) /**< arguments length */
{
bool native1 = false;
double native2 = 0;
double native3 = 3;
const char *name_p[] = {"prop1", "prop2", "prop3"};
jerryx_arg_t mapping[] =
{
jerryx_arg_boolean (&native1, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&native2, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&native3, JERRYX_ARG_COERCE, JERRYX_ARG_OPTIONAL)
};
jerry_value_t is_ok = jerryx_arg_transform_object_properties (args_p[0],
(const jerry_char_t **) name_p,
3,
mapping,
3);
TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
TEST_ASSERT (native1);
TEST_ASSERT (native2 == 1.5);
TEST_ASSERT (native3 == 3);
validator_prop_count ++;
return jerry_create_undefined ();
} /* test_validator_prop1_handler */
/**
* Calling jerryx_arg_transform_object_properties indirectly by
* using jerryx_arg_object_properties.
*/
static jerry_value_t
test_validator_prop2_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */
const jerry_value_t this_val __attribute__((unused)), /**< this value */
const jerry_value_t args_p[], /**< arguments list */
const jerry_length_t args_cnt __attribute__((unused))) /**< arguments length */
{
bool native1 = false;
double native2 = 0;
double native3 = 3;
jerryx_arg_object_props_t prop_info;
const char *name_p[] = { "prop1", "prop2", "prop3" };
jerryx_arg_t prop_mapping[] =
{
jerryx_arg_boolean (&native1, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&native2, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_number (&native3, JERRYX_ARG_COERCE, JERRYX_ARG_OPTIONAL)
};
prop_info.name_p = (const jerry_char_t **) name_p;
prop_info.name_cnt = 3;
prop_info.c_arg_p = prop_mapping;
prop_info.c_arg_cnt = 3;
jerryx_arg_t mapping[] =
{
jerryx_arg_object_properties (&prop_info, JERRYX_ARG_OPTIONAL),
};
jerry_value_t is_ok = jerryx_arg_transform_args (args_p, 1, mapping, 1);
TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
if (validator_prop_count == 1)
{
TEST_ASSERT (native1);
TEST_ASSERT (native2 == 1.5);
TEST_ASSERT (native3 == 3);
}
validator_prop_count ++;
return jerry_create_undefined ();
} /* test_validator_prop2_handler */
static jerry_value_t
test_validator_prop3_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */
const jerry_value_t this_val __attribute__((unused)), /**< this value */
const jerry_value_t args_p[], /**< arguments list */
const jerry_length_t args_cnt __attribute__((unused))) /**< arguments length */
{
bool native1 = false;
bool native2 = true;
const char *name_p[] = { "prop1", "prop2" };
jerryx_arg_t mapping[] =
{
jerryx_arg_boolean (&native1, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
jerryx_arg_boolean (&native2, JERRYX_ARG_COERCE, JERRYX_ARG_REQUIRED),
};
jerry_value_t is_ok = jerryx_arg_transform_object_properties (args_p[0],
(const jerry_char_t **) name_p,
2,
mapping,
2);
TEST_ASSERT (jerry_value_has_error_flag (is_ok));
TEST_ASSERT (!native1);
TEST_ASSERT (native2);
validator_prop_count ++;
jerry_release_value (is_ok);
return jerry_create_undefined ();
} /* test_validator_prop3_handler */
static jerry_value_t static jerry_value_t
create_object_a_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */ create_object_a_handler (const jerry_value_t func_obj_val __attribute__((unused)), /**< function object */
const jerry_value_t this_val, /**< this value */ const jerry_value_t this_val, /**< this value */
@@ -272,6 +407,9 @@ main (void)
register_js_function ("test_validator2", test_validator2_handler); register_js_function ("test_validator2", test_validator2_handler);
register_js_function ("MyObjectA", create_object_a_handler); register_js_function ("MyObjectA", create_object_a_handler);
register_js_function ("MyObjectB", create_object_b_handler); register_js_function ("MyObjectB", create_object_b_handler);
register_js_function ("test_validator_prop1", test_validator_prop1_handler);
register_js_function ("test_validator_prop2", test_validator_prop2_handler);
register_js_function ("test_validator_prop3", test_validator_prop3_handler);
jerry_value_t parsed_code_val = jerry_parse ((jerry_char_t *) test_source, strlen (test_source), false); jerry_value_t parsed_code_val = jerry_parse ((jerry_char_t *) test_source, strlen (test_source), false);
TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val)); TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
@@ -280,6 +418,7 @@ main (void)
TEST_ASSERT (!jerry_value_has_error_flag (res)); TEST_ASSERT (!jerry_value_has_error_flag (res));
TEST_ASSERT (validator1_count == 4); TEST_ASSERT (validator1_count == 4);
TEST_ASSERT (validator2_count == 3); TEST_ASSERT (validator2_count == 3);
TEST_ASSERT (validator_prop_count == 4);
jerry_release_value (res); jerry_release_value (res);
jerry_release_value (parsed_code_val); jerry_release_value (parsed_code_val);