mirror of
https://github.com/status-im/realm-js.git
synced 2025-02-23 03:38:16 +00:00
Merge pull request #1315 from realm/tg/test-realm-errors
Check the exception message in all Realm tests which assert an exception is thrown
This commit is contained in:
commit
c0db1a6eff
@ -83,14 +83,14 @@ export default class Realm {
|
||||
if (typeof item == 'function') {
|
||||
let schema = item.schema;
|
||||
if (!schema || typeof schema != 'object') {
|
||||
throw new Error("Realm object constructor must have 'schema' property");
|
||||
throw new Error("Realm object constructor must have a 'schema' property.");
|
||||
}
|
||||
|
||||
let {name, properties} = schema;
|
||||
if (!name || typeof name != 'string') {
|
||||
throw new Error("Realm object schema must have 'name' property");
|
||||
throw new Error(`Failed to read ObjectSchema: name must be of type 'string', got (${typeof name})`);
|
||||
} else if (!properties || typeof properties != 'object') {
|
||||
throw new Error("Realm object schema must have 'properties' property");
|
||||
throw new Error(`Failed to read ObjectSchema: properties must be of type 'object', got (${typeof properties})`);
|
||||
}
|
||||
|
||||
schemas.splice(i, 1, schema);
|
||||
|
@ -85,5 +85,5 @@ export function typeForConstructor(realmId, constructor) {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
throw new Error("Constructor was not registered in the schema for this Realm")
|
||||
}
|
||||
|
@ -59,9 +59,9 @@
|
||||
"jsdoc": "npm install && npm run jsdoc:clean && jsdoc -u docs/tutorials -p package.json -c docs/conf.json",
|
||||
"prenode-tests": "npm install --build-from-source && cd tests && npm install",
|
||||
"node-tests": "cd tests && npm run test && cd ..",
|
||||
"test-runner:ava": "cd tests/test-runners/ava && npm install && npm test",
|
||||
"test-runner:mocha": "cd tests/test-runners/mocha && npm install && npm test",
|
||||
"test-runner:jest": "cd tests/test-runners/jest && npm install && npm test",
|
||||
"test-runner:ava": "cd tests/test-runners/ava && npm install --build-from-source=realm && npm test",
|
||||
"test-runner:mocha": "cd tests/test-runners/mocha && npm install --build-from-source=realm && npm test",
|
||||
"test-runner:jest": "cd tests/test-runners/jest && npm install --build-from-source=realm && npm test",
|
||||
"test-runners": "npm run test-runner:ava && npm run test-runner:mocha && npm run test-runner:jest",
|
||||
"isMac": "node -p \"if (process.platform == 'darwin') { process.exit(0); } else { process.exit(-1); }\"",
|
||||
"testMac": "npm run isMac -s && echo this is mac || echo . ",
|
||||
|
@ -9,7 +9,7 @@ export NPM_CONFIG_PROGRESS=false
|
||||
TARGET=$1
|
||||
CONFIGURATION=${2:-Release}
|
||||
|
||||
if echo $CONFIGURATION | grep -i "^Debug$" > /dev/null ; then
|
||||
if echo "$CONFIGURATION" | grep -i "^Debug$" > /dev/null ; then
|
||||
CONFIGURATION="Debug"
|
||||
fi
|
||||
|
||||
@ -17,8 +17,6 @@ IOS_SIM_DEVICE=${IOS_SIM_DEVICE:-} # use preferentially, otherwise will be set a
|
||||
ios_sim_default_device_type=${IOS_SIM_DEVICE_TYPE:-iPhone 5s}
|
||||
ios_sim_default_ios_version=${IOS_SIM_OS:-iOS 10.1}
|
||||
|
||||
ACCEPTED_LICENSES='MIT, ISC, BSD, Apache-2.0, BSD-2-Clause, BSD-3-Clause, WTFPL, Unlicense, (MIT AND CC-BY-3.0)'
|
||||
|
||||
PATH="/opt/android-sdk-linux/platform-tools:$PATH"
|
||||
SRCROOT=$(cd "$(dirname "$0")/.." && pwd)
|
||||
XCPRETTY=$(which xcpretty || true)
|
||||
@ -124,13 +122,18 @@ xctest() {
|
||||
echo " done"
|
||||
|
||||
# - Run the build and test
|
||||
xcrun xcodebuild -scheme "$1" -configuration "$CONFIGURATION" -sdk iphonesimulator -destination id="$IOS_SIM_DEVICE" build || {
|
||||
EXITCODE=$?
|
||||
echo "*** Failure (exit code $EXITCODE). ***"
|
||||
exit $EXITCODE
|
||||
}
|
||||
if [ -n "$XCPRETTY" ]; then
|
||||
log_temp=$(mktemp build.log.XXXXXX)
|
||||
if [ -e "$log_temp" ]; then
|
||||
rm "$log_temp"
|
||||
fi
|
||||
xcrun xcodebuild -scheme "$1" -configuration "$CONFIGURATION" -sdk iphonesimulator -destination name="iPhone 5s" build test 2>&1 | tee "$log_temp" | "$XCPRETTY" -c --no-utf --report junit --output build/reports/junit.xml || {
|
||||
EXITCODE=$?
|
||||
xcrun xcodebuild -scheme "$1" -configuration "$CONFIGURATION" -sdk iphonesimulator -destination name="iPhone 5s" test 2>&1 | tee "$log_temp" | "$XCPRETTY" -c --no-utf --report junit --output build/reports/junit.xml || {
|
||||
EXITCODE=$?
|
||||
printf "*** Xcode Failure (exit code %s). The full xcode log follows: ***\n\n" "$EXITCODE"
|
||||
cat "$log_temp"
|
||||
printf "\n\n*** End Xcode Failure ***\n"
|
||||
@ -138,11 +141,11 @@ xctest() {
|
||||
}
|
||||
rm "$log_temp"
|
||||
else
|
||||
xcrun xcodebuild -scheme "$1" -configuration "$CONFIGURATION" -sdk iphonesimulator -destination id="$IOS_SIM_DEVICE" build test || {
|
||||
EXITCODE=$?
|
||||
xcrun xcodebuild -scheme "$1" -configuration "$CONFIGURATION" -sdk iphonesimulator -destination id="$IOS_SIM_DEVICE" test || {
|
||||
EXITCODE=$?
|
||||
echo "*** Failure (exit code $EXITCODE). ***"
|
||||
exit $EXITCODE
|
||||
}
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
@ -234,14 +237,22 @@ cleanup
|
||||
trap cleanup EXIT
|
||||
|
||||
# Use a consistent version of Node if possible.
|
||||
if [ -f "$NVM_DIR/nvm.sh" ]; then
|
||||
. "$NVM_DIR/nvm.sh"
|
||||
elif [ -x "$(command -v brew)" ] && [ -f "$(brew --prefix nvm)/nvm.sh" ]; then
|
||||
# we must be on mac and nvm was installed with brew
|
||||
# TODO: change the mac slaves to use manual nvm installation
|
||||
. "$(brew --prefix nvm)/nvm.sh"
|
||||
if [[ -z "$(command -v nvm)" ]]; then
|
||||
set +e
|
||||
if [ -f "$NVM_DIR/nvm.sh" ]; then
|
||||
. "$NVM_DIR/nvm.sh" '' || true
|
||||
elif [ -x "$(command -v brew)" ] && [ -f "$(brew --prefix nvm)/nvm.sh" ]; then
|
||||
# we must be on mac and nvm was installed with brew
|
||||
# TODO: change the mac slaves to use manual nvm installation
|
||||
. "$(brew --prefix nvm)/nvm.sh" '' || true
|
||||
elif [ -f "$HOME/.nvm/nvm.sh" ]; then
|
||||
. ~/.nvm/nvm.sh ''
|
||||
fi
|
||||
set -e
|
||||
fi
|
||||
if [[ "$(command -v nvm)" ]]; then
|
||||
nvm install 6.5.0
|
||||
fi
|
||||
[[ "$(command -v nvm)" ]] && nvm use 6.5.0 || true
|
||||
|
||||
# Remove cached packages
|
||||
rm -rf ~/.yarn-cache/npm-realm-*
|
||||
@ -396,8 +407,6 @@ case "$TARGET" in
|
||||
;;
|
||||
"test-runners")
|
||||
npm run check-environment
|
||||
# Create a fake realm module that points to the source root so that test-runner tests can require('realm')
|
||||
npm install --build-from-source
|
||||
npm run test-runners
|
||||
;;
|
||||
"all")
|
||||
|
@ -33,6 +33,29 @@ using ConstructorType = void(typename T::Context, typename T::Object, size_t, co
|
||||
template<typename T>
|
||||
using MethodType = void(typename T::Context, typename T::Function, typename T::Object, size_t, const typename T::Value[], ReturnValue<T> &);
|
||||
|
||||
template<typename T>
|
||||
struct Arguments {
|
||||
const typename T::Context ctx;
|
||||
const size_t count;
|
||||
const typename T::Value* const value;
|
||||
|
||||
typename T::Value operator[](size_t index) const noexcept {
|
||||
if (index >= count) {
|
||||
return Value<T>::from_undefined(ctx);
|
||||
}
|
||||
return value[index];
|
||||
}
|
||||
|
||||
void validate_maximum(size_t max) const {
|
||||
if (max < count) {
|
||||
throw std::invalid_argument(util::format("Invalid arguments: at most %1 expected, but %2 supplied.", max, count));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using ArgumentsMethodType = void(typename T::Context, typename T::Function, typename T::Object, Arguments<T>, ReturnValue<T> &);
|
||||
|
||||
template<typename T>
|
||||
struct PropertyType {
|
||||
using GetterType = void(typename T::Context, typename T::Object, ReturnValue<T> &);
|
||||
|
@ -22,8 +22,6 @@
|
||||
#include "js_realm_object.hpp"
|
||||
#include "js_schema.hpp"
|
||||
|
||||
#include "util/format.hpp"
|
||||
|
||||
namespace realm {
|
||||
class List;
|
||||
class Object;
|
||||
@ -65,8 +63,9 @@ public:
|
||||
ValueType value = Object::get_property(m_ctx, object, prop_name);
|
||||
const auto& prop = m_object_schema.persisted_properties[prop_index];
|
||||
if (!Value::is_valid_for_property(m_ctx, value, prop)) {
|
||||
throw TypeErrorException(util::format("%1.%2", m_object_schema.name, prop.name),
|
||||
js_type_name_for_property_type(prop.type));
|
||||
throw TypeErrorException(m_object_schema.name, prop.name,
|
||||
js_type_name_for_property_type(prop.type),
|
||||
print(value));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -121,7 +120,7 @@ public:
|
||||
void will_change(realm::Object&, realm::Property const&) { }
|
||||
void did_change() { }
|
||||
|
||||
std::string print(ValueType const&) { return "not implemented"; }
|
||||
std::string print(ValueType const& v) { return Value::to_string(m_ctx, v); }
|
||||
|
||||
private:
|
||||
ContextType m_ctx;
|
||||
|
197
src/js_realm.hpp
197
src/js_realm.hpp
@ -123,9 +123,7 @@ class RealmDelegate : public BindingContext {
|
||||
}
|
||||
|
||||
ObjectType realm_object = create_object<T, RealmClass<T>>(m_context, new SharedRealm(realm));
|
||||
ValueType arguments[2];
|
||||
arguments[0] = realm_object;
|
||||
arguments[1] = Value::from_string(m_context, notification_name);
|
||||
ValueType arguments[] = {realm_object, Value::from_string(m_context, notification_name)};
|
||||
|
||||
std::list<Protected<FunctionType>> notifications_copy(m_notifications);
|
||||
for (auto &callback : notifications_copy) {
|
||||
@ -148,6 +146,7 @@ class RealmClass : public ClassDefinition<T, SharedRealm, ObservableClass<T>> {
|
||||
using FunctionType = typename T::Function;
|
||||
using ObjectType = typename T::Object;
|
||||
using ValueType = typename T::Value;
|
||||
using Arguments = js::Arguments<T>;
|
||||
using String = js::String<T>;
|
||||
using Object = js::Object<T>;
|
||||
using Value = js::Value<T>;
|
||||
@ -165,22 +164,22 @@ public:
|
||||
static FunctionType create_constructor(ContextType);
|
||||
|
||||
// methods
|
||||
static void objects(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void object_for_primary_key(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void create(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void delete_one(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void delete_all(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void write(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void begin_transaction(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue&);
|
||||
static void commit_transaction(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue&);
|
||||
static void cancel_transaction(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue&);
|
||||
static void add_listener(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void wait_for_download_completion(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void remove_listener(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void remove_all_listeners(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void close(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void compact(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void delete_model(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void objects(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void object_for_primary_key(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void create(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void delete_one(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void delete_all(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void write(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void begin_transaction(ContextType, FunctionType, ObjectType, Arguments, ReturnValue&);
|
||||
static void commit_transaction(ContextType, FunctionType, ObjectType, Arguments, ReturnValue&);
|
||||
static void cancel_transaction(ContextType, FunctionType, ObjectType, Arguments, ReturnValue&);
|
||||
static void add_listener(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void wait_for_download_completion(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void remove_listener(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void remove_all_listeners(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void close(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void compact(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void delete_model(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
|
||||
// properties
|
||||
static void get_empty(ContextType, ObjectType, ReturnValue &);
|
||||
@ -198,10 +197,10 @@ public:
|
||||
static void constructor(ContextType, ObjectType, size_t, const ValueType[]);
|
||||
static SharedRealm create_shared_realm(ContextType, realm::Realm::Config, bool, ObjectDefaultsMap &&, ConstructorMap &&);
|
||||
|
||||
static void schema_version(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void clear_test_state(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void copy_bundled_realm_files(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void delete_file(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
|
||||
static void schema_version(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void clear_test_state(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void copy_bundled_realm_files(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
static void delete_file(ContextType, FunctionType, ObjectType, Arguments, ReturnValue &);
|
||||
|
||||
// static properties
|
||||
static void get_default_path(ContextType, ObjectType, ReturnValue &);
|
||||
@ -398,7 +397,7 @@ void RealmClass<T>::constructor(ContextType ctx, ObjectType this_object, size_t
|
||||
static const String schema_string = "schema";
|
||||
ValueType schema_value = Object::get_property(ctx, object, schema_string);
|
||||
if (!Value::is_undefined(ctx, schema_value)) {
|
||||
ObjectType schema_object = Value::validated_to_object(ctx, schema_value, "schema");
|
||||
ObjectType schema_object = Value::validated_to_array(ctx, schema_value, "schema");
|
||||
config.schema.emplace(Schema<T>::parse_schema(ctx, schema_object, defaults, constructors));
|
||||
schema_updated = true;
|
||||
}
|
||||
@ -504,13 +503,13 @@ SharedRealm RealmClass<T>::create_shared_realm(ContextType ctx, realm::Realm::Co
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::schema_version(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 1, 2);
|
||||
void RealmClass<T>::schema_version(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(2);
|
||||
|
||||
realm::Realm::Config config;
|
||||
config.path = normalize_realm_path(Value::validated_to_string(ctx, arguments[0]));
|
||||
if (argc == 2) {
|
||||
auto encryption_key = Value::validated_to_binary(ctx, arguments[1], "encryptionKey");
|
||||
config.path = normalize_realm_path(Value::validated_to_string(ctx, args[0]));
|
||||
if (args.count == 2) {
|
||||
auto encryption_key = Value::validated_to_binary(ctx, args[1], "encryptionKey");
|
||||
config.encryption_key.assign(encryption_key.data(), encryption_key.data() + encryption_key.size());
|
||||
}
|
||||
|
||||
@ -525,23 +524,22 @@ void RealmClass<T>::schema_version(ContextType ctx, FunctionType, ObjectType thi
|
||||
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::clear_test_state(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 0);
|
||||
|
||||
void RealmClass<T>::clear_test_state(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(0);
|
||||
js::clear_test_state();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::copy_bundled_realm_files(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 0);
|
||||
void RealmClass<T>::copy_bundled_realm_files(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(0);
|
||||
realm::copy_bundled_realm_files();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::delete_file(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 1);
|
||||
void RealmClass<T>::delete_file(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(1);
|
||||
|
||||
ValueType value = arguments[0];
|
||||
ValueType value = args[0];
|
||||
if (!Value::is_object(ctx, value)) {
|
||||
throw std::runtime_error("Invalid argument, expected a Realm configuration object");
|
||||
}
|
||||
@ -569,9 +567,9 @@ void RealmClass<T>::delete_file(ContextType ctx, FunctionType, ObjectType this_o
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::delete_model(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 1);
|
||||
ValueType value = arguments[0];
|
||||
void RealmClass<T>::delete_model(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(1);
|
||||
ValueType value = args[0];
|
||||
|
||||
SharedRealm& realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
|
||||
@ -643,14 +641,14 @@ void RealmClass<T>::get_sync_session(ContextType ctx, ObjectType object, ReturnV
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::wait_for_download_completion(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 2, 3);
|
||||
auto config_object = Value::validated_to_object(ctx, arguments[0]);
|
||||
auto callback_function = Value::validated_to_function(ctx, arguments[argc - 1]);
|
||||
void RealmClass<T>::wait_for_download_completion(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(3);
|
||||
auto config_object = Value::validated_to_object(ctx, args[0]);
|
||||
auto callback_function = Value::validated_to_function(ctx, args[1 + (args.count == 3)]);
|
||||
|
||||
ValueType session_callback = Value::from_null(ctx);
|
||||
if (argc == 3) {
|
||||
session_callback = Value::validated_to_function(ctx, arguments[1]);
|
||||
if (args.count == 3) {
|
||||
session_callback = Value::validated_to_function(ctx, args[1]);
|
||||
}
|
||||
|
||||
#if REALM_ENABLE_SYNC
|
||||
@ -754,6 +752,8 @@ void RealmClass<T>::wait_for_download_completion(ContextType ctx, FunctionType,
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static_cast<void>(config_object);
|
||||
#endif
|
||||
|
||||
ValueType callback_arguments[1];
|
||||
@ -762,25 +762,25 @@ void RealmClass<T>::wait_for_download_completion(ContextType ctx, FunctionType,
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::objects(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 1);
|
||||
void RealmClass<T>::objects(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(1);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
std::string object_type;
|
||||
validated_object_schema_for_value(ctx, realm, arguments[0], object_type);
|
||||
validated_object_schema_for_value(ctx, realm, args[0], object_type);
|
||||
|
||||
return_value.set(ResultsClass<T>::create_instance(ctx, realm, object_type));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::object_for_primary_key(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 2);
|
||||
void RealmClass<T>::object_for_primary_key(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(2);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
std::string object_type;
|
||||
auto &object_schema = validated_object_schema_for_value(ctx, realm, arguments[0], object_type);
|
||||
auto &object_schema = validated_object_schema_for_value(ctx, realm, args[0], object_type);
|
||||
NativeAccessor accessor(ctx, realm, object_schema);
|
||||
auto realm_object = realm::Object::get_for_primary_key(accessor, realm, object_schema, arguments[1]);
|
||||
auto realm_object = realm::Object::get_for_primary_key(accessor, realm, object_schema, args[1]);
|
||||
|
||||
if (realm_object.is_valid()) {
|
||||
return_value.set(RealmObjectClass<T>::create_instance(ctx, std::move(realm_object)));
|
||||
@ -791,21 +791,22 @@ void RealmClass<T>::object_for_primary_key(ContextType ctx, FunctionType, Object
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::create(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 2, 3);
|
||||
void RealmClass<T>::create(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(3);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
realm->verify_open();
|
||||
std::string object_type;
|
||||
auto &object_schema = validated_object_schema_for_value(ctx, realm, arguments[0], object_type);
|
||||
auto &object_schema = validated_object_schema_for_value(ctx, realm, args[0], object_type);
|
||||
|
||||
ObjectType object = Value::validated_to_object(ctx, arguments[1], "properties");
|
||||
if (Value::is_array(ctx, arguments[1])) {
|
||||
ObjectType object = Value::validated_to_object(ctx, args[1], "properties");
|
||||
if (Value::is_array(ctx, args[1])) {
|
||||
object = Schema<T>::dict_for_property_array(ctx, object_schema, object);
|
||||
}
|
||||
|
||||
bool update = false;
|
||||
if (argc == 3) {
|
||||
update = Value::validated_to_boolean(ctx, arguments[2], "update");
|
||||
if (args.count == 3) {
|
||||
update = Value::validated_to_boolean(ctx, args[2], "update");
|
||||
}
|
||||
|
||||
NativeAccessor accessor(ctx, realm, object_schema);
|
||||
@ -814,15 +815,16 @@ void RealmClass<T>::create(ContextType ctx, FunctionType, ObjectType this_object
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::delete_one(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 1);
|
||||
void RealmClass<T>::delete_one(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(1);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
realm->verify_open();
|
||||
if (!realm->is_in_transaction()) {
|
||||
throw std::runtime_error("Can only delete objects within a transaction.");
|
||||
}
|
||||
|
||||
ObjectType arg = Value::validated_to_object(ctx, arguments[0]);
|
||||
ObjectType arg = Value::validated_to_object(ctx, args[0], "object");
|
||||
|
||||
if (Object::template is_instance<RealmObjectClass<T>>(ctx, arg)) {
|
||||
auto object = get_internal<T, RealmObjectClass<T>>(arg);
|
||||
@ -861,10 +863,11 @@ void RealmClass<T>::delete_one(ContextType ctx, FunctionType, ObjectType this_ob
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::delete_all(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 0);
|
||||
void RealmClass<T>::delete_all(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(0);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
realm->verify_open();
|
||||
|
||||
if (!realm->is_in_transaction()) {
|
||||
throw std::runtime_error("Can only delete objects within a transaction.");
|
||||
@ -876,18 +879,18 @@ void RealmClass<T>::delete_all(ContextType ctx, FunctionType, ObjectType this_ob
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::write(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 1);
|
||||
void RealmClass<T>::write(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(1);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
FunctionType callback = Value::validated_to_function(ctx, arguments[0]);
|
||||
FunctionType callback = Value::validated_to_function(ctx, args[0]);
|
||||
|
||||
realm->begin_transaction();
|
||||
|
||||
try {
|
||||
Function<T>::call(ctx, callback, this_object, 0, nullptr);
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
catch (...) {
|
||||
realm->cancel_transaction();
|
||||
throw;
|
||||
}
|
||||
@ -896,82 +899,76 @@ void RealmClass<T>::write(ContextType ctx, FunctionType, ObjectType this_object,
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::begin_transaction(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 0);
|
||||
void RealmClass<T>::begin_transaction(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(0);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
realm->begin_transaction();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::commit_transaction(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 0);
|
||||
void RealmClass<T>::commit_transaction(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(0);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
realm->commit_transaction();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::cancel_transaction(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 0);
|
||||
void RealmClass<T>::cancel_transaction(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(0);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
realm->cancel_transaction();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::add_listener(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 2);
|
||||
void RealmClass<T>::add_listener(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(2);
|
||||
|
||||
validated_notification_name(ctx, arguments[0]);
|
||||
auto callback = Value::validated_to_function(ctx, arguments[1]);
|
||||
validated_notification_name(ctx, args[0]);
|
||||
auto callback = Value::validated_to_function(ctx, args[1]);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
if (realm->is_closed()) {
|
||||
throw ClosedRealmException();
|
||||
}
|
||||
realm->verify_open();
|
||||
get_delegate<T>(realm.get())->add_notification(callback);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::remove_listener(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 2);
|
||||
void RealmClass<T>::remove_listener(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(2);
|
||||
|
||||
validated_notification_name(ctx, arguments[0]);
|
||||
auto callback = Value::validated_to_function(ctx, arguments[1]);
|
||||
validated_notification_name(ctx, args[0]);
|
||||
auto callback = Value::validated_to_function(ctx, args[1]);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
if (realm->is_closed()) {
|
||||
throw ClosedRealmException();
|
||||
}
|
||||
realm->verify_open();
|
||||
get_delegate<T>(realm.get())->remove_notification(callback);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::remove_all_listeners(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 0, 1);
|
||||
if (argc) {
|
||||
validated_notification_name(ctx, arguments[0]);
|
||||
void RealmClass<T>::remove_all_listeners(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(1);
|
||||
if (args.count) {
|
||||
validated_notification_name(ctx, args[0]);
|
||||
}
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
if (realm->is_closed()) {
|
||||
throw ClosedRealmException();
|
||||
}
|
||||
realm->verify_open();
|
||||
get_delegate<T>(realm.get())->remove_all_notifications();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::close(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 0);
|
||||
void RealmClass<T>::close(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(0);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
realm->close();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RealmClass<T>::compact(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 0);
|
||||
void RealmClass<T>::compact(ContextType ctx, FunctionType, ObjectType this_object, Arguments args, ReturnValue &return_value) {
|
||||
args.validate_maximum(0);
|
||||
|
||||
SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object);
|
||||
if (realm->is_in_transaction()) {
|
||||
|
@ -49,7 +49,7 @@ struct RealmObjectClass : ClassDefinition<T, realm::Object> {
|
||||
static void get_property(ContextType, ObjectType, const String &, ReturnValue &);
|
||||
static bool set_property(ContextType, ObjectType, const String &, ValueType);
|
||||
static std::vector<String> get_property_names(ContextType, ObjectType);
|
||||
|
||||
|
||||
static void is_valid(ContextType, FunctionType, ObjectType, size_t, const ValueType [], ReturnValue &);
|
||||
static void get_object_schema(ContextType, FunctionType, ObjectType, size_t, const ValueType [], ReturnValue &);
|
||||
static void linking_objects(ContextType, FunctionType, ObjectType, size_t, const ValueType [], ReturnValue &);
|
||||
@ -73,13 +73,13 @@ template<typename T>
|
||||
void RealmObjectClass<T>::is_valid(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
return_value.set(get_internal<T, RealmObjectClass<T>>(this_object)->is_valid());
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void RealmObjectClass<T>::get_object_schema(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
auto object = get_internal<T, RealmObjectClass<T>>(this_object);
|
||||
return_value.set(Schema<T>::object_for_object_schema(ctx, object->get_object_schema()));
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
typename T::Object RealmObjectClass<T>::create_instance(ContextType ctx, realm::Object realm_object) {
|
||||
static String prototype_string = "prototype";
|
||||
@ -100,7 +100,7 @@ typename T::Object RealmObjectClass<T>::create_instance(ContextType ctx, realm::
|
||||
if (result != object && !Value::is_null(ctx, result) && !Value::is_undefined(ctx, result)) {
|
||||
throw std::runtime_error("Realm object constructor must not return another value");
|
||||
}
|
||||
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
@ -127,12 +127,13 @@ bool RealmObjectClass<T>::set_property(ContextType ctx, ObjectType object, const
|
||||
return false;
|
||||
}
|
||||
|
||||
NativeAccessor<T> accessor(ctx, realm_object->realm(), realm_object->get_object_schema());
|
||||
if (!Value::is_valid_for_property(ctx, value, *prop)) {
|
||||
throw TypeErrorException(util::format("%1.%2", realm_object->get_object_schema().name, property_name),
|
||||
js_type_name_for_property_type(prop->type));
|
||||
throw TypeErrorException(realm_object->get_object_schema().name, property_name,
|
||||
js_type_name_for_property_type(prop->type),
|
||||
accessor.print(value));
|
||||
}
|
||||
|
||||
NativeAccessor<T> accessor(ctx, realm_object->realm(), realm_object->get_object_schema());
|
||||
realm_object->set_property_value(accessor, property_name, value, true);
|
||||
return true;
|
||||
}
|
||||
@ -162,29 +163,29 @@ std::vector<String<T>> RealmObjectClass<T>::get_property_names(ContextType ctx,
|
||||
template<typename T>
|
||||
void realm::js::RealmObjectClass<T>::linking_objects(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||
validate_argument_count(argc, 2);
|
||||
|
||||
|
||||
std::string object_type = Value::validated_to_string(ctx, arguments[0], "objectType");
|
||||
std::string property_name = Value::validated_to_string(ctx, arguments[1], "property");
|
||||
|
||||
|
||||
auto object = get_internal<T, RealmObjectClass<T>>(this_object);
|
||||
|
||||
|
||||
auto target_object_schema = object->realm()->schema().find(object_type);
|
||||
if (target_object_schema == object->realm()->schema().end()) {
|
||||
throw std::logic_error(util::format("Could not find schema for type '%1'", object_type));
|
||||
}
|
||||
|
||||
|
||||
auto link_property = target_object_schema->property_for_name(property_name);
|
||||
if (!link_property) {
|
||||
throw std::logic_error(util::format("Type '%1' does not contain property '%2'", object_type, property_name));
|
||||
}
|
||||
|
||||
|
||||
if (link_property->object_type != object->get_object_schema().name) {
|
||||
throw std::logic_error(util::format("'%1.%2' is not a relationship to '%3'", object_type, property_name, object->get_object_schema().name));
|
||||
}
|
||||
|
||||
|
||||
realm::TableRef table = ObjectStore::table_for_object_type(object->realm()->read_group(), target_object_schema->name);
|
||||
auto row = object->row();
|
||||
auto tv = row.get_table()->get_backlink_view(row.get_index(), table.get(), link_property->table_column);
|
||||
|
||||
|
||||
return_value.set(ResultsClass<T>::create_instance(ctx, realm::Results(object->realm(), std::move(tv))));
|
||||
}
|
||||
|
@ -179,9 +179,9 @@ ObjectSchema Schema<T>::parse_object_schema(ContextType ctx, ObjectType object_s
|
||||
|
||||
ObjectDefaults object_defaults;
|
||||
ObjectSchema object_schema;
|
||||
object_schema.name = Object::validated_get_string(ctx, object_schema_object, name_string);
|
||||
|
||||
ObjectType properties_object = Object::validated_get_object(ctx, object_schema_object, properties_string, "ObjectSchema must have a 'properties' object.");
|
||||
object_schema.name = Object::validated_get_string(ctx, object_schema_object, name_string, "ObjectSchema");
|
||||
|
||||
ObjectType properties_object = Object::validated_get_object(ctx, object_schema_object, properties_string, "ObjectSchema");
|
||||
if (Value::is_array(ctx, properties_object)) {
|
||||
uint32_t length = Object::validated_get_length(ctx, properties_object);
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
@ -232,7 +232,8 @@ ObjectSchema Schema<T>::parse_object_schema(ContextType ctx, ObjectType object_s
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
realm::Schema Schema<T>::parse_schema(ContextType ctx, ObjectType schema_object, ObjectDefaultsMap &defaults, ConstructorMap &constructors) {
|
||||
realm::Schema Schema<T>::parse_schema(ContextType ctx, ObjectType schema_object,
|
||||
ObjectDefaultsMap &defaults, ConstructorMap &constructors) {
|
||||
std::vector<ObjectSchema> schema;
|
||||
uint32_t length = Object::validated_get_length(ctx, schema_object);
|
||||
|
||||
|
@ -20,12 +20,14 @@
|
||||
|
||||
#include "execution_context_id.hpp"
|
||||
#include "property.hpp"
|
||||
#include "util/format.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <realm/binary_data.hpp>
|
||||
#include <realm/string_data.hpp>
|
||||
#include <realm/util/to_string.hpp>
|
||||
|
||||
#if defined(__GNUC__) && !(defined(DEBUG) && DEBUG)
|
||||
@ -80,18 +82,16 @@ struct Context {
|
||||
|
||||
class TypeErrorException : public std::invalid_argument {
|
||||
public:
|
||||
std::string const& prefix() const { return m_prefix; }
|
||||
std::string const& type() const { return m_type; }
|
||||
TypeErrorException(StringData object_type, StringData property,
|
||||
std::string const& type, std::string const& value)
|
||||
: std::invalid_argument(util::format("%1.%2 must be of type '%3', got (%4)",
|
||||
object_type, property, type, value))
|
||||
{}
|
||||
|
||||
TypeErrorException(std::string prefix, std::string type) :
|
||||
std::invalid_argument(prefix + " must be of type: " + type),
|
||||
m_prefix(std::move(prefix)),
|
||||
m_type(std::move(type))
|
||||
{}
|
||||
|
||||
private:
|
||||
std::string m_prefix;
|
||||
std::string m_type;
|
||||
TypeErrorException(const char *name, std::string const& type, std::string const& value)
|
||||
: std::invalid_argument(util::format("%1 must be of type '%2', got (%3)",
|
||||
name ? name : "JS value", type, value))
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -138,8 +138,7 @@ struct Value {
|
||||
#define VALIDATED(return_t, type) \
|
||||
static return_t validated_to_##type(ContextType ctx, const ValueType &value, const char *name = nullptr) { \
|
||||
if (!is_##type(ctx, value)) { \
|
||||
std::string prefix = name ? std::string("'") + name + "'" : "JS value"; \
|
||||
throw TypeErrorException(prefix, #type); \
|
||||
throw TypeErrorException(name, #type, to_string(ctx, value)); \
|
||||
} \
|
||||
return to_##type(ctx, value); \
|
||||
}
|
||||
@ -225,7 +224,7 @@ struct Object {
|
||||
return Value<T>::validated_to_##type(ctx, get_property(ctx, object, key), std::string(key).c_str()); \
|
||||
} \
|
||||
catch (std::invalid_argument &e) { \
|
||||
throw message ? std::invalid_argument(message) : e; \
|
||||
throw message ? std::invalid_argument(util::format("Failed to read %1: %2", message, e.what())) : e; \
|
||||
} \
|
||||
} \
|
||||
static return_t validated_get_##type(ContextType ctx, const ObjectType &object, uint32_t index, const char *message = nullptr) { \
|
||||
@ -233,7 +232,7 @@ struct Object {
|
||||
return Value<T>::validated_to_##type(ctx, get_property(ctx, object, index)); \
|
||||
} \
|
||||
catch (std::invalid_argument &e) { \
|
||||
throw message ? std::invalid_argument(message) : e; \
|
||||
throw message ? std::invalid_argument(util::format("Failed to read %1: %2", message, e.what())) : e; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,9 @@ template<typename T>
|
||||
using ClassDefinition = js::ClassDefinition<Types, T>;
|
||||
|
||||
using ConstructorType = js::ConstructorType<Types>;
|
||||
using ArgumentsMethodType = js::ArgumentsMethodType<Types>;
|
||||
using MethodType = js::MethodType<Types>;
|
||||
using Arguments = js::Arguments<Types>;
|
||||
using PropertyType = js::PropertyType<Types>;
|
||||
using IndexPropertyType = js::IndexPropertyType<Types>;
|
||||
using StringPropertyType = js::StringPropertyType<Types>;
|
||||
@ -369,6 +371,19 @@ JSValueRef wrap(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object,
|
||||
}
|
||||
}
|
||||
|
||||
template<jsc::ArgumentsMethodType F>
|
||||
JSValueRef wrap(JSContextRef ctx, JSObjectRef function, JSObjectRef this_object, size_t argc, const JSValueRef arguments[], JSValueRef* exception) {
|
||||
jsc::ReturnValue return_value(ctx);
|
||||
try {
|
||||
F(ctx, function, this_object, jsc::Arguments{ctx, argc, arguments}, return_value);
|
||||
return return_value;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
*exception = jsc::Exception::value(ctx, e);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<jsc::PropertyType::GetterType F>
|
||||
JSValueRef wrap(JSContextRef ctx, JSObjectRef object, JSStringRef property, JSValueRef* exception) {
|
||||
jsc::ReturnValue return_value(ctx);
|
||||
|
@ -31,6 +31,8 @@ using ClassDefinition = js::ClassDefinition<Types, T>;
|
||||
|
||||
using ConstructorType = js::ConstructorType<Types>;
|
||||
using MethodType = js::MethodType<Types>;
|
||||
using ArgumentsMethodType = js::ArgumentsMethodType<Types>;
|
||||
using Arguments = js::Arguments<Types>;
|
||||
using PropertyType = js::PropertyType<Types>;
|
||||
using IndexPropertyType = js::IndexPropertyType<Types>;
|
||||
using StringPropertyType = js::StringPropertyType<Types>;
|
||||
@ -308,6 +310,21 @@ void wrap(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
}
|
||||
}
|
||||
|
||||
template<node::ArgumentsMethodType F>
|
||||
void wrap(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
||||
v8::Isolate* isolate = info.GetIsolate();
|
||||
node::ReturnValue return_value(info.GetReturnValue());
|
||||
auto arguments = node::get_arguments(info);
|
||||
|
||||
try {
|
||||
F(isolate, info.Callee(), info.This(), node::Arguments{isolate, arguments.size(), arguments.data()}, return_value);
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
Nan::ThrowError(node::Exception::value(isolate, e));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<node::PropertyType::GetterType F>
|
||||
void wrap(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||
v8::Isolate* isolate = info.GetIsolate();
|
||||
|
@ -120,6 +120,23 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
assertThrowsContaining: function(func, expectedMessage) {
|
||||
var caught = false;
|
||||
try {
|
||||
func();
|
||||
}
|
||||
catch (e) {
|
||||
caught = true;
|
||||
if (!e.message.includes(expectedMessage)) {
|
||||
throw new TestFailureError(`Expected exception "${expectedMessage}" not thrown - instead caught: "${e}"`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!caught) {
|
||||
throw new TestFailureError(`Expected exception "${expectedMessage}" not thrown`);
|
||||
}
|
||||
},
|
||||
|
||||
assertTrue: function(condition, errorMessage) {
|
||||
if (!condition) {
|
||||
throw new TestFailureError(errorMessage || `Condition ${condition} expected to be true`);
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user