Merge pull request #1017 from realm/revert-1005-download-api

Revert "Download api (aka open async api)"
This commit is contained in:
blagoev 2017-05-17 15:13:14 +03:00 committed by GitHub
commit e3ef08b837
15 changed files with 23 additions and 420 deletions

42
.vscode/launch.json vendored
View File

@ -4,24 +4,6 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug LLDB",
"program": "node",
"cwd": "${workspaceRoot}/tests",
"args": ["--debug-brk=5858", "${workspaceRoot}/tests/node_modules/jasmine/bin/jasmine.js", "spec/unit_tests.js"],
"stopOnEntry": true
},
{
"type": "lldb",
"request": "launch",
"name": "Debug LLDB only",
"program": "node",
"cwd": "${workspaceRoot}/tests",
"args": ["${workspaceRoot}/tests/node_modules/jasmine/bin/jasmine.js", "spec/unit_tests.js"],
"stopOnEntry": false
},
{ {
"type": "node", "type": "node",
"request": "launch", "request": "launch",
@ -42,30 +24,6 @@
"args": [ "args": [
"spec/unit_tests.js" "spec/unit_tests.js"
] ]
},
{
"type": "node",
"request": "launch",
"name": "Download & Start Server",
"cwd": "${workspaceRoot}/scripts"
},
{
"type": "node",
"request": "attach",
"name": "Attach to Port",
"address": "localhost",
"port": 5858
}
],
"compounds": [
{
"name": "Rebuild + Start Server + Debug",
"configurations": ["Download & Start Server", "Debug Node Unit Tests (rebuild)"]
},
{
"name": "Debug LLDB + NodeJS",
"configurations": ["Debug LLDB", "Attach to Port"]
} }
] ]
} }

32
.vscode/tasks.json vendored
View File

@ -2,33 +2,15 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558 // See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format // for the documentation about the tasks.json format
"version": "0.1.0", "version": "0.1.0",
"command": "npm",
"isShellCommand": true,
"showOutput": "always",
"suppressTaskName": true,
"tasks": [ "tasks": [
{ {
"taskName": "Rebuild Node Tests", "taskName": "rebuild-node-tests",
"command": "npm",
"isShellCommand": true, "args": ["run", "prenode-tests"]
"showOutput": "always",
"suppressTaskName": true,
"args": ["run", "rebuild-changes"],
"isBuildCommand": false
},
{
"taskName": "Build Node Tests",
"command": "npm",
"isShellCommand": true,
"showOutput": "always",
"suppressTaskName": true,
"args": ["run", "build-changes"],
"isBuildCommand": true
},
{
"taskName": "Download and Start Server",
"command": "${workspaceRoot}/scripts/download_and_start_server.sh",
"isShellCommand": true,
"showOutput": "always",
"echoCommand": true,
"isBackground": true,
"suppressTaskName": true
} }
] ]
} }

View File

@ -19,7 +19,7 @@ Old files can still be opened and files open in read-only mode will not be modif
* The SyncConfig now gets two more optional parameters, `validate_ssl` and `ssl_trust_certificate_path`. * The SyncConfig now gets two more optional parameters, `validate_ssl` and `ssl_trust_certificate_path`.
### Enhancements ### Enhancements
* Add Realm open async API support. * None
### Bug fixes ### Bug fixes
* None * None

View File

@ -40,35 +40,6 @@ module.exports = function(realmConstructor) {
setConstructorOnPrototype(realmConstructor.Results); setConstructorOnPrototype(realmConstructor.Results);
setConstructorOnPrototype(realmConstructor.Object); setConstructorOnPrototype(realmConstructor.Object);
//Add async open API
Object.defineProperties(realmConstructor, getOwnPropertyDescriptors({
open(config) {
return new Promise((resolve, reject) => {
realmConstructor._waitForDownload(config, (error) => {
if (error) {
reject(error);
}
let syncedRealm = new realmConstructor(config);
//FIXME: RN hangs here. Remove when node's makeCallback alternative is implemented
setTimeout(() => { resolve(syncedRealm); }, 1);
});
});
},
openAsync(config, callback) {
realmConstructor._waitForDownload(config, (error) => {
if (error) {
callback(error);
}
let syncedRealm = new realmConstructor(config);
//FIXME: RN hangs here. Remove when node's makeCallback alternative is implemented
setTimeout(() => { callback(null, syncedRealm); }, 1);
});
},
}));
// Add sync methods // Add sync methods
if (realmConstructor.Sync) { if (realmConstructor.Sync) {
let userMethods = require('./user-methods'); let userMethods = require('./user-methods');

View File

@ -51,9 +51,7 @@
"lint": "eslint", "lint": "eslint",
"test": "scripts/test.sh", "test": "scripts/test.sh",
"install": "node-pre-gyp install --fallback-to-build", "install": "node-pre-gyp install --fallback-to-build",
"build-changes": "node-pre-gyp build --fallback-to-build --debug --build-from-source", "prepublish": "node scripts/prepublish.js",
"rebuild-changes": "node-pre-gyp install --fallback-to-build --debug --build-from-source && cd tests && npm install",
"prepublish": "echo prepublishing && node scripts/prepublish.js",
"eslint": "npm install && npm run lint .", "eslint": "npm install && npm run lint .",
"license-check": "npm install && license-checker --exclude \"MIT,ISC,BSD,Apache-2.0,BSD-2-Clause,BSD-3-Clause,WTFPL,Unlicense,(MIT AND CC-BY-3.0)\" | node scripts/handle-license-check.js", "license-check": "npm install && license-checker --exclude \"MIT,ISC,BSD,Apache-2.0,BSD-2-Clause,BSD-3-Clause,WTFPL,Unlicense,(MIT AND CC-BY-3.0)\" | node scripts/handle-license-check.js",
"jsdoc:clean": "rimraf ./docs/output", "jsdoc:clean": "rimraf ./docs/output",

View File

@ -1,6 +0,0 @@
#!/bin/bash
set -o pipefail
set -e
echo $(pwd)
sh scripts/download-object-server.sh && sh object-server-for-testing/start-object-server.command -f && echo \"Server PID: $!\"

View File

@ -45,21 +45,13 @@ template <typename... Args>
class EventLoopDispatcher<void(Args...)> { class EventLoopDispatcher<void(Args...)> {
using Tuple = std::tuple<typename std::remove_reference<Args>::type...>; using Tuple = std::tuple<typename std::remove_reference<Args>::type...>;
private: private:
struct Callback;
struct State { struct State {
public: public:
State(std::function<void(Args...)> func) : State(std::function<void(Args...)> func) : m_func(func) { }
m_func(func),
m_signal(nullptr)
{
}
const std::function<void(Args...)> m_func; const std::function<void(Args...)> m_func;
std::queue<Tuple> m_invocations; std::queue<Tuple> m_invocations;
std::mutex m_mutex; std::mutex m_mutex;
std::shared_ptr<EventLoopSignal<Callback>> m_signal;
}; };
const std::shared_ptr<State> m_state; const std::shared_ptr<State> m_state;
@ -75,7 +67,6 @@ private:
::_apply_polyfill::apply(tuple, m_state->m_func); ::_apply_polyfill::apply(tuple, m_state->m_func);
m_state->m_invocations.pop(); m_state->m_invocations.pop();
} }
m_state->m_signal.reset();
} }
}; };
const std::shared_ptr<EventLoopSignal<Callback>> m_signal; const std::shared_ptr<EventLoopSignal<Callback>> m_signal;
@ -101,7 +92,6 @@ public:
{ {
std::unique_lock<std::mutex> lock(m_state->m_mutex); std::unique_lock<std::mutex> lock(m_state->m_mutex);
m_state->m_signal = m_signal;
m_state->m_invocations.push(std::make_tuple(args...)); m_state->m_invocations.push(std::make_tuple(args...));
} }
m_signal->notify(); m_signal->notify();

View File

@ -165,8 +165,6 @@ public:
using ObjectDefaultsMap = typename Schema<T>::ObjectDefaultsMap; using ObjectDefaultsMap = typename Schema<T>::ObjectDefaultsMap;
using ConstructorMap = typename Schema<T>::ConstructorMap; using ConstructorMap = typename Schema<T>::ConstructorMap;
using WaitHandler = void(std::error_code);
static FunctionType create_constructor(ContextType); static FunctionType create_constructor(ContextType);
// methods // methods
@ -177,7 +175,6 @@ public:
static void delete_all(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 write(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void add_listener(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_listener(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void remove_all_listeners(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 close(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
@ -209,7 +206,6 @@ public:
{"schemaVersion", wrap<schema_version>}, {"schemaVersion", wrap<schema_version>},
{"clearTestState", wrap<clear_test_state>}, {"clearTestState", wrap<clear_test_state>},
{"copyBundledRealmFiles", wrap<copy_bundled_realm_files>}, {"copyBundledRealmFiles", wrap<copy_bundled_realm_files>},
{"_waitForDownload", wrap<wait_for_download_completion>},
}; };
PropertyMap<T> const static_properties = { PropertyMap<T> const static_properties = {
@ -541,78 +537,6 @@ void RealmClass<T>::get_sync_session(ContextType ctx, ObjectType object, ReturnV
} }
} }
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);
auto config_object = Value::validated_to_object(ctx, arguments[0]);
auto callback_function = Value::validated_to_function(ctx, arguments[1]);
ValueType sync_config_value = Object::get_property(ctx, config_object, "sync");
if (!Value::is_undefined(ctx, sync_config_value)) {
realm::Realm::Config config;
static const String encryption_key_string = "encryptionKey";
ValueType encryption_key_value = Object::get_property(ctx, config_object, encryption_key_string);
if (!Value::is_undefined(ctx, encryption_key_value)) {
std::string encryption_key = NativeAccessor::to_binary(ctx, encryption_key_value);
config.encryption_key = std::vector<char>(encryption_key.begin(), encryption_key.end());
}
Protected<ObjectType> thiz(ctx, this_object);
SyncClass<T>::populate_sync_config(ctx, thiz, config_object, config);
Protected<FunctionType> protected_callback(ctx, callback_function);
Protected<ObjectType> protected_this(ctx, this_object);
Protected<typename T::GlobalContext> protected_ctx(Context<T>::get_global_context(ctx));
EventLoopDispatcher<WaitHandler> wait_handler([=](std::error_code error_code) {
HANDLESCOPE
if (!error_code) {
//success
Function<T>::callback(protected_ctx, protected_callback, protected_this, 0, nullptr);
}
else {
//fail
ObjectType object = Object::create_empty(protected_ctx);
Object::set_property(protected_ctx, object, "message", Value::from_string(protected_ctx, error_code.message()));
Object::set_property(protected_ctx, object, "errorCode", Value::from_number(protected_ctx, error_code.value()));
ValueType callback_arguments[1];
callback_arguments[0] = object;
Function<T>::callback(protected_ctx, protected_callback, protected_this, 1, callback_arguments);
}
});
std::function<WaitHandler> waitFunc = std::move(wait_handler);
auto realm = realm::Realm::get_shared_realm(config);
if (auto sync_config = config.sync_config) {
std::shared_ptr<SyncUser> user = sync_config->user;
if (user && user->state() != SyncUser::State::Error) {
if (auto session = user->session_for_on_disk_path(config.path)) {
session->wait_for_download_completion([=](std::error_code error_code) {
realm->config(); //capture and keep realm instance for till here
waitFunc(error_code);
});
return;
}
}
ObjectType object = Object::create_empty(protected_ctx);
Object::set_property(protected_ctx, object, "message", Value::from_string(protected_ctx, "Cannot asynchronously open synced Realm, because the associated session previously experienced a fatal error"));
Object::set_property(protected_ctx, object, "errorCode", Value::from_number(protected_ctx, 1));
ValueType callback_arguments[1];
callback_arguments[0] = object;
Function<T>::call(protected_ctx, protected_callback, protected_this, 1, callback_arguments);
return;
}
}
ValueType callback_arguments[1];
callback_arguments[0] = Value::from_null(ctx);
Function<T>::call(ctx, callback_function, this_object, 1, callback_arguments);
}
#endif #endif
template<typename T> template<typename T>

View File

@ -151,7 +151,6 @@ struct Function {
using ObjectType = typename T::Object; using ObjectType = typename T::Object;
using ValueType = typename T::Value; using ValueType = typename T::Value;
static ValueType callback(ContextType, const FunctionType &, const ObjectType &, size_t, const ValueType[]);
static ValueType call(ContextType, const FunctionType &, const ObjectType &, size_t, const ValueType[]); static ValueType call(ContextType, const FunctionType &, const ObjectType &, size_t, const ValueType[]);
template<size_t N> static ValueType call(ContextType ctx, const FunctionType &function, template<size_t N> static ValueType call(ContextType ctx, const FunctionType &function,
const ObjectType &this_object, const ValueType (&arguments)[N]) const ObjectType &this_object, const ValueType (&arguments)[N])

View File

@ -33,11 +33,6 @@ inline JSValueRef jsc::Function::call(JSContextRef ctx, const JSObjectRef &funct
return result; return result;
} }
template<>
inline JSValueRef jsc::Function::callback(JSContextRef ctx, const JSObjectRef &function, const JSObjectRef &this_object, size_t argc, const JSValueRef arguments[]) {
return jsc::Function::call(ctx, function, this_object, argc, arguments);
}
template<> template<>
inline JSObjectRef jsc::Function::construct(JSContextRef ctx, const JSObjectRef &function, size_t argc, const JSValueRef arguments[]) { inline JSObjectRef jsc::Function::construct(JSContextRef ctx, const JSObjectRef &function, size_t argc, const JSValueRef arguments[]) {
JSValueRef exception = nullptr; JSValueRef exception = nullptr;

View File

@ -36,19 +36,6 @@ inline v8::Local<v8::Value> node::Function::call(v8::Isolate* isolate, const v8:
return result.ToLocalChecked(); return result.ToLocalChecked();
} }
template<>
inline v8::Local<v8::Value> node::Function::callback(v8::Isolate* isolate, const v8::Local<v8::Function> &function, const v8::Local<v8::Object> &this_object, size_t argc, const v8::Local<v8::Value> arguments[]) {
Nan::TryCatch trycatch;
auto recv = this_object.IsEmpty() ? isolate->GetCurrentContext()->Global() : this_object;
auto result = Nan::MakeCallback(recv, function, (int)argc, const_cast<v8::Local<v8::Value>*>(arguments));
if (trycatch.HasCaught()) {
throw node::Exception(isolate, trycatch.Exception());
}
return result;
}
template<> template<>
inline v8::Local<v8::Object> node::Function::construct(v8::Isolate* isolate, const v8::Local<v8::Function> &function, size_t argc, const v8::Local<v8::Value> arguments[]) { inline v8::Local<v8::Object> node::Function::construct(v8::Isolate* isolate, const v8::Local<v8::Function> &function, size_t argc, const v8::Local<v8::Value> arguments[]) {
Nan::TryCatch trycatch; Nan::TryCatch trycatch;

View File

@ -1,34 +0,0 @@
/*
This script creates 3 new objects into a new realm. These are objects are validated to exists by the download api tests.
*/
'use strict';
const username = process.argv[2];
const realmName = process.argv[3];
const realmModule = process.argv[4];
var Realm = require(realmModule);
Realm.Sync.User.register('http://localhost:9080', username, 'password', (error, user) => {
if (error) {
console.log(error);
process.exit(-2);
} else {
const config = {
sync: { user, url: `realm://localhost:9080/~/${realmName}`, error: err => console.log(err) },
schema: [{ name: 'Dog', properties: { name: 'string' } }]
};
var realm = new Realm(config);
realm.write(() => {
for (let i = 1; i <= 3; i++) {
realm.create('Dog', { name: `Lassy ${i}` });
}
});
console.log("Dogs count " + realm.objects('Dog').length);
setTimeout(_ => process.exit(0), 3000);
}
});

View File

@ -35,16 +35,11 @@ if (!(typeof process === 'object' && process.platform === 'win32')) {
} }
// If sync is enabled, run the user tests // If sync is enabled, run the user tests
let hasSync = false;
try { try {
Realm.Sync; // This will throw if Sync is disabled. Realm.Sync; // This will throw if Sync is disabled.
hasSync = true;
} catch (e) { }
if (hasSync) {
TESTS.UserTests = require('./user-tests'); TESTS.UserTests = require('./user-tests');
TESTS.SessionTests = require('./session-tests'); TESTS.SessionTests = require('./session-tests');
} } catch (e) {}
function node_require(module) { return require(module); } function node_require(module) { return require(module); }

View File

@ -23,49 +23,17 @@
const Realm = require('realm'); const Realm = require('realm');
const TestCase = require('./asserts'); const TestCase = require('./asserts');
const isNodeProccess = (typeof process === 'object' && process + '' === '[object process]');
console.log("isnode " + isNodeProccess + " typeof " + typeof process === 'object');
function node_require(module) {
return require(module);
}
let tmp;
let fs;
let execFile;
if (isNodeProccess) {
tmp = node_require('tmp');
fs = node_require('fs');
execFile = node_require('child_process').execFile;
tmp.setGracefulCleanup();
}
function uuid() { function uuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16); return v.toString(16);
}); });
} }
function promisifiedRegister(server, username, password) { function promisifiedRegister(server, username, password) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Realm.Sync.User.register(server, username, password, (error, user) => { Realm.Sync.User.register(server, username, password, (error, user) => {
if (error) { if (error) {
console.log(`promisifiedRegister ${error}`);
reject(error);
} else {
resolve(user);
}
});
});
}
function promisifiedLogin(server, username, password) {
return new Promise((resolve, reject) => {
Realm.Sync.User.login(server, username, password, (error, user) => {
if (error) {
console.log(`promisifiedLogin ${error}`);
reject(error); reject(error);
} else { } else {
resolve(user); resolve(user);
@ -75,7 +43,6 @@ function promisifiedLogin(server, username, password) {
} }
module.exports = { module.exports = {
testLocalRealmHasNoSession() { testLocalRealmHasNoSession() {
let realm = new Realm(); let realm = new Realm();
TestCase.assertNull(realm.syncSession); TestCase.assertNull(realm.syncSession);
@ -83,25 +50,17 @@ module.exports = {
testProperties() { testProperties() {
return promisifiedRegister('http://localhost:9080', uuid(), 'password').then(user => { return promisifiedRegister('http://localhost:9080', uuid(), 'password').then(user => {
return new Promise((resolve, reject) => { return new Promise((resolve, _reject) => {
const accessTokenRefreshed = this; const accessTokenRefreshed = this;
let successCounter = 0;
function checkSuccess() {
successCounter++;
if (successCounter == 2) {
resolve();
}
}
function postTokenRefreshChecks(sender, error) { function postTokenRefreshChecks(sender, error) {
try { try {
TestCase.assertEqual(error, accessTokenRefreshed); TestCase.assertEqual(error, accessTokenRefreshed);
TestCase.assertEqual(sender.url, `realm://localhost:9080/${user.identity}/myrealm`); TestCase.assertEqual(sender.url, `realm://localhost:9080/${user.identity}/myrealm`);
checkSuccess(); resolve();
} }
catch (e) { catch (e) {
reject(e) _reject(e)
} }
}; };
@ -111,129 +70,18 @@ module.exports = {
const config = { sync: { user, url: 'realm://localhost:9080/~/myrealm', error: postTokenRefreshChecks } }; const config = { sync: { user, url: 'realm://localhost:9080/~/myrealm', error: postTokenRefreshChecks } };
const realm = new Realm(config); const realm = new Realm(config);
const session = realm.syncSession; const session = realm.syncSession;
TestCase.assertInstanceOf(session, Realm.Sync.Session); TestCase.assertInstanceOf(session, Realm.Sync.Session);
TestCase.assertEqual(session.user.identity, user.identity); TestCase.assertEqual(session.user.identity, user.identity);
TestCase.assertEqual(session.config.url, config.sync.url); TestCase.assertEqual(session.config.url, config.sync.url);
TestCase.assertEqual(session.config.user.identity, config.sync.user.identity); TestCase.assertEqual(session.config.user.identity, config.sync.user.identity);
TestCase.assertUndefined(session.url); TestCase.assertUndefined(session.url);
TestCase.assertEqual(session.state, 'active'); TestCase.assertEqual(session.state, 'active');
checkSuccess();
}); });
}); });
}, },
testRealmOpen() {
if (!isNodeProccess) {
return Promise.resolve();
}
const username = uuid();
const realmName = uuid();
const expectedObjectsCount = 3;
let tmpDir = tmp.dirSync();
let content = fs.readFileSync(__dirname + '/download-api-helper.js', 'utf8');
let tmpFile = tmp.fileSync({ dir: tmpDir.name });
fs.appendFileSync(tmpFile.fd, content, { encoding: 'utf8' });
return new Promise((resolve, reject) => {
//execute download-api-helper which inserts predefined number of objects into the synced realm.
const child = execFile('node', [tmpFile.name, username, realmName, REALM_MODULE_PATH], { cwd: tmpDir.name }, (error, stdout, stderr) => {
if (error) {
reject(new Error('Error executing download api helper' + error));
}
resolve();
});
})
.then(() => {
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
return new Promise((resolve, reject) => {
const accessTokenRefreshed = this;
let successCounter = 0;
let config = {
sync: { user, url: `realm://localhost:9080/~/${realmName}` },
schema: [{ name: 'Dog', properties: { name: 'string' } }],
};
Realm.open(config)
.then(realm => {
let actualObjectsCount = realm.objects('Dog').length;
TestCase.assertEqual(actualObjectsCount, expectedObjectsCount, "Synced realm does not contain the expected objects count");
const session = realm.syncSession;
TestCase.assertInstanceOf(session, Realm.Sync.Session);
TestCase.assertEqual(session.user.identity, user.identity);
TestCase.assertEqual(session.config.url, config.sync.url);
TestCase.assertEqual(session.config.user.identity, config.sync.user.identity);
TestCase.assertEqual(session.state, 'active');
resolve();
}).catch(e => { reject(e) });
});
});
});
},
testRealmOpenAsync() {
if (!isNodeProccess) {
return Promise.resolve();
}
const username = uuid();
const realmName = uuid();
const expectedObjectsCount = 3;
let tmpDir = tmp.dirSync();
let content = fs.readFileSync(__dirname + '/download-api-helper.js', 'utf8');
let tmpFile = tmp.fileSync({ dir: tmpDir.name });
fs.appendFileSync(tmpFile.fd, content, { encoding: 'utf8' });
return new Promise((resolve, reject) => {
//execute download-api-helper which inserts predefined number of objects into the synced realm.
const child = execFile('node', [tmpFile.name, username, realmName, REALM_MODULE_PATH], { cwd: tmpDir.name }, (error, stdout, stderr) => {
if (error) {
reject(new Error('Error executing download api helper' + error));
}
resolve();
});
})
.then(() => {
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
return new Promise((resolve, reject) => {
const accessTokenRefreshed = this;
let successCounter = 0;
let config = {
sync: { user, url: `realm://localhost:9080/~/${realmName}` },
schema: [{ name: 'Dog', properties: { name: 'string' } }],
};
Realm.openAsync(config, (error, realm) => {
try {
if (error) {
reject(error);
}
let actualObjectsCount = realm.objects('Dog').length;
TestCase.assertEqual(actualObjectsCount, expectedObjectsCount, "Synced realm does not contain the expected objects count");
const session = realm.syncSession;
TestCase.assertInstanceOf(session, Realm.Sync.Session);
TestCase.assertEqual(session.user.identity, user.identity);
TestCase.assertEqual(session.config.url, config.sync.url);
TestCase.assertEqual(session.config.user.identity, config.sync.user.identity);
TestCase.assertEqual(session.state, 'active');
resolve();
}
catch (e) {
reject(e);
}
});
});
});
});
},
testErrorHandling() { testErrorHandling() {
return promisifiedRegister('http://localhost:9080', uuid(), 'password').then(user => { return promisifiedRegister('http://localhost:9080', uuid(), 'password').then(user => {
return new Promise((resolve, _reject) => { return new Promise((resolve, _reject) => {

View File

@ -28,10 +28,6 @@ const Realm = require('realm');
const RealmTests = require('../js'); const RealmTests = require('../js');
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000; jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
const isDebuggerAttached = typeof v8debug === 'object';
if (isDebuggerAttached) {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000000;
}
// Create this method with appropriate implementation for Node testing. // Create this method with appropriate implementation for Node testing.
Realm.copyBundledRealmFiles = function() { Realm.copyBundledRealmFiles = function() {