Merge branch 'master' into al-android-example
* master: Fix typo in README Improve clarity of schema parsing and serialization Add test that checks schema validation Update README with new Schema API Cleanup some code and comments to make it consistent Convert tests to create objects with property objects Update example apps with new schema API Remove confusion between propTypes and objectTypes Simplify object schema info returned from RPC RPC now keeps object keys in the same order Change schema API to take properties as an object Add method to clear mutation listeners in RPC client Plug small leak from not releasing a JSStringRef Make RJSStringForValue use consistent exception style Improve error messages inside RJSUtil
This commit is contained in:
commit
2f1eca4a9c
35
README.md
35
README.md
|
@ -28,12 +28,12 @@ const Realm = require('realm');
|
||||||
const personSchema = {
|
const personSchema = {
|
||||||
name: 'Person',
|
name: 'Person',
|
||||||
primaryKey: 'name',
|
primaryKey: 'name',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'name', type: Realm.Types.STRING},
|
name: 'string',
|
||||||
{name: 'birthday', type: Realm.Types.DATE},
|
birthday: 'date',
|
||||||
{name: 'friends', type: Realm.Types.LIST, objectType: 'Person'},
|
friends: {type: 'list', objectType: 'Person'},
|
||||||
{name: 'points', type: Realm.Types.INT, default: 0},
|
points: {type: 'int', default: 0},
|
||||||
],
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const realm = new Realm({schema: [personSchema]});
|
const realm = new Realm({schema: [personSchema]});
|
||||||
|
@ -101,27 +101,28 @@ The `realmConfig` passed to the constructor can contain the following:
|
||||||
|
|
||||||
### ObjectSchema
|
### ObjectSchema
|
||||||
- `name` – string used to refer to this object type
|
- `name` – string used to refer to this object type
|
||||||
- `properties` - array of property defitions (see below)
|
- `properties` - object with property definitions (see below)
|
||||||
- `primaryKey` – optional - name of `STRING` or `INT` property that should be unique
|
- `primaryKey` – optional - name of `STRING` or `INT` property that should be unique
|
||||||
|
|
||||||
### Property Types
|
### Property Types
|
||||||
When definining object `properties` in a `schema`, each should have a unique `name`, and the `type` of each property must be defined as either the name of an object type in the same schema **or** as one of the following:
|
When defining object `properties` in a `schema`, the value for each property must either be the `type` **OR** an object with a `type` key along with other options detailed below. The `type` of each property must be defined as either the name of an object type in the same schema **or** as one of the following:
|
||||||
|
|
||||||
- `Realm.Types.BOOL`
|
- `Realm.Types.BOOL` (`"bool"`)
|
||||||
- `Realm.Types.INT`
|
- `Realm.Types.INT` (`"int"`)
|
||||||
- `Realm.Types.FLOAT`
|
- `Realm.Types.FLOAT` (`"float"`)
|
||||||
- `Realm.Types.DOUBLE`
|
- `Realm.Types.DOUBLE` (`"double"`)
|
||||||
- `Realm.Types.STRING`
|
- `Realm.Types.STRING` (`"string"`)
|
||||||
- `Realm.Types.DATE`
|
- `Realm.Types.DATE` (`"date"`)
|
||||||
- `Realm.Types.DATA`
|
- `Realm.Types.DATA` (`"data"`)
|
||||||
- `Realm.Types.OBJECT` (requires `objectType`, is always `optional`)
|
- `Realm.Types.LIST` (`"list"` – requires `objectType` and cannot be `optional`)
|
||||||
- `Realm.Types.LIST` (requires `objectType`, is never `optional`)
|
|
||||||
|
|
||||||
You _may_ specify these property options as well:
|
You _may_ specify these property options as well:
|
||||||
|
|
||||||
- `default` – default value when property was not specified on creation
|
- `default` – default value when property was not specified on creation
|
||||||
- `optional` – boolean indicating if this property may be assigned `null` or `undefined`
|
- `optional` – boolean indicating if this property may be assigned `null` or `undefined`
|
||||||
|
|
||||||
|
**Note:** When the `type` of a property is that of an object type in the same schema, it _always_ will be `optional`.
|
||||||
|
|
||||||
### `Realm` Instance Methods
|
### `Realm` Instance Methods
|
||||||
#### `create(type, props [, update])`
|
#### `create(type, props [, update])`
|
||||||
- `type` – string matching object `name` in the `schema` definition
|
- `type` – string matching object `name` in the `schema` definition
|
||||||
|
|
|
@ -10,17 +10,17 @@ module.exports = new Realm({
|
||||||
schema: [
|
schema: [
|
||||||
{
|
{
|
||||||
name: 'Todo',
|
name: 'Todo',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'done', type: Realm.Types.BOOL, default: false},
|
done: {type: Realm.Types.BOOL, default: false},
|
||||||
{name: 'text', type: Realm.Types.STRING, default: ''},
|
text: Realm.Types.STRING,
|
||||||
]
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'TodoList',
|
name: 'TodoList',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'name', type: Realm.Types.STRING},
|
name: Realm.Types.STRING,
|
||||||
{name: 'items', type: Realm.Types.LIST, objectType: 'Todo'},
|
items: {type: Realm.Types.LIST, objectType: 'Todo', default: []},
|
||||||
]
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,7 +23,7 @@ class TodoApp extends React.Component {
|
||||||
let todoLists = realm.objects('TodoList');
|
let todoLists = realm.objects('TodoList');
|
||||||
if (todoLists.length < 1) {
|
if (todoLists.length < 1) {
|
||||||
realm.write(() => {
|
realm.write(() => {
|
||||||
realm.create('TodoList', {name: 'Todo List', items: []});
|
realm.create('TodoList', {name: 'Todo List'});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ class TodoApp extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
realm.write(() => {
|
realm.write(() => {
|
||||||
realm.create('TodoList', {name: '', items: []});
|
realm.create('TodoList', {name: ''});
|
||||||
});
|
});
|
||||||
|
|
||||||
this._setEditingRow(items.length - 1);
|
this._setEditingRow(items.length - 1);
|
||||||
|
|
|
@ -17,12 +17,18 @@ let propTypes = {};
|
||||||
});
|
});
|
||||||
|
|
||||||
[
|
[
|
||||||
|
'DATA',
|
||||||
|
'DATE',
|
||||||
|
'DICT',
|
||||||
'FUNCTION',
|
'FUNCTION',
|
||||||
|
'LIST',
|
||||||
|
'OBJECT',
|
||||||
'REALM',
|
'REALM',
|
||||||
'RESULTS',
|
'RESULTS',
|
||||||
|
'UNDEFINED',
|
||||||
].forEach(function(type) {
|
].forEach(function(type) {
|
||||||
Object.defineProperty(objectTypes, type, {
|
Object.defineProperty(objectTypes, type, {
|
||||||
value: 'ObjectTypes' + type,
|
value: type.toLowerCase(),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
const constants = require('./constants');
|
const constants = require('./constants');
|
||||||
const util = require('./util');
|
const util = require('./util');
|
||||||
|
|
||||||
|
const {objectTypes} = constants;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
create,
|
create,
|
||||||
};
|
};
|
||||||
|
@ -14,12 +16,12 @@ module.exports = {
|
||||||
class List {}
|
class List {}
|
||||||
|
|
||||||
// Non-mutating methods:
|
// Non-mutating methods:
|
||||||
util.createMethods(List.prototype, constants.propTypes.LIST, [
|
util.createMethods(List.prototype, objectTypes.LIST, [
|
||||||
'snapshot',
|
'snapshot',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Mutating methods:
|
// Mutating methods:
|
||||||
util.createMethods(List.prototype, constants.propTypes.LIST, [
|
util.createMethods(List.prototype, objectTypes.LIST, [
|
||||||
'pop',
|
'pop',
|
||||||
'shift',
|
'shift',
|
||||||
'push',
|
'push',
|
||||||
|
|
|
@ -24,9 +24,7 @@ function create(realmId, info) {
|
||||||
object[keys.id] = info.id;
|
object[keys.id] = info.id;
|
||||||
object[keys.type] = info.type;
|
object[keys.type] = info.type;
|
||||||
|
|
||||||
schema.properties.forEach((prop) => {
|
schema.properties.forEach((name) => {
|
||||||
let name = prop.name;
|
|
||||||
|
|
||||||
Object.defineProperty(object, name, {
|
Object.defineProperty(object, name, {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
get: util.getterForProperty(name),
|
get: util.getterForProperty(name),
|
||||||
|
|
|
@ -14,8 +14,8 @@ const util = require('./util');
|
||||||
const {keys, propTypes, objectTypes} = constants;
|
const {keys, propTypes, objectTypes} = constants;
|
||||||
const listenersKey = Symbol();
|
const listenersKey = Symbol();
|
||||||
|
|
||||||
rpc.registerTypeConverter(propTypes.LIST, lists.create);
|
rpc.registerTypeConverter(objectTypes.LIST, lists.create);
|
||||||
rpc.registerTypeConverter(propTypes.OBJECT, objects.create);
|
rpc.registerTypeConverter(objectTypes.OBJECT, objects.create);
|
||||||
rpc.registerTypeConverter(objectTypes.RESULTS, results.create);
|
rpc.registerTypeConverter(objectTypes.RESULTS, results.create);
|
||||||
|
|
||||||
class Realm {
|
class Realm {
|
||||||
|
@ -125,7 +125,10 @@ Object.defineProperties(Realm, {
|
||||||
set: util.setterForProperty('defaultPath'),
|
set: util.setterForProperty('defaultPath'),
|
||||||
},
|
},
|
||||||
clearTestState: {
|
clearTestState: {
|
||||||
value: rpc.clearTestState,
|
value: function() {
|
||||||
|
util.clearMutationListeners();
|
||||||
|
rpc.clearTestState();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
43
lib/rpc.js
43
lib/rpc.js
|
@ -9,7 +9,8 @@ const constants = require('./constants');
|
||||||
|
|
||||||
const DEVICE_HOST = 'localhost:8082';
|
const DEVICE_HOST = 'localhost:8082';
|
||||||
|
|
||||||
const {keys, objectTypes, propTypes} = constants;
|
const {keys, objectTypes} = constants;
|
||||||
|
const {id: idKey, realm: realmKey} = keys;
|
||||||
const typeConverters = {};
|
const typeConverters = {};
|
||||||
|
|
||||||
let XMLHttpRequest = global.originalXMLHttpRequest || global.XMLHttpRequest;
|
let XMLHttpRequest = global.originalXMLHttpRequest || global.XMLHttpRequest;
|
||||||
|
@ -38,8 +39,9 @@ module.exports = {
|
||||||
clearTestState,
|
clearTestState,
|
||||||
};
|
};
|
||||||
|
|
||||||
registerTypeConverter(propTypes.DATA, (_, {value}) => base64.decode(value));
|
registerTypeConverter(objectTypes.DATA, (_, {value}) => base64.decode(value));
|
||||||
registerTypeConverter(propTypes.DATE, (_, {value}) => new Date(value));
|
registerTypeConverter(objectTypes.DATE, (_, {value}) => new Date(value));
|
||||||
|
registerTypeConverter(objectTypes.DICT, deserializeDict);
|
||||||
|
|
||||||
function registerTypeConverter(type, handler) {
|
function registerTypeConverter(type, handler) {
|
||||||
typeConverters[type] = handler;
|
typeConverters[type] = handler;
|
||||||
|
@ -94,21 +96,19 @@ function clearTestState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function serialize(realmId, value) {
|
function serialize(realmId, value) {
|
||||||
|
if (typeof value == 'undefined') {
|
||||||
|
return {type: objectTypes.UNDEFINED};
|
||||||
|
}
|
||||||
if (typeof value == 'function') {
|
if (typeof value == 'function') {
|
||||||
return {type: objectTypes.FUNCTION};
|
return {type: objectTypes.FUNCTION};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === 'undefined') {
|
|
||||||
return {type: 'undefined'};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!value || typeof value != 'object') {
|
if (!value || typeof value != 'object') {
|
||||||
return {value: value};
|
return {value: value};
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = value[keys.id];
|
let id = value[idKey];
|
||||||
if (id) {
|
if (id) {
|
||||||
if (value[keys.realm] != realmId) {
|
if (value[realmKey] != realmId) {
|
||||||
throw new Error('Unable to serialize value from another Realm');
|
throw new Error('Unable to serialize value from another Realm');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ function serialize(realmId, value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof Date) {
|
if (value instanceof Date) {
|
||||||
return {type: propTypes.DATE, value: value.getTime()};
|
return {type: objectTypes.DATE, value: value.getTime()};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
|
@ -125,14 +125,12 @@ function serialize(realmId, value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
||||||
return {type: propTypes.DATA, value: base64.encode(value)};
|
return {type: objectTypes.DATA, value: base64.encode(value)};
|
||||||
}
|
}
|
||||||
|
|
||||||
let object = {};
|
let keys = Object.keys(value);
|
||||||
for (let key in value) {
|
let values = keys.map((key) => serialize(realmId, value[key]));
|
||||||
object[key] = serialize(realmId, value[key]);
|
return {type: objectTypes.DICT, keys, values};
|
||||||
}
|
|
||||||
return {value: object};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function deserialize(realmId, info) {
|
function deserialize(realmId, info) {
|
||||||
|
@ -150,6 +148,17 @@ function deserialize(realmId, info) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deserializeDict(realmId, info) {
|
||||||
|
let {keys, values} = info;
|
||||||
|
let object = {};
|
||||||
|
|
||||||
|
for (let i = 0, len = keys.length; i < len; i++) {
|
||||||
|
object[keys[i]] = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
function sendRequest(command, data) {
|
function sendRequest(command, data) {
|
||||||
data = Object.assign({}, data, sessionId ? {sessionId} : null);
|
data = Object.assign({}, data, sessionId ? {sessionId} : null);
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,10 @@ const constants = require('./constants');
|
||||||
const rpc = require('./rpc');
|
const rpc = require('./rpc');
|
||||||
|
|
||||||
const {keys} = constants;
|
const {keys} = constants;
|
||||||
const mutationListeners = {};
|
let mutationListeners = {};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
clearMutationListeners,
|
||||||
fireMutationListeners,
|
fireMutationListeners,
|
||||||
createList,
|
createList,
|
||||||
createMethods,
|
createMethods,
|
||||||
|
@ -31,6 +32,10 @@ function removeMutationListener(realmId, callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearMutationListeners() {
|
||||||
|
mutationListeners = {};
|
||||||
|
}
|
||||||
|
|
||||||
function fireMutationListeners(realmId) {
|
function fireMutationListeners(realmId) {
|
||||||
let listeners = mutationListeners[realmId];
|
let listeners = mutationListeners[realmId];
|
||||||
if (listeners) {
|
if (listeners) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ JSClassRef RJSRealmTypeClass() {
|
||||||
{ "DATE", RJSTypeGet, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
|
{ "DATE", RJSTypeGet, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
|
||||||
{ "DATA", RJSTypeGet, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
|
{ "DATA", RJSTypeGet, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
|
||||||
{ "OBJECT", RJSTypeGet, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
|
{ "OBJECT", RJSTypeGet, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
|
||||||
{ "LIST", RJSTypeGet, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
|
{ "LIST", RJSTypeGet, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
|
||||||
{ NULL, NULL, NULL, 0 }
|
{ NULL, NULL, NULL, 0 }
|
||||||
};
|
};
|
||||||
realmTypesDefinition.staticValues = types;
|
realmTypesDefinition.staticValues = types;
|
||||||
|
|
|
@ -69,13 +69,16 @@ namespace realm {
|
||||||
|
|
||||||
template<> bool RJSAccessor::dict_has_value_for_key(JSContextRef ctx, JSValueRef dict, const std::string &prop_name) {
|
template<> bool RJSAccessor::dict_has_value_for_key(JSContextRef ctx, JSValueRef dict, const std::string &prop_name) {
|
||||||
JSObjectRef object = RJSValidatedValueToObject(ctx, dict);
|
JSObjectRef object = RJSValidatedValueToObject(ctx, dict);
|
||||||
JSStringRef propStr =JSStringCreateWithUTF8CString(prop_name.c_str());
|
JSStringRef propStr = RJSStringForString(prop_name);
|
||||||
return JSObjectHasProperty(ctx, object, propStr);
|
bool ret = JSObjectHasProperty(ctx, object, propStr);
|
||||||
|
|
||||||
|
JSStringRelease(propStr);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> JSValueRef RJSAccessor::dict_value_for_key(JSContextRef ctx, JSValueRef dict, const std::string &prop_name) {
|
template<> JSValueRef RJSAccessor::dict_value_for_key(JSContextRef ctx, JSValueRef dict, const std::string &prop_name) {
|
||||||
JSObjectRef object = RJSValidatedValueToObject(ctx, dict);
|
JSObjectRef object = RJSValidatedValueToObject(ctx, dict);
|
||||||
JSStringRef propStr =JSStringCreateWithUTF8CString(prop_name.c_str());
|
JSStringRef propStr = RJSStringForString(prop_name);
|
||||||
JSValueRef ex = NULL;
|
JSValueRef ex = NULL;
|
||||||
JSValueRef ret = JSObjectGetProperty(ctx, object, propStr, &ex);
|
JSValueRef ret = JSObjectGetProperty(ctx, object, propStr, &ex);
|
||||||
if (ex) {
|
if (ex) {
|
||||||
|
|
|
@ -31,25 +31,34 @@ JSObjectRef RJSSchemaCreate(JSContextRef ctx, Schema &schema) {
|
||||||
return RJSWrapObject(ctx, RJSSchemaClass(), wrapper);
|
return RJSWrapObject(ctx, RJSSchemaClass(), wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Property RJSParseProperty(JSContextRef ctx, JSObjectRef propertyObject) {
|
static inline Property RJSParseProperty(JSContextRef ctx, JSValueRef propertyAttributes, std::string propertyName, ObjectDefaults &objectDefaults) {
|
||||||
static JSStringRef nameString = JSStringCreateWithUTF8CString("name");
|
static JSStringRef defaultString = JSStringCreateWithUTF8CString("default");
|
||||||
static JSStringRef typeString = JSStringCreateWithUTF8CString("type");
|
static JSStringRef typeString = JSStringCreateWithUTF8CString("type");
|
||||||
static JSStringRef objectTypeString = JSStringCreateWithUTF8CString("objectType");
|
static JSStringRef objectTypeString = JSStringCreateWithUTF8CString("objectType");
|
||||||
static JSStringRef optionalString = JSStringCreateWithUTF8CString("optional");
|
static JSStringRef optionalString = JSStringCreateWithUTF8CString("optional");
|
||||||
|
|
||||||
Property prop;
|
Property prop;
|
||||||
prop.name = RJSValidatedStringProperty(ctx, propertyObject, nameString);
|
prop.name = propertyName;
|
||||||
|
|
||||||
prop.is_nullable = false;
|
JSObjectRef propertyObject = NULL;
|
||||||
JSValueRef optionalValue = JSObjectGetProperty(ctx, propertyObject, optionalString, NULL);
|
std::string type;
|
||||||
if (!JSValueIsUndefined(ctx, optionalValue)) {
|
|
||||||
if (!JSValueIsBoolean(ctx, optionalValue)) {
|
if (JSValueIsObject(ctx, propertyAttributes)) {
|
||||||
throw std::runtime_error("'optional' designation expected to be of type boolean");
|
propertyObject = RJSValidatedValueToObject(ctx, propertyAttributes);
|
||||||
|
type = RJSValidatedStringProperty(ctx, propertyObject, typeString);
|
||||||
|
|
||||||
|
JSValueRef optionalValue = JSObjectGetProperty(ctx, propertyObject, optionalString, NULL);
|
||||||
|
if (!JSValueIsUndefined(ctx, optionalValue)) {
|
||||||
|
if (!JSValueIsBoolean(ctx, optionalValue)) {
|
||||||
|
throw std::runtime_error("'optional' designation expected to be of type boolean");
|
||||||
|
}
|
||||||
|
prop.is_nullable = JSValueToBoolean(ctx, optionalValue);
|
||||||
}
|
}
|
||||||
prop.is_nullable = JSValueToBoolean(ctx, optionalValue);
|
}
|
||||||
|
else {
|
||||||
|
type = RJSValidatedStringForValue(ctx, propertyAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string type = RJSValidatedStringProperty(ctx, propertyObject, typeString);
|
|
||||||
if (type == "bool") {
|
if (type == "bool") {
|
||||||
prop.type = PropertyTypeBool;
|
prop.type = PropertyTypeBool;
|
||||||
}
|
}
|
||||||
|
@ -72,22 +81,49 @@ static inline Property RJSParseProperty(JSContextRef ctx, JSObjectRef propertyOb
|
||||||
prop.type = PropertyTypeData;
|
prop.type = PropertyTypeData;
|
||||||
}
|
}
|
||||||
else if (type == "list") {
|
else if (type == "list") {
|
||||||
|
if (!propertyObject) {
|
||||||
|
throw std::runtime_error("List property must specify 'objectType'");
|
||||||
|
}
|
||||||
prop.type = PropertyTypeArray;
|
prop.type = PropertyTypeArray;
|
||||||
prop.object_type = RJSValidatedStringProperty(ctx, propertyObject, objectTypeString);
|
prop.object_type = RJSValidatedStringProperty(ctx, propertyObject, objectTypeString);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
prop.type = PropertyTypeObject;
|
prop.type = PropertyTypeObject;
|
||||||
prop.is_nullable = true;
|
prop.is_nullable = true;
|
||||||
prop.object_type = type == "object" ? RJSValidatedStringProperty(ctx, propertyObject, objectTypeString) : type;
|
|
||||||
|
// The type could either be 'object' or the name of another object type in the same schema.
|
||||||
|
if (type == "object") {
|
||||||
|
if (!propertyObject) {
|
||||||
|
throw std::runtime_error("Object property must specify 'objectType'");
|
||||||
|
}
|
||||||
|
prop.object_type = RJSValidatedStringProperty(ctx, propertyObject, objectTypeString);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prop.object_type = type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (propertyObject) {
|
||||||
|
JSValueRef defaultValue = RJSValidatedPropertyValue(ctx, propertyObject, defaultString);
|
||||||
|
if (!JSValueIsUndefined(ctx, defaultValue)) {
|
||||||
|
JSValueProtect(ctx, defaultValue);
|
||||||
|
objectDefaults.emplace(prop.name, defaultValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef objectSchemaObject, std::map<std::string, realm::ObjectDefaults> &defaults, std::map<std::string, JSValueRef> &prototypes) {
|
static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef objectSchemaObject, std::map<std::string, realm::ObjectDefaults> &defaults, std::map<std::string, JSValueRef> &prototypes) {
|
||||||
static JSStringRef schemaString = JSStringCreateWithUTF8CString("schema");
|
static JSStringRef nameString = JSStringCreateWithUTF8CString("name");
|
||||||
|
static JSStringRef primaryString = JSStringCreateWithUTF8CString("primaryKey");
|
||||||
static JSStringRef prototypeString = JSStringCreateWithUTF8CString("prototype");
|
static JSStringRef prototypeString = JSStringCreateWithUTF8CString("prototype");
|
||||||
|
static JSStringRef propertiesString = JSStringCreateWithUTF8CString("properties");
|
||||||
|
static JSStringRef schemaString = JSStringCreateWithUTF8CString("schema");
|
||||||
|
|
||||||
JSObjectRef prototypeObject = NULL;
|
JSObjectRef prototypeObject = NULL;
|
||||||
JSValueRef prototypeValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, prototypeString);
|
JSValueRef prototypeValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, prototypeString);
|
||||||
|
|
||||||
if (!JSValueIsUndefined(ctx, prototypeValue)) {
|
if (!JSValueIsUndefined(ctx, prototypeValue)) {
|
||||||
prototypeObject = RJSValidatedValueToObject(ctx, prototypeValue);
|
prototypeObject = RJSValidatedValueToObject(ctx, prototypeValue);
|
||||||
objectSchemaObject = RJSValidatedObjectProperty(ctx, prototypeObject, schemaString, "Realm object prototype must have a 'schema' property.");
|
objectSchemaObject = RJSValidatedObjectProperty(ctx, prototypeObject, schemaString, "Realm object prototype must have a 'schema' property.");
|
||||||
|
@ -99,29 +135,30 @@ static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef ob
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSStringRef propertiesString = JSStringCreateWithUTF8CString("properties");
|
|
||||||
JSObjectRef propertiesObject = RJSValidatedObjectProperty(ctx, objectSchemaObject, propertiesString, "ObjectSchema object must have a 'properties' array.");
|
|
||||||
|
|
||||||
ObjectSchema objectSchema;
|
|
||||||
ObjectDefaults objectDefaults;
|
ObjectDefaults objectDefaults;
|
||||||
static JSStringRef nameString = JSStringCreateWithUTF8CString("name");
|
ObjectSchema objectSchema;
|
||||||
objectSchema.name = RJSValidatedStringProperty(ctx, objectSchemaObject, nameString);
|
objectSchema.name = RJSValidatedStringProperty(ctx, objectSchemaObject, nameString);
|
||||||
|
|
||||||
size_t numProperties = RJSValidatedListLength(ctx, propertiesObject);
|
JSObjectRef propertiesObject = RJSValidatedObjectProperty(ctx, objectSchemaObject, propertiesString, "ObjectSchema must have a 'properties' object.");
|
||||||
for (unsigned int p = 0; p < numProperties; p++) {
|
if (RJSIsValueArray(ctx, propertiesObject)) {
|
||||||
JSObjectRef property = RJSValidatedObjectAtIndex(ctx, propertiesObject, p);
|
size_t propertyCount = RJSValidatedListLength(ctx, propertiesObject);
|
||||||
objectSchema.properties.emplace_back(RJSParseProperty(ctx, property));
|
for (size_t i = 0; i < propertyCount; i++) {
|
||||||
|
JSObjectRef propertyObject = RJSValidatedObjectAtIndex(ctx, propertiesObject, (unsigned int)i);
|
||||||
static JSStringRef defaultString = JSStringCreateWithUTF8CString("default");
|
std::string propertyName = RJSValidatedStringProperty(ctx, propertyObject, nameString);
|
||||||
JSValueRef defaultValue = JSObjectGetProperty(ctx, property, defaultString, NULL);
|
objectSchema.properties.emplace_back(RJSParseProperty(ctx, propertyObject, propertyName, objectDefaults));
|
||||||
if (!JSValueIsUndefined(ctx, defaultValue)) {
|
|
||||||
JSValueProtect(ctx, defaultValue);
|
|
||||||
objectDefaults.emplace(objectSchema.properties.back().name, defaultValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defaults.emplace(objectSchema.name, std::move(objectDefaults));
|
else {
|
||||||
|
JSPropertyNameArrayRef propertyNames = JSObjectCopyPropertyNames(ctx, propertiesObject);
|
||||||
|
size_t propertyCount = JSPropertyNameArrayGetCount(propertyNames);
|
||||||
|
for (size_t i = 0; i < propertyCount; i++) {
|
||||||
|
JSStringRef propertyName = JSPropertyNameArrayGetNameAtIndex(propertyNames, i);
|
||||||
|
JSValueRef propertyValue = RJSValidatedPropertyValue(ctx, propertiesObject, propertyName);
|
||||||
|
objectSchema.properties.emplace_back(RJSParseProperty(ctx, propertyValue, RJSStringForJSString(propertyName), objectDefaults));
|
||||||
|
}
|
||||||
|
JSPropertyNameArrayRelease(propertyNames);
|
||||||
|
}
|
||||||
|
|
||||||
static JSStringRef primaryString = JSStringCreateWithUTF8CString("primaryKey");
|
|
||||||
JSValueRef primaryValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, primaryString);
|
JSValueRef primaryValue = RJSValidatedPropertyValue(ctx, objectSchemaObject, primaryString);
|
||||||
if (!JSValueIsUndefined(ctx, primaryValue)) {
|
if (!JSValueIsUndefined(ctx, primaryValue)) {
|
||||||
objectSchema.primary_key = RJSValidatedStringForValue(ctx, primaryValue);
|
objectSchema.primary_key = RJSValidatedStringForValue(ctx, primaryValue);
|
||||||
|
@ -132,12 +169,14 @@ static inline ObjectSchema RJSParseObjectSchema(JSContextRef ctx, JSObjectRef ob
|
||||||
property->is_primary = true;
|
property->is_primary = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store prototype
|
// Store prototype so that objects of this type will have their prototype set to this prototype object.
|
||||||
if (prototypeObject) {
|
if (prototypeObject) {
|
||||||
JSValueProtect(ctx, prototypeObject);
|
JSValueProtect(ctx, prototypeObject);
|
||||||
prototypes[objectSchema.name] = std::move(prototypeObject);
|
prototypes[objectSchema.name] = std::move(prototypeObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaults.emplace(objectSchema.name, std::move(objectDefaults));
|
||||||
|
|
||||||
return objectSchema;
|
return objectSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,21 +24,6 @@ JSValueRef RJSMakeError(JSContextRef ctx, const std::string &message) {
|
||||||
return JSObjectMakeError(ctx, 1, &value, NULL);
|
return JSObjectMakeError(ctx, 1, &value, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RJSTypeGet(PropertyType propertyType) {
|
|
||||||
switch (propertyType) {
|
|
||||||
case PropertyTypeBool: return "bool";
|
|
||||||
case PropertyTypeInt: return "int";
|
|
||||||
case PropertyTypeFloat: return "float";
|
|
||||||
case PropertyTypeDouble:return "double";
|
|
||||||
case PropertyTypeString:return "string";
|
|
||||||
case PropertyTypeDate: return "date";
|
|
||||||
case PropertyTypeData: return "data";
|
|
||||||
case PropertyTypeObject:return "object";
|
|
||||||
case PropertyTypeArray: return "list";
|
|
||||||
default: return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string RJSStringForJSString(JSStringRef jsString) {
|
std::string RJSStringForJSString(JSStringRef jsString) {
|
||||||
std::string str;
|
std::string str;
|
||||||
size_t maxSize = JSStringGetMaximumUTF8CStringSize(jsString);
|
size_t maxSize = JSStringGetMaximumUTF8CStringSize(jsString);
|
||||||
|
@ -48,10 +33,10 @@ std::string RJSStringForJSString(JSStringRef jsString) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RJSStringForValue(JSContextRef ctx, JSValueRef value) {
|
std::string RJSStringForValue(JSContextRef ctx, JSValueRef value) {
|
||||||
JSValueRef *exception = nullptr;
|
JSValueRef exception = nullptr;
|
||||||
JSStringRef jsString = JSValueToStringCopy(ctx, value, exception);
|
JSStringRef jsString = JSValueToStringCopy(ctx, value, &exception);
|
||||||
if (!jsString) {
|
if (!jsString) {
|
||||||
throw RJSException(ctx, *exception);
|
throw RJSException(ctx, exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string string = RJSStringForJSString(jsString);
|
std::string string = RJSStringForJSString(jsString);
|
||||||
|
@ -98,4 +83,3 @@ bool RJSIsValueDate(JSContextRef ctx, JSValueRef value) {
|
||||||
static JSStringRef dateString = JSStringCreateWithUTF8CString("Date");
|
static JSStringRef dateString = JSStringCreateWithUTF8CString("Date");
|
||||||
return RJSIsValueObjectOfType(ctx, value, dateString);
|
return RJSIsValueObjectOfType(ctx, value, dateString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,6 @@ JSClassRef RJSCreateWrapperClass(const char * name, JSObjectGetPropertyCallback
|
||||||
return JSClassCreate(&classDefinition);
|
return JSClassCreate(&classDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RJSTypeGet(realm::PropertyType propertyType);
|
|
||||||
|
|
||||||
std::string RJSStringForJSString(JSStringRef jsString);
|
std::string RJSStringForJSString(JSStringRef jsString);
|
||||||
std::string RJSStringForValue(JSContextRef ctx, JSValueRef value);
|
std::string RJSStringForValue(JSContextRef ctx, JSValueRef value);
|
||||||
std::string RJSValidatedStringForValue(JSContextRef ctx, JSValueRef value, const char * name = nullptr);
|
std::string RJSValidatedStringForValue(JSContextRef ctx, JSValueRef value, const char * name = nullptr);
|
||||||
|
@ -148,7 +146,7 @@ static inline JSValueRef RJSValidatedPropertyValue(JSContextRef ctx, JSObjectRef
|
||||||
static inline JSObjectRef RJSValidatedObjectProperty(JSContextRef ctx, JSObjectRef object, JSStringRef property, const char *err = NULL) {
|
static inline JSObjectRef RJSValidatedObjectProperty(JSContextRef ctx, JSObjectRef object, JSStringRef property, const char *err = NULL) {
|
||||||
JSValueRef propertyValue = RJSValidatedPropertyValue(ctx, object, property);
|
JSValueRef propertyValue = RJSValidatedPropertyValue(ctx, object, property);
|
||||||
if (JSValueIsUndefined(ctx, propertyValue)) {
|
if (JSValueIsUndefined(ctx, propertyValue)) {
|
||||||
throw std::runtime_error(err ?: "Object property is undefined");
|
throw std::runtime_error(err ?: "Object property '" + RJSStringForJSString(property) + "' is undefined");
|
||||||
}
|
}
|
||||||
return RJSValidatedValueToObject(ctx, propertyValue, err);
|
return RJSValidatedValueToObject(ctx, propertyValue, err);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +166,7 @@ static inline std::string RJSValidatedStringProperty(JSContextRef ctx, JSObjectR
|
||||||
if (exception) {
|
if (exception) {
|
||||||
throw RJSException(ctx, exception);
|
throw RJSException(ctx, exception);
|
||||||
}
|
}
|
||||||
return RJSValidatedStringForValue(ctx, propertyValue);
|
return RJSValidatedStringForValue(ctx, propertyValue, RJSStringForJSString(property).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t RJSValidatedListLength(JSContextRef ctx, JSObjectRef object) {
|
static inline size_t RJSValidatedListLength(JSContextRef ctx, JSObjectRef object) {
|
||||||
|
|
85
src/rpc.cpp
85
src/rpc.cpp
|
@ -23,8 +23,14 @@
|
||||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||||
using namespace realm_js;
|
using namespace realm_js;
|
||||||
|
|
||||||
static const char * const RealmObjectTypesFunction = "ObjectTypesFUNCTION";
|
static const char * const RealmObjectTypesData = "data";
|
||||||
static const char * const RealmObjectTypesResults = "ObjectTypesRESULTS";
|
static const char * const RealmObjectTypesDate = "date";
|
||||||
|
static const char * const RealmObjectTypesDictionary = "dict";
|
||||||
|
static const char * const RealmObjectTypesFunction = "function";
|
||||||
|
static const char * const RealmObjectTypesList = "list";
|
||||||
|
static const char * const RealmObjectTypesObject = "object";
|
||||||
|
static const char * const RealmObjectTypesResults = "results";
|
||||||
|
static const char * const RealmObjectTypesUndefined = "undefined";
|
||||||
|
|
||||||
RPCServer::RPCServer() {
|
RPCServer::RPCServer() {
|
||||||
m_context = JSGlobalContextCreate(NULL);
|
m_context = JSGlobalContextCreate(NULL);
|
||||||
|
@ -219,7 +225,7 @@ json RPCServer::serialize_json_value(JSValueRef value) {
|
||||||
if (JSValueIsObjectOfClass(m_context, value, RJSObjectClass())) {
|
if (JSValueIsObjectOfClass(m_context, value, RJSObjectClass())) {
|
||||||
realm::Object *object = RJSGetInternal<realm::Object *>(js_object);
|
realm::Object *object = RJSGetInternal<realm::Object *>(js_object);
|
||||||
return {
|
return {
|
||||||
{"type", RJSTypeGet(realm::PropertyTypeObject)},
|
{"type", RealmObjectTypesObject},
|
||||||
{"id", store_object(js_object)},
|
{"id", store_object(js_object)},
|
||||||
{"schema", serialize_object_schema(object->get_object_schema())}
|
{"schema", serialize_object_schema(object->get_object_schema())}
|
||||||
};
|
};
|
||||||
|
@ -227,7 +233,7 @@ json RPCServer::serialize_json_value(JSValueRef value) {
|
||||||
else if (JSValueIsObjectOfClass(m_context, value, RJSListClass())) {
|
else if (JSValueIsObjectOfClass(m_context, value, RJSListClass())) {
|
||||||
realm::List *list = RJSGetInternal<realm::List *>(js_object);
|
realm::List *list = RJSGetInternal<realm::List *>(js_object);
|
||||||
return {
|
return {
|
||||||
{"type", RJSTypeGet(realm::PropertyTypeArray)},
|
{"type", RealmObjectTypesList},
|
||||||
{"id", store_object(js_object)},
|
{"id", store_object(js_object)},
|
||||||
{"size", list->size()},
|
{"size", list->size()},
|
||||||
{"schema", serialize_object_schema(list->get_object_schema())}
|
{"schema", serialize_object_schema(list->get_object_schema())}
|
||||||
|
@ -253,26 +259,47 @@ json RPCServer::serialize_json_value(JSValueRef value) {
|
||||||
else if (RJSIsValueArrayBuffer(m_context, value)) {
|
else if (RJSIsValueArrayBuffer(m_context, value)) {
|
||||||
std::string data = RJSAccessor::to_binary(m_context, value);
|
std::string data = RJSAccessor::to_binary(m_context, value);
|
||||||
return {
|
return {
|
||||||
{"type", RJSTypeGet(realm::PropertyTypeData)},
|
{"type", RealmObjectTypesData},
|
||||||
{"value", base64_encode((unsigned char *)data.data(), data.size())},
|
{"value", base64_encode((unsigned char *)data.data(), data.size())},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (RJSIsValueDate(m_context, value)) {
|
else if (RJSIsValueDate(m_context, value)) {
|
||||||
return {
|
return {
|
||||||
{"type", RJSTypeGet(realm::PropertyTypeDate)},
|
{"type", RealmObjectTypesDate},
|
||||||
{"value", RJSValidatedValueToNumber(m_context, value)},
|
{"value", RJSValidatedValueToNumber(m_context, value)},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Serialize this JS object as a plain object since it doesn't match any known types above.
|
||||||
|
JSPropertyNameArrayRef js_keys = JSObjectCopyPropertyNames(m_context, js_object);
|
||||||
|
size_t count = JSPropertyNameArrayGetCount(js_keys);
|
||||||
|
std::vector<std::string> keys;
|
||||||
|
std::vector<json> values;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
JSStringRef js_key = JSPropertyNameArrayGetNameAtIndex(js_keys, i);
|
||||||
|
JSValueRef js_value = RJSValidatedPropertyValue(m_context, js_object, js_key);
|
||||||
|
|
||||||
|
keys.push_back(RJSStringForJSString(js_key));
|
||||||
|
values.push_back(serialize_json_value(js_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
JSPropertyNameArrayRelease(js_keys);
|
||||||
|
|
||||||
|
return {
|
||||||
|
{"type", RealmObjectTypesDictionary},
|
||||||
|
{"keys", keys},
|
||||||
|
{"values", values},
|
||||||
|
};
|
||||||
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
json RPCServer::serialize_object_schema(const realm::ObjectSchema &object_schema) {
|
json RPCServer::serialize_object_schema(const realm::ObjectSchema &object_schema) {
|
||||||
json properties = json::array();
|
std::vector<std::string> properties;
|
||||||
|
|
||||||
for (realm::Property prop : object_schema.properties) {
|
for (realm::Property prop : object_schema.properties) {
|
||||||
properties.push_back({
|
properties.push_back(prop.name);
|
||||||
{"name", prop.name},
|
|
||||||
{"type", RJSTypeGet(prop.type)},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -300,14 +327,30 @@ JSValueRef RPCServer::deserialize_json_value(const json dict)
|
||||||
|
|
||||||
return js_function;
|
return js_function;
|
||||||
}
|
}
|
||||||
else if (type_string == RJSTypeGet(realm::PropertyTypeData)) {
|
else if (type_string == RealmObjectTypesDictionary) {
|
||||||
|
JSObjectRef js_object = JSObjectMake(m_context, NULL, NULL);
|
||||||
|
json keys = dict["keys"];
|
||||||
|
json values = dict["values"];
|
||||||
|
size_t count = keys.size();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
JSStringRef js_key = RJSStringForString(keys.at(i));
|
||||||
|
JSValueRef js_value = deserialize_json_value(values.at(i));
|
||||||
|
|
||||||
|
JSObjectSetProperty(m_context, js_object, js_key, js_value, 0, NULL);
|
||||||
|
JSStringRelease(js_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return js_object;
|
||||||
|
}
|
||||||
|
else if (type_string == RealmObjectTypesData) {
|
||||||
std::string bytes;
|
std::string bytes;
|
||||||
if (!base64_decode(value.get<std::string>(), &bytes)) {
|
if (!base64_decode(value.get<std::string>(), &bytes)) {
|
||||||
throw std::runtime_error("Failed to decode base64 encoded data");
|
throw std::runtime_error("Failed to decode base64 encoded data");
|
||||||
}
|
}
|
||||||
return RJSAccessor::from_binary(m_context, realm::BinaryData(bytes));
|
return RJSAccessor::from_binary(m_context, realm::BinaryData(bytes));
|
||||||
}
|
}
|
||||||
else if (type_string == RJSTypeGet(realm::PropertyTypeDate)) {
|
else if (type_string == RealmObjectTypesDate) {
|
||||||
JSValueRef exception = NULL;
|
JSValueRef exception = NULL;
|
||||||
JSValueRef time = JSValueMakeNumber(m_context, value.get<double>());
|
JSValueRef time = JSValueMakeNumber(m_context, value.get<double>());
|
||||||
JSObjectRef date = JSObjectMakeDate(m_context, 1, &time, &exception);
|
JSObjectRef date = JSObjectMakeDate(m_context, 1, &time, &exception);
|
||||||
|
@ -317,7 +360,7 @@ JSValueRef RPCServer::deserialize_json_value(const json dict)
|
||||||
}
|
}
|
||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
else if (type_string == "undefined") {
|
else if (type_string == RealmObjectTypesUndefined) {
|
||||||
return JSValueMakeUndefined(m_context);
|
return JSValueMakeUndefined(m_context);
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -345,19 +388,5 @@ JSValueRef RPCServer::deserialize_json_value(const json dict)
|
||||||
|
|
||||||
return JSObjectMakeArray(m_context, count, js_values, NULL);
|
return JSObjectMakeArray(m_context, count, js_values, NULL);
|
||||||
}
|
}
|
||||||
else if (value.is_object()) {
|
|
||||||
JSObjectRef js_object = JSObjectMake(m_context, NULL, NULL);
|
|
||||||
|
|
||||||
for (json::iterator it = value.begin(); it != value.end(); ++it) {
|
|
||||||
JSValueRef js_value = deserialize_json_value(it.value());
|
|
||||||
JSStringRef js_key = JSStringCreateWithUTF8CString(it.key().c_str());
|
|
||||||
|
|
||||||
JSObjectSetProperty(m_context, js_object, js_key, js_value, 0, NULL);
|
|
||||||
JSStringRelease(js_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return js_object;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,20 +12,30 @@ var schemas = require('./schemas');
|
||||||
module.exports = BaseTest.extend({
|
module.exports = BaseTest.extend({
|
||||||
testArrayLength: function() {
|
testArrayLength: function() {
|
||||||
var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]});
|
||||||
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
TestCase.assertEqual(obj.arrayCol.length, 1);
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}],
|
||||||
|
});
|
||||||
|
|
||||||
|
array = obj.arrayCol;
|
||||||
|
TestCase.assertEqual(array.length, 1);
|
||||||
|
|
||||||
obj.arrayCol = [];
|
obj.arrayCol = [];
|
||||||
TestCase.assertEqual(obj.arrayCol.length, 0);
|
TestCase.assertEqual(array.length, 0);
|
||||||
|
|
||||||
obj.arrayCol = [[1], [2]];
|
obj.arrayCol = [{doubleCol: 1}, {doubleCol: 2}];
|
||||||
TestCase.assertEqual(obj.arrayCol.length, 2);
|
TestCase.assertEqual(array.length, 2);
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
obj.arrayCol.length = 0;
|
array.length = 0;
|
||||||
}, 'cannot set length property on lists');
|
}, 'cannot set length property on lists');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TestCase.assertEqual(array.length, 2);
|
||||||
},
|
},
|
||||||
|
|
||||||
testArraySubscriptGetters: function() {
|
testArraySubscriptGetters: function() {
|
||||||
|
@ -33,7 +43,12 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}, {doubleCol: 4}],
|
||||||
|
});
|
||||||
|
|
||||||
array = obj.arrayCol;
|
array = obj.arrayCol;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -48,26 +63,36 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
array = obj.arrayCol;
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}, {doubleCol: 4}],
|
||||||
|
});
|
||||||
|
|
||||||
array[0] = [5];
|
array = obj.arrayCol;
|
||||||
array[1] = [6];
|
array[0] = {doubleCol: 5};
|
||||||
|
array[1] = {doubleCol: 6};
|
||||||
|
|
||||||
TestCase.assertEqual(array[0].doubleCol, 5);
|
TestCase.assertEqual(array[0].doubleCol, 5);
|
||||||
TestCase.assertEqual(array[1].doubleCol, 6);
|
TestCase.assertEqual(array[1].doubleCol, 6);
|
||||||
|
|
||||||
|
array[0] = obj.objectCol;
|
||||||
|
array[1] = obj.objectCol1;
|
||||||
|
|
||||||
|
TestCase.assertEqual(array[0].doubleCol, 1);
|
||||||
|
TestCase.assertEqual(array[1].doubleCol, 2);
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
array[2] = [1];
|
array[2] = {doubleCol: 1};
|
||||||
}, 'cannot set list item beyond its bounds');
|
}, 'cannot set list item beyond its bounds');
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
array[-1] = [1];
|
array[-1] = {doubleCol: 1};
|
||||||
}, 'cannot set list item with negative index');
|
}, 'cannot set list item with negative index');
|
||||||
});
|
});
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
array[0] = [3];
|
array[0] = {doubleCol: 1};
|
||||||
}, 'cannot set list item outside write transaction');
|
}, 'cannot set list item outside write transaction');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -76,7 +101,12 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}, {doubleCol: 4}],
|
||||||
|
});
|
||||||
|
|
||||||
array = obj.arrayCol;
|
array = obj.arrayCol;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -88,21 +118,26 @@ module.exports = BaseTest.extend({
|
||||||
var obj;
|
var obj;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
obj = realm.create('LinkTypesObject', [[1], [2], []]);
|
obj = realm.create('LinkTypesObject', {
|
||||||
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var index in obj.arrayCol) {
|
var index;
|
||||||
|
for (index in obj.arrayCol) {
|
||||||
TestCase.assertTrue(false, "No objects should have been enumerated: " + index);
|
TestCase.assertTrue(false, "No objects should have been enumerated: " + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
obj.arrayCol = [[0], [1]];
|
obj.arrayCol = [{doubleCol: 0}, {doubleCol: 1}];
|
||||||
TestCase.assertEqual(obj.arrayCol.length, 2);
|
TestCase.assertEqual(obj.arrayCol.length, 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
var keys = Object.keys(obj.arrayCol);
|
var keys = Object.keys(obj.arrayCol);
|
||||||
for (var index in obj.arrayCol) {
|
for (index in obj.arrayCol) {
|
||||||
TestCase.assertEqual(count++, +index);
|
TestCase.assertEqual(count++, +index);
|
||||||
TestCase.assertEqual(keys[index], index);
|
TestCase.assertEqual(keys[index], index);
|
||||||
}
|
}
|
||||||
|
@ -116,11 +151,16 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
TestCase.assertEqual(obj.arrayCol.length, 1);
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}],
|
||||||
|
});
|
||||||
|
|
||||||
array = obj.arrayCol;
|
array = obj.arrayCol;
|
||||||
TestCase.assertEqual(array.push([4]), 2);
|
TestCase.assertEqual(array.length, 1);
|
||||||
|
|
||||||
|
TestCase.assertEqual(array.push({doubleCol: 4}), 2);
|
||||||
TestCase.assertEqual(array.length, 2);
|
TestCase.assertEqual(array.length, 2);
|
||||||
TestCase.assertEqual(array[1].doubleCol, 4);
|
TestCase.assertEqual(array[1].doubleCol, 4);
|
||||||
|
|
||||||
|
@ -145,9 +185,13 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
array = obj.arrayCol;
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}, {doubleCol: 4}],
|
||||||
|
});
|
||||||
|
|
||||||
|
array = obj.arrayCol;
|
||||||
TestCase.assertEqual(array.pop().doubleCol, 4);
|
TestCase.assertEqual(array.pop().doubleCol, 4);
|
||||||
TestCase.assertEqual(array.pop().doubleCol, 3);
|
TestCase.assertEqual(array.pop().doubleCol, 3);
|
||||||
TestCase.assertEqual(array.length, 0);
|
TestCase.assertEqual(array.length, 0);
|
||||||
|
@ -169,11 +213,16 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
TestCase.assertEqual(obj.arrayCol.length, 1);
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}],
|
||||||
|
});
|
||||||
|
|
||||||
array = obj.arrayCol;
|
array = obj.arrayCol;
|
||||||
TestCase.assertEqual(array.unshift([5]), 2);
|
TestCase.assertEqual(array.length, 1);
|
||||||
|
|
||||||
|
TestCase.assertEqual(array.unshift({doubleCol: 5}), 2);
|
||||||
TestCase.assertEqual(array.length, 2);
|
TestCase.assertEqual(array.length, 2);
|
||||||
TestCase.assertEqual(array[0].doubleCol, 5);
|
TestCase.assertEqual(array[0].doubleCol, 5);
|
||||||
|
|
||||||
|
@ -185,7 +234,7 @@ module.exports = BaseTest.extend({
|
||||||
|
|
||||||
TestCase.assertEqual(array.length, 4);
|
TestCase.assertEqual(array.length, 4);
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
array.unshift([1]);
|
array.unshift({doubleCol: 1});
|
||||||
}, 'can only unshift in a write transaction');
|
}, 'can only unshift in a write transaction');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -194,9 +243,13 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
array = obj.arrayCol;
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}, {doubleCol: 4}],
|
||||||
|
});
|
||||||
|
|
||||||
|
array = obj.arrayCol;
|
||||||
TestCase.assertEqual(array.shift().doubleCol, 3);
|
TestCase.assertEqual(array.shift().doubleCol, 3);
|
||||||
TestCase.assertEqual(array.shift().doubleCol, 4);
|
TestCase.assertEqual(array.shift().doubleCol, 4);
|
||||||
TestCase.assertEqual(array.length, 0);
|
TestCase.assertEqual(array.length, 0);
|
||||||
|
@ -218,10 +271,14 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
var removed;
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}, {doubleCol: 4}],
|
||||||
|
});
|
||||||
|
|
||||||
array = obj.arrayCol;
|
array = obj.arrayCol;
|
||||||
|
var removed;
|
||||||
|
|
||||||
removed = array.splice(0, 0, obj.objectCol, obj.objectCol1);
|
removed = array.splice(0, 0, obj.objectCol, obj.objectCol1);
|
||||||
TestCase.assertEqual(removed.length, 0);
|
TestCase.assertEqual(removed.length, 0);
|
||||||
|
@ -229,7 +286,7 @@ module.exports = BaseTest.extend({
|
||||||
TestCase.assertEqual(array[0].doubleCol, 1);
|
TestCase.assertEqual(array[0].doubleCol, 1);
|
||||||
TestCase.assertEqual(array[1].doubleCol, 2);
|
TestCase.assertEqual(array[1].doubleCol, 2);
|
||||||
|
|
||||||
removed = array.splice(2, 2, [5], [6]);
|
removed = array.splice(2, 2, {doubleCol: 5}, {doubleCol: 6});
|
||||||
TestCase.assertEqual(removed.length, 2);
|
TestCase.assertEqual(removed.length, 2);
|
||||||
TestCase.assertEqual(removed[0].doubleCol, 3);
|
TestCase.assertEqual(removed[0].doubleCol, 3);
|
||||||
TestCase.assertEqual(removed[1].doubleCol, 4);
|
TestCase.assertEqual(removed[1].doubleCol, 4);
|
||||||
|
@ -270,7 +327,7 @@ module.exports = BaseTest.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
array.splice(0, 0, [1]);
|
array.splice(0, 0, {doubleCol: 1});
|
||||||
}, 'can only splice in a write transaction');
|
}, 'can only splice in a write transaction');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -280,7 +337,12 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
object = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
|
object = realm.create('LinkTypesObject', {
|
||||||
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}, {doubleCol: 4}],
|
||||||
|
});
|
||||||
|
|
||||||
array = object.arrayCol;
|
array = object.arrayCol;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -313,21 +375,27 @@ module.exports = BaseTest.extend({
|
||||||
var array;
|
var array;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
|
var obj = realm.create('LinkTypesObject', {
|
||||||
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: {doubleCol: 2},
|
||||||
|
arrayCol: [{doubleCol: 3}, {doubleCol: 4}],
|
||||||
|
});
|
||||||
|
|
||||||
array = obj.arrayCol;
|
array = obj.arrayCol;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TestCase.assertEqual(array.length, 2);
|
||||||
TestCase.assertEqual(objects.length, 4);
|
TestCase.assertEqual(objects.length, 4);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
array.push([5]);
|
array.push({doubleCol: 5});
|
||||||
TestCase.assertEqual(objects.length, 5);
|
TestCase.assertEqual(objects.length, 5);
|
||||||
|
|
||||||
array.unshift([2]);
|
array.unshift({doubleCol: 2});
|
||||||
TestCase.assertEqual(objects.length, 6);
|
TestCase.assertEqual(objects.length, 6);
|
||||||
|
|
||||||
array.splice(0, 0, [1]);
|
array.splice(0, 0, {doubleCol: 1});
|
||||||
TestCase.assertEqual(objects.length, 7);
|
TestCase.assertEqual(objects.length, 7);
|
||||||
|
|
||||||
array.push(objects[0], objects[1]);
|
array.push(objects[0], objects[1]);
|
||||||
|
|
|
@ -16,67 +16,105 @@ var RANDOM_DATA = new Uint8Array([
|
||||||
|
|
||||||
module.exports = BaseTest.extend({
|
module.exports = BaseTest.extend({
|
||||||
testBasicTypesPropertyGetters: function() {
|
testBasicTypesPropertyGetters: function() {
|
||||||
var basicTypesValues = [true, 1, 1.1, 1.11, 'string', new Date(1), RANDOM_DATA];
|
|
||||||
var realm = new Realm({schema: [schemas.BasicTypes]});
|
var realm = new Realm({schema: [schemas.BasicTypes]});
|
||||||
var object;
|
var object;
|
||||||
|
|
||||||
|
var basicTypesValues = {
|
||||||
|
boolCol: true,
|
||||||
|
intCol: 1,
|
||||||
|
floatCol: 1.1,
|
||||||
|
doubleCol: 1.11,
|
||||||
|
stringCol: 'string',
|
||||||
|
dateCol: new Date(1),
|
||||||
|
dataCol: RANDOM_DATA,
|
||||||
|
};
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
object = realm.create('BasicTypesObject', basicTypesValues);
|
object = realm.create('BasicTypesObject', basicTypesValues);
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var i = 0; i < schemas.BasicTypes.properties.length; i++) {
|
for (var name in schemas.BasicTypes.properties) {
|
||||||
var prop = schemas.BasicTypes.properties[i];
|
var prop = schemas.BasicTypes.properties[name];
|
||||||
if (prop.type == Realm.Types.FLOAT) {
|
var type = typeof prop == 'object' ? prop.type : prop;
|
||||||
TestCase.assertEqualWithTolerance(object[prop.name], basicTypesValues[i], 0.000001);
|
|
||||||
|
if (type == Realm.Types.FLOAT || type == Realm.Types.DOUBLE) {
|
||||||
|
TestCase.assertEqualWithTolerance(object[name], basicTypesValues[name], 0.000001);
|
||||||
}
|
}
|
||||||
else if (prop.type == Realm.Types.DATA) {
|
else if (type == Realm.Types.DATA) {
|
||||||
TestCase.assertArraysEqual(new Uint8Array(object[prop.name]), RANDOM_DATA);
|
TestCase.assertArraysEqual(new Uint8Array(object[name]), RANDOM_DATA);
|
||||||
}
|
}
|
||||||
else if (prop.type == Realm.Types.DATE) {
|
else if (type == Realm.Types.DATE) {
|
||||||
TestCase.assertEqual(object[prop.name].getTime(), basicTypesValues[i].getTime());
|
TestCase.assertEqual(object[name].getTime(), basicTypesValues[name].getTime());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TestCase.assertEqual(object[prop.name], basicTypesValues[i]);
|
TestCase.assertEqual(object[name], basicTypesValues[name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestCase.assertEqual(object.nonexistent, undefined);
|
TestCase.assertEqual(object.nonexistent, undefined);
|
||||||
},
|
},
|
||||||
testNullableBasicTypesPropertyGetters: function() {
|
testNullableBasicTypesPropertyGetters: function() {
|
||||||
var nullValues = [null, null, null, null, null, null, null];
|
|
||||||
var basicTypesValues = [true, 1, 1.1, 1.11, 'string', new Date(1), RANDOM_DATA];
|
|
||||||
|
|
||||||
var realm = new Realm({schema: [schemas.NullableBasicTypes]});
|
var realm = new Realm({schema: [schemas.NullableBasicTypes]});
|
||||||
var nullObject = null;
|
var object, nullObject;
|
||||||
var object = null;
|
|
||||||
|
var basicTypesValues = {
|
||||||
|
boolCol: true,
|
||||||
|
intCol: 1,
|
||||||
|
floatCol: 1.1,
|
||||||
|
doubleCol: 1.11,
|
||||||
|
stringCol: 'string',
|
||||||
|
dateCol: new Date(1),
|
||||||
|
dataCol: RANDOM_DATA,
|
||||||
|
};
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
nullObject = realm.create('NullableBasicTypesObject', nullValues);
|
|
||||||
object = realm.create('NullableBasicTypesObject', basicTypesValues);
|
object = realm.create('NullableBasicTypesObject', basicTypesValues);
|
||||||
|
|
||||||
|
nullObject = realm.create('NullableBasicTypesObject', {
|
||||||
|
boolCol: null,
|
||||||
|
intCol: null,
|
||||||
|
floatCol: null,
|
||||||
|
doubleCol: null,
|
||||||
|
stringCol: null,
|
||||||
|
dateCol: null,
|
||||||
|
dataCol: null,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var i = 0; i < schemas.BasicTypes.properties.length; i++) {
|
for (var name in schemas.BasicTypes.properties) {
|
||||||
var prop = schemas.BasicTypes.properties[i];
|
var prop = schemas.BasicTypes.properties[name];
|
||||||
TestCase.assertEqual(nullObject[prop.name], null);
|
var type = typeof prop == 'object' ? prop.type : prop;
|
||||||
|
|
||||||
if (prop.type == Realm.Types.FLOAT) {
|
TestCase.assertEqual(nullObject[name], null);
|
||||||
TestCase.assertEqualWithTolerance(object[prop.name], basicTypesValues[i], 0.000001);
|
|
||||||
|
if (type == Realm.Types.FLOAT || type == Realm.Types.DOUBLE) {
|
||||||
|
TestCase.assertEqualWithTolerance(object[name], basicTypesValues[name], 0.000001);
|
||||||
}
|
}
|
||||||
else if (prop.type == Realm.Types.DATA) {
|
else if (type == Realm.Types.DATA) {
|
||||||
TestCase.assertArraysEqual(new Uint8Array(object[prop.name]), RANDOM_DATA);
|
TestCase.assertArraysEqual(new Uint8Array(object[name]), RANDOM_DATA);
|
||||||
}
|
}
|
||||||
else if (prop.type == Realm.Types.DATE) {
|
else if (type == Realm.Types.DATE) {
|
||||||
TestCase.assertEqual(object[prop.name].getTime(), basicTypesValues[i].getTime());
|
TestCase.assertEqual(object[name].getTime(), basicTypesValues[name].getTime());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TestCase.assertEqual(object[prop.name], basicTypesValues[i]);
|
TestCase.assertEqual(object[name], basicTypesValues[name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
testBasicTypesPropertySetters: function() {
|
testBasicTypesPropertySetters: function() {
|
||||||
var basicTypesValues = [true, 1, 1.1, 1.11, 'string', new Date(1), new ArrayBuffer()];
|
|
||||||
var realm = new Realm({schema: [schemas.BasicTypes]});
|
var realm = new Realm({schema: [schemas.BasicTypes]});
|
||||||
var obj = null;
|
var obj;
|
||||||
|
|
||||||
|
var basicTypesValues = {
|
||||||
|
boolCol: true,
|
||||||
|
intCol: 1,
|
||||||
|
floatCol: 1.1,
|
||||||
|
doubleCol: 1.11,
|
||||||
|
stringCol: 'string',
|
||||||
|
dateCol: new Date(1),
|
||||||
|
dataCol: new ArrayBuffer(),
|
||||||
|
};
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
obj = realm.create('BasicTypesObject', basicTypesValues);
|
obj = realm.create('BasicTypesObject', basicTypesValues);
|
||||||
|
@ -92,7 +130,7 @@ module.exports = BaseTest.extend({
|
||||||
TestCase.assertEqual(obj.boolCol, false, 'wrong bool value');
|
TestCase.assertEqual(obj.boolCol, false, 'wrong bool value');
|
||||||
TestCase.assertEqual(obj.intCol, 2, 'wrong int value');
|
TestCase.assertEqual(obj.intCol, 2, 'wrong int value');
|
||||||
TestCase.assertEqualWithTolerance(obj.floatCol, 2.2, 0.000001, 'wrong float value');
|
TestCase.assertEqualWithTolerance(obj.floatCol, 2.2, 0.000001, 'wrong float value');
|
||||||
TestCase.assertEqual(obj.doubleCol, 2.22, 'wrong double value');
|
TestCase.assertEqualWithTolerance(obj.doubleCol, 2.22, 0.000001, 'wrong double value');
|
||||||
TestCase.assertEqual(obj.stringCol, 'STRING', 'wrong string value');
|
TestCase.assertEqual(obj.stringCol, 'STRING', 'wrong string value');
|
||||||
TestCase.assertEqual(obj.dateCol.getTime(), 2, 'wrong date value');
|
TestCase.assertEqual(obj.dateCol.getTime(), 2, 'wrong date value');
|
||||||
TestCase.assertArraysEqual(new Uint8Array(obj.dataCol), RANDOM_DATA, 'wrong data value');
|
TestCase.assertArraysEqual(new Uint8Array(obj.dataCol), RANDOM_DATA, 'wrong data value');
|
||||||
|
@ -156,24 +194,32 @@ module.exports = BaseTest.extend({
|
||||||
TestCase.assertEqual(obj.boolCol, false, 'bool value changed outside transaction');
|
TestCase.assertEqual(obj.boolCol, false, 'bool value changed outside transaction');
|
||||||
},
|
},
|
||||||
testNullableBasicTypesPropertySetters: function() {
|
testNullableBasicTypesPropertySetters: function() {
|
||||||
var basicTypesValues = [true, 1, 1.1, 1.11, 'string', new Date(1), RANDOM_DATA];
|
|
||||||
var realm = new Realm({schema: [schemas.NullableBasicTypes]});
|
var realm = new Realm({schema: [schemas.NullableBasicTypes]});
|
||||||
var obj, obj1;
|
var obj, obj1;
|
||||||
|
|
||||||
|
var basicTypesValues = {
|
||||||
|
boolCol: true,
|
||||||
|
intCol: 1,
|
||||||
|
floatCol: 1.1,
|
||||||
|
doubleCol: 1.11,
|
||||||
|
stringCol: 'string',
|
||||||
|
dateCol: new Date(1),
|
||||||
|
dataCol: RANDOM_DATA,
|
||||||
|
};
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
obj = realm.create('NullableBasicTypesObject', basicTypesValues);
|
obj = realm.create('NullableBasicTypesObject', basicTypesValues);
|
||||||
obj1 = realm.create('NullableBasicTypesObject', basicTypesValues);
|
obj1 = realm.create('NullableBasicTypesObject', basicTypesValues);
|
||||||
for (var index in schemas.NullableBasicTypes.properties) {
|
|
||||||
var prop = schemas.NullableBasicTypes.properties[index];
|
for (var name in schemas.NullableBasicTypes.properties) {
|
||||||
obj[prop.name] = null;
|
obj[name] = null;
|
||||||
obj1[prop.name] = undefined;
|
obj1[name] = undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var index in schemas.NullableBasicTypes.properties) {
|
for (var name in schemas.NullableBasicTypes.properties) {
|
||||||
var prop = schemas.NullableBasicTypes.properties[index];
|
TestCase.assertEqual(obj[name], null);
|
||||||
TestCase.assertEqual(obj[prop.name], null);
|
TestCase.assertEqual(obj1[name], null);
|
||||||
TestCase.assertEqual(obj1[prop.name], null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
|
@ -192,8 +238,13 @@ module.exports = BaseTest.extend({
|
||||||
testLinkTypesPropertyGetters: function() {
|
testLinkTypesPropertyGetters: function() {
|
||||||
var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]});
|
||||||
var obj = null;
|
var obj = null;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
obj = realm.create('LinkTypesObject', [[1], null, [[3]]]);
|
obj = realm.create('LinkTypesObject', {
|
||||||
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: null,
|
||||||
|
arrayCol: [{doubleCol: 3}],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var objVal = obj.objectCol;
|
var objVal = obj.objectCol;
|
||||||
|
@ -212,11 +263,16 @@ module.exports = BaseTest.extend({
|
||||||
testLinkTypesPropertySetters: function() {
|
testLinkTypesPropertySetters: function() {
|
||||||
var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]});
|
||||||
var objects = realm.objects('TestObject');
|
var objects = realm.objects('TestObject');
|
||||||
var obj = null;
|
var obj;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
obj = realm.create('LinkTypesObject', [[1], null, [[3]]]);
|
obj = realm.create('LinkTypesObject', {
|
||||||
|
objectCol: {doubleCol: 1},
|
||||||
|
objectCol1: null,
|
||||||
|
arrayCol: [{doubleCol: 3}],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
TestCase.assertEqual(objects.length, 2);
|
TestCase.assertEqual(objects.length, 2);
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
|
@ -240,15 +296,20 @@ module.exports = BaseTest.extend({
|
||||||
|
|
||||||
// set object as JSON
|
// set object as JSON
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
obj.objectCol = { doubleCol: 1 };
|
obj.objectCol = {doubleCol: 1};
|
||||||
});
|
});
|
||||||
TestCase.assertEqual(obj.objectCol.doubleCol, 1);
|
TestCase.assertEqual(obj.objectCol.doubleCol, 1);
|
||||||
TestCase.assertEqual(objects.length, 3);
|
TestCase.assertEqual(objects.length, 3);
|
||||||
|
|
||||||
// set array property
|
// set array property
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
obj.arrayCol = [obj.arrayCol[0], obj.objectCol, realm.create('TestObject', [2])];
|
obj.arrayCol = [
|
||||||
|
obj.arrayCol[0],
|
||||||
|
obj.objectCol,
|
||||||
|
realm.create('TestObject', {doubleCol: 2}),
|
||||||
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
TestCase.assertEqual(objects.length, 4);
|
TestCase.assertEqual(objects.length, 4);
|
||||||
TestCase.assertEqual(obj.arrayCol.length, 3);
|
TestCase.assertEqual(obj.arrayCol.length, 3);
|
||||||
TestCase.assertEqual(obj.arrayCol[0].doubleCol, 3);
|
TestCase.assertEqual(obj.arrayCol[0].doubleCol, 3);
|
||||||
|
@ -256,15 +317,22 @@ module.exports = BaseTest.extend({
|
||||||
TestCase.assertEqual(obj.arrayCol[2].doubleCol, 2);
|
TestCase.assertEqual(obj.arrayCol[2].doubleCol, 2);
|
||||||
},
|
},
|
||||||
testEnumerablePropertyNames: function() {
|
testEnumerablePropertyNames: function() {
|
||||||
var basicTypesValues = [true, 1, 1.1, 1.11, 'string', new Date(1), new ArrayBuffer()];
|
|
||||||
var realm = new Realm({schema: [schemas.BasicTypes]});
|
var realm = new Realm({schema: [schemas.BasicTypes]});
|
||||||
var object;
|
var object;
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
object = realm.create('BasicTypesObject', basicTypesValues);
|
object = realm.create('BasicTypesObject', {
|
||||||
|
boolCol: true,
|
||||||
|
intCol: 1,
|
||||||
|
floatCol: 1.1,
|
||||||
|
doubleCol: 1.11,
|
||||||
|
stringCol: 'string',
|
||||||
|
dateCol: new Date(1),
|
||||||
|
dataCol: RANDOM_DATA,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var propNames = schemas.BasicTypes.properties.map(function(prop) { return prop.name; });
|
var propNames = Object.keys(schemas.BasicTypes.properties);
|
||||||
TestCase.assertArraysEqual(Object.keys(object), propNames, 'Object.keys');
|
TestCase.assertArraysEqual(Object.keys(object), propNames, 'Object.keys');
|
||||||
|
|
||||||
for (var key in object) {
|
for (var key in object) {
|
||||||
|
|
|
@ -12,8 +12,12 @@ var util = require('./util');
|
||||||
|
|
||||||
module.exports = BaseTest.extend({
|
module.exports = BaseTest.extend({
|
||||||
testRealmConstructorPath: function() {
|
testRealmConstructorPath: function() {
|
||||||
TestCase.assertThrows(function() { new Realm('/invalidpath'); });
|
TestCase.assertThrows(function() {
|
||||||
TestCase.assertThrows(function() { new Realm(util.realmPathForFile('test1.realm'), 'invalidArgument'); });
|
new Realm('/invalidpath');
|
||||||
|
}, 'Realm cannot be created with an invalid path');
|
||||||
|
TestCase.assertThrows(function() {
|
||||||
|
new Realm(util.realmPathForFile('test1.realm'), 'invalidArgument');
|
||||||
|
}, 'Realm constructor can only have 0 or 1 argument(s)');
|
||||||
|
|
||||||
var defaultRealm = new Realm({schema: []});
|
var defaultRealm = new Realm({schema: []});
|
||||||
TestCase.assertEqual(defaultRealm.path, Realm.defaultPath);
|
TestCase.assertEqual(defaultRealm.path, Realm.defaultPath);
|
||||||
|
@ -57,11 +61,33 @@ module.exports = BaseTest.extend({
|
||||||
|
|
||||||
realm = new Realm({path: testPath, schema: [schemas.TestObject], schemaVersion: 2});
|
realm = new Realm({path: testPath, schema: [schemas.TestObject], schemaVersion: 2});
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
realm.create('TestObject', [1]);
|
realm.create('TestObject', {doubleCol: 1});
|
||||||
});
|
});
|
||||||
TestCase.assertEqual(realm.objects('TestObject')[0].doubleCol, 1)
|
TestCase.assertEqual(realm.objects('TestObject')[0].doubleCol, 1)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
testRealmConstructorSchemaValidation: function() {
|
||||||
|
TestCase.assertThrows(function() {
|
||||||
|
new Realm({schema: schemas.AllTypes});
|
||||||
|
}, 'The schema should be an array');
|
||||||
|
|
||||||
|
TestCase.assertThrows(function() {
|
||||||
|
new Realm({schema: ['SomeType']});
|
||||||
|
}, 'The schema should be an array of objects');
|
||||||
|
|
||||||
|
TestCase.assertThrows(function() {
|
||||||
|
new Realm({schema: [{}]});
|
||||||
|
}, 'The schema should be an array of ObjectSchema objects');
|
||||||
|
|
||||||
|
TestCase.assertThrows(function() {
|
||||||
|
new Realm({schema: [{name: 'SomeObject'}]});
|
||||||
|
}, 'The schema should be an array of ObjectSchema objects');
|
||||||
|
|
||||||
|
TestCase.assertThrows(function() {
|
||||||
|
new Realm({schema: [{properties: {intCol: Realm.Types.INT}}]});
|
||||||
|
}, 'The schema should be an array of ObjectSchema objects');
|
||||||
|
},
|
||||||
|
|
||||||
testDefaultPath: function() {
|
testDefaultPath: function() {
|
||||||
var defaultRealm = new Realm({schema: []});
|
var defaultRealm = new Realm({schema: []});
|
||||||
TestCase.assertEqual(defaultRealm.path, Realm.defaultPath);
|
TestCase.assertEqual(defaultRealm.path, Realm.defaultPath);
|
||||||
|
@ -77,12 +103,12 @@ module.exports = BaseTest.extend({
|
||||||
var realm = new Realm({schema: [schemas.IntPrimary, schemas.AllTypes, schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.IntPrimary, schemas.AllTypes, schemas.TestObject]});
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
realm.create('TestObject', [1]);
|
realm.create('TestObject', {doubleCol: 1});
|
||||||
}, 'can only create inside a write transaction');
|
}, 'can only create inside a write transaction');
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
realm.create('TestObject', [1]);
|
realm.create('TestObject', {doubleCol: 1});
|
||||||
realm.create('TestObject', {'doubleCol': 2});
|
realm.create('TestObject', {doubleCol: 2});
|
||||||
});
|
});
|
||||||
|
|
||||||
var objects = realm.objects('TestObject');
|
var objects = realm.objects('TestObject');
|
||||||
|
@ -92,16 +118,31 @@ module.exports = BaseTest.extend({
|
||||||
|
|
||||||
// test int primary object
|
// test int primary object
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj0 = realm.create('IntPrimaryObject', [0, 'val0']);
|
var obj0 = realm.create('IntPrimaryObject', {
|
||||||
|
primaryCol: 0,
|
||||||
|
valueCol: 'val0',
|
||||||
|
});
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
realm.create('IntPrimaryObject', [0, 'val0']);
|
realm.create('IntPrimaryObject', {
|
||||||
});
|
primaryCol: 0,
|
||||||
realm.create('IntPrimaryObject', [1, 'val1'], true);
|
valueCol: 'val0',
|
||||||
|
});
|
||||||
|
}, 'cannot create object with conflicting primary key');
|
||||||
|
|
||||||
|
realm.create('IntPrimaryObject', {
|
||||||
|
primaryCol: 1,
|
||||||
|
valueCol: 'val1',
|
||||||
|
}, true);
|
||||||
|
|
||||||
var objects = realm.objects('IntPrimaryObject');
|
var objects = realm.objects('IntPrimaryObject');
|
||||||
TestCase.assertEqual(objects.length, 2);
|
TestCase.assertEqual(objects.length, 2);
|
||||||
|
|
||||||
realm.create('IntPrimaryObject', [0, 'newVal0'], true);
|
realm.create('IntPrimaryObject', {
|
||||||
|
primaryCol: 0,
|
||||||
|
valueCol: 'newVal0',
|
||||||
|
}, true);
|
||||||
|
|
||||||
TestCase.assertEqual(obj0.valueCol, 'newVal0');
|
TestCase.assertEqual(obj0.valueCol, 'newVal0');
|
||||||
TestCase.assertEqual(objects.length, 2);
|
TestCase.assertEqual(objects.length, 2);
|
||||||
|
|
||||||
|
@ -111,47 +152,89 @@ module.exports = BaseTest.extend({
|
||||||
|
|
||||||
// test upsert with all type and string primary object
|
// test upsert with all type and string primary object
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var values = ['0', true, 1, 1.1, 1.11, '1', new Date(1), new ArrayBuffer(1), [1], []];
|
var values = {
|
||||||
|
primaryCol: '0',
|
||||||
|
boolCol: true,
|
||||||
|
intCol: 1,
|
||||||
|
floatCol: 1.1,
|
||||||
|
doubleCol: 1.11,
|
||||||
|
stringCol: '1',
|
||||||
|
dateCol: new Date(1),
|
||||||
|
dataCol: new ArrayBuffer(1),
|
||||||
|
objectCol: {doubleCol: 1},
|
||||||
|
arrayCol: [],
|
||||||
|
};
|
||||||
|
|
||||||
var obj0 = realm.create('AllTypesObject', values);
|
var obj0 = realm.create('AllTypesObject', values);
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
realm.create('AllTypesObject', values);
|
realm.create('AllTypesObject', values);
|
||||||
});
|
}, 'cannot create object with conflicting primary key');
|
||||||
var obj1 = realm.create('AllTypesObject', ['1', false, 2, 2.2, 2.11, '2', new Date(2), new ArrayBuffer(2), [0], [[2]]], true);
|
|
||||||
|
var obj1 = realm.create('AllTypesObject', {
|
||||||
|
primaryCol: '1',
|
||||||
|
boolCol: false,
|
||||||
|
intCol: 2,
|
||||||
|
floatCol: 2.2,
|
||||||
|
doubleCol: 2.22,
|
||||||
|
stringCol: '2',
|
||||||
|
dateCol: new Date(2),
|
||||||
|
dataCol: new ArrayBuffer(2),
|
||||||
|
objectCol: {doubleCol: 0},
|
||||||
|
arrayCol: [{doubleCol: 2}],
|
||||||
|
}, true);
|
||||||
|
|
||||||
var objects = realm.objects('AllTypesObject');
|
var objects = realm.objects('AllTypesObject');
|
||||||
TestCase.assertEqual(objects.length, 2);
|
TestCase.assertEqual(objects.length, 2);
|
||||||
|
|
||||||
realm.create('AllTypesObject', ['0', false, 2, 2.2, 2.22, '2', new Date(2), new ArrayBuffer(2), null, [[2]]], true);
|
realm.create('AllTypesObject', {
|
||||||
|
primaryCol: '0',
|
||||||
|
boolCol: false,
|
||||||
|
intCol: 2,
|
||||||
|
floatCol: 2.2,
|
||||||
|
doubleCol: 2.22,
|
||||||
|
stringCol: '2',
|
||||||
|
dateCol: new Date(2),
|
||||||
|
dataCol: new ArrayBuffer(2),
|
||||||
|
objectCol: null,
|
||||||
|
arrayCol: [{doubleCol: 2}],
|
||||||
|
}, true);
|
||||||
|
|
||||||
TestCase.assertEqual(objects.length, 2);
|
TestCase.assertEqual(objects.length, 2);
|
||||||
TestCase.assertEqual(obj0.stringCol, '2');
|
TestCase.assertEqual(obj0.stringCol, '2');
|
||||||
TestCase.assertEqual(obj0.boolCol, false);
|
TestCase.assertEqual(obj0.boolCol, false);
|
||||||
TestCase.assertEqual(obj0.intCol, 2);
|
TestCase.assertEqual(obj0.intCol, 2);
|
||||||
TestCase.assertEqualWithTolerance(obj0.floatCol, 2.2, 0.000001);
|
TestCase.assertEqualWithTolerance(obj0.floatCol, 2.2, 0.000001);
|
||||||
TestCase.assertEqual(obj0.doubleCol, 2.22);
|
TestCase.assertEqualWithTolerance(obj0.doubleCol, 2.22, 0.000001);
|
||||||
TestCase.assertEqual(obj0.dateCol.getTime(), 2);
|
TestCase.assertEqual(obj0.dateCol.getTime(), 2);
|
||||||
TestCase.assertEqual(obj0.dataCol.byteLength, 2);
|
TestCase.assertEqual(obj0.dataCol.byteLength, 2);
|
||||||
TestCase.assertEqual(obj0.objectCol, null);
|
TestCase.assertEqual(obj0.objectCol, null);
|
||||||
TestCase.assertEqual(obj0.arrayCol.length, 1);
|
TestCase.assertEqual(obj0.arrayCol.length, 1);
|
||||||
|
|
||||||
realm.create('AllTypesObject', { primaryCol: '0' }, true);
|
realm.create('AllTypesObject', {primaryCol: '0'}, true);
|
||||||
realm.create('AllTypesObject', { primaryCol: '1' }, true);
|
realm.create('AllTypesObject', {primaryCol: '1'}, true);
|
||||||
TestCase.assertEqual(obj0.stringCol, '2');
|
TestCase.assertEqual(obj0.stringCol, '2');
|
||||||
TestCase.assertEqual(obj0.objectCol, null);
|
TestCase.assertEqual(obj0.objectCol, null);
|
||||||
TestCase.assertEqual(obj1.objectCol.doubleCol, 0);
|
TestCase.assertEqual(obj1.objectCol.doubleCol, 0);
|
||||||
|
|
||||||
realm.create('AllTypesObject', { primaryCol: '0', stringCol: '3', objectCol: [0] }, true);
|
realm.create('AllTypesObject', {
|
||||||
|
primaryCol: '0',
|
||||||
|
stringCol: '3',
|
||||||
|
objectCol: {doubleCol: 0},
|
||||||
|
}, true);
|
||||||
|
|
||||||
TestCase.assertEqual(obj0.stringCol, '3');
|
TestCase.assertEqual(obj0.stringCol, '3');
|
||||||
TestCase.assertEqual(obj0.boolCol, false);
|
TestCase.assertEqual(obj0.boolCol, false);
|
||||||
TestCase.assertEqual(obj0.intCol, 2);
|
TestCase.assertEqual(obj0.intCol, 2);
|
||||||
TestCase.assertEqualWithTolerance(obj0.floatCol, 2.2, 0.000001);
|
TestCase.assertEqualWithTolerance(obj0.floatCol, 2.2, 0.000001);
|
||||||
TestCase.assertEqual(obj0.doubleCol, 2.22);
|
TestCase.assertEqualWithTolerance(obj0.doubleCol, 2.22, 0.000001);
|
||||||
TestCase.assertEqual(obj0.dateCol.getTime(), 2);
|
TestCase.assertEqual(obj0.dateCol.getTime(), 2);
|
||||||
TestCase.assertEqual(obj0.dataCol.byteLength, 2);
|
TestCase.assertEqual(obj0.dataCol.byteLength, 2);
|
||||||
TestCase.assertEqual(obj0.objectCol.doubleCol, 0);
|
TestCase.assertEqual(obj0.objectCol.doubleCol, 0);
|
||||||
TestCase.assertEqual(obj0.arrayCol.length, 1);
|
TestCase.assertEqual(obj0.arrayCol.length, 1);
|
||||||
|
|
||||||
realm.create('AllTypesObject', { primaryCol: '0', objectCol: undefined }, true);
|
realm.create('AllTypesObject', {primaryCol: '0', objectCol: undefined}, true);
|
||||||
realm.create('AllTypesObject', { primaryCol: '1', objectCol: null }, true);
|
realm.create('AllTypesObject', {primaryCol: '1', objectCol: null}, true);
|
||||||
TestCase.assertEqual(obj0.objectCol, null);
|
TestCase.assertEqual(obj0.objectCol, null);
|
||||||
TestCase.assertEqual(obj1.objectCol, null);
|
TestCase.assertEqual(obj1.objectCol, null);
|
||||||
});
|
});
|
||||||
|
@ -159,27 +242,31 @@ module.exports = BaseTest.extend({
|
||||||
|
|
||||||
testRealmCreateWithDefaults: function() {
|
testRealmCreateWithDefaults: function() {
|
||||||
var realm = new Realm({schema: [schemas.DefaultValues, schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.DefaultValues, schemas.TestObject]});
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
var obj = realm.create('DefaultValuesObject', {});
|
var obj = realm.create('DefaultValuesObject', {});
|
||||||
TestCase.assertEqual(obj.boolCol, schemas.DefaultValues.properties[0].default);
|
var properties = schemas.DefaultValues.properties;
|
||||||
TestCase.assertEqual(obj.intCol, schemas.DefaultValues.properties[1].default);
|
|
||||||
TestCase.assertEqualWithTolerance(obj.floatCol, schemas.DefaultValues.properties[2].default, 0.000001);
|
TestCase.assertEqual(obj.boolCol, properties.boolCol.default);
|
||||||
TestCase.assertEqual(obj.doubleCol, schemas.DefaultValues.properties[3].default);
|
TestCase.assertEqual(obj.intCol, properties.intCol.default);
|
||||||
TestCase.assertEqual(obj.stringCol, schemas.DefaultValues.properties[4].default);
|
TestCase.assertEqualWithTolerance(obj.floatCol, properties.floatCol.default, 0.000001);
|
||||||
TestCase.assertEqual(obj.dateCol.getTime(), schemas.DefaultValues.properties[5].default.getTime());
|
TestCase.assertEqualWithTolerance(obj.doubleCol, properties.doubleCol.default, 0.000001);
|
||||||
TestCase.assertEqual(obj.dataCol.byteLength, schemas.DefaultValues.properties[6].default.byteLength);
|
TestCase.assertEqual(obj.stringCol, properties.stringCol.default);
|
||||||
TestCase.assertEqual(obj.objectCol.doubleCol, schemas.DefaultValues.properties[7].default[0]);
|
TestCase.assertEqual(obj.dateCol.getTime(), properties.dateCol.default.getTime());
|
||||||
|
TestCase.assertEqual(obj.dataCol.byteLength, properties.dataCol.default.byteLength);
|
||||||
|
TestCase.assertEqual(obj.objectCol.doubleCol, properties.objectCol.default.doubleCol);
|
||||||
TestCase.assertEqual(obj.nullObjectCol, null);
|
TestCase.assertEqual(obj.nullObjectCol, null);
|
||||||
TestCase.assertEqual(obj.arrayCol.length, schemas.DefaultValues.properties[9].default.length);
|
TestCase.assertEqual(obj.arrayCol.length, properties.arrayCol.default.length);
|
||||||
TestCase.assertEqual(obj.arrayCol[0].doubleCol, schemas.DefaultValues.properties[9].default[0][0]);
|
TestCase.assertEqual(obj.arrayCol[0].doubleCol, properties.arrayCol.default[0].doubleCol);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
testRealmDelete: function() {
|
testRealmDelete: function() {
|
||||||
var realm = new Realm({schema: [schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.TestObject]});
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
for (var i = 0; i < 10; i++) {
|
for (var i = 0; i < 10; i++) {
|
||||||
realm.create('TestObject', [i]);
|
realm.create('TestObject', {doubleCol: i});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -213,11 +300,13 @@ module.exports = BaseTest.extend({
|
||||||
|
|
||||||
testDeleteAll: function() {
|
testDeleteAll: function() {
|
||||||
var realm = new Realm({schema: [schemas.TestObject, schemas.IntPrimary]});
|
var realm = new Realm({schema: [schemas.TestObject, schemas.IntPrimary]});
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
realm.create('TestObject', [1]);
|
realm.create('TestObject', {doubleCol: 1});
|
||||||
realm.create('TestObject', [2]);
|
realm.create('TestObject', {doubleCol: 2});
|
||||||
realm.create('IntPrimaryObject', [2, 'value']);
|
realm.create('IntPrimaryObject', {primaryCol: 2, valueCol: 'value'});
|
||||||
});
|
});
|
||||||
|
|
||||||
TestCase.assertEqual(realm.objects('TestObject').length, 2);
|
TestCase.assertEqual(realm.objects('TestObject').length, 2);
|
||||||
TestCase.assertEqual(realm.objects('IntPrimaryObject').length, 1);
|
TestCase.assertEqual(realm.objects('IntPrimaryObject').length, 1);
|
||||||
|
|
||||||
|
@ -236,10 +325,10 @@ module.exports = BaseTest.extend({
|
||||||
testRealmObjects: function() {
|
testRealmObjects: function() {
|
||||||
var realm = new Realm({schema: [schemas.PersonObject, schemas.DefaultValues, schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.PersonObject, schemas.DefaultValues, schemas.TestObject]});
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
realm.create('PersonObject', ['Ari', 10, false]);
|
realm.create('PersonObject', {name: 'Ari', age: 10});
|
||||||
realm.create('PersonObject', ['Tim', 11, false]);
|
realm.create('PersonObject', {name: 'Tim', age: 11});
|
||||||
realm.create('PersonObject', {'name': 'Bjarne', 'age': 12});
|
realm.create('PersonObject', {name: 'Bjarne', age: 12});
|
||||||
realm.create('PersonObject', {'name': 'Alex', 'age': 12, 'married': true});
|
realm.create('PersonObject', {name: 'Alex', age: 12, married: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
|
|
|
@ -16,7 +16,7 @@ module.exports = BaseTest.extend({
|
||||||
TestCase.assertEqual(objects.length, 0);
|
TestCase.assertEqual(objects.length, 0);
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
realm.create('TestObject', [1]);
|
realm.create('TestObject', {doubleCol: 1});
|
||||||
TestCase.assertEqual(objects.length, 1);
|
TestCase.assertEqual(objects.length, 1);
|
||||||
});
|
});
|
||||||
TestCase.assertEqual(objects.length, 1);
|
TestCase.assertEqual(objects.length, 1);
|
||||||
|
@ -24,8 +24,8 @@ module.exports = BaseTest.extend({
|
||||||
testResultsSubscript: function() {
|
testResultsSubscript: function() {
|
||||||
var realm = new Realm({schema: [schemas.PersonObject]});
|
var realm = new Realm({schema: [schemas.PersonObject]});
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
realm.create('PersonObject', ['name1', 1, false]);
|
realm.create('PersonObject', {name: 'name1', age: 1});
|
||||||
realm.create('PersonObject', ['name2', 2, false]);
|
realm.create('PersonObject', {name: 'name2', age: 2});
|
||||||
});
|
});
|
||||||
|
|
||||||
var people = realm.objects('PersonObject');
|
var people = realm.objects('PersonObject');
|
||||||
|
@ -41,17 +41,17 @@ module.exports = BaseTest.extend({
|
||||||
var objects = realm.objects('TestObject');
|
var objects = realm.objects('TestObject');
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
realm.create('TestObject', [1]);
|
realm.create('TestObject', {doubleCol: 1});
|
||||||
});
|
});
|
||||||
|
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
objects[-1] = [0];
|
objects[-1] = {doubleCol: 0};
|
||||||
});
|
});
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
objects[0] = [0];
|
objects[0] = {doubleCol: 0};
|
||||||
});
|
});
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
objects[1] = [0];
|
objects[1] = {doubleCol: 0};
|
||||||
});
|
});
|
||||||
TestCase.assertThrows(function() {
|
TestCase.assertThrows(function() {
|
||||||
objects.length = 0;
|
objects.length = 0;
|
||||||
|
@ -71,12 +71,13 @@ module.exports = BaseTest.extend({
|
||||||
testResultsEnumerate: function() {
|
testResultsEnumerate: function() {
|
||||||
var realm = new Realm({schema: [schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.TestObject]});
|
||||||
var objects = realm.objects('TestObject');
|
var objects = realm.objects('TestObject');
|
||||||
for (var object in objects) {
|
|
||||||
|
for (var index in objects) {
|
||||||
TestCase.assertTrue(false, "No objects should have been enumerated");
|
TestCase.assertTrue(false, "No objects should have been enumerated");
|
||||||
}
|
}
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
realm.create('TestObject', [1]);
|
realm.create('TestObject', {doubleCol: 1});
|
||||||
TestCase.assertEqual(objects.length, 1);
|
TestCase.assertEqual(objects.length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,12 +94,13 @@ module.exports = BaseTest.extend({
|
||||||
testSort: function() {
|
testSort: function() {
|
||||||
var realm = new Realm({schema: [schemas.TestObject]});
|
var realm = new Realm({schema: [schemas.TestObject]});
|
||||||
var objects = realm.objects('TestObject');
|
var objects = realm.objects('TestObject');
|
||||||
|
|
||||||
realm.write(function() {
|
realm.write(function() {
|
||||||
realm.create('TestObject', [2]);
|
realm.create('TestObject', {doubleCol: 2});
|
||||||
realm.create('TestObject', [3]);
|
realm.create('TestObject', {doubleCol: 3});
|
||||||
realm.create('TestObject', [1]);
|
realm.create('TestObject', {doubleCol: 1});
|
||||||
realm.create('TestObject', [4]);
|
realm.create('TestObject', {doubleCol: 4});
|
||||||
realm.create('TestObject', [0]);
|
realm.create('TestObject', {doubleCol: 0});
|
||||||
});
|
});
|
||||||
|
|
||||||
objects.sortByProperty('doubleCol');
|
objects.sortByProperty('doubleCol');
|
||||||
|
|
|
@ -7,20 +7,20 @@
|
||||||
var Realm = require('realm');
|
var Realm = require('realm');
|
||||||
|
|
||||||
exports.TestObject = {
|
exports.TestObject = {
|
||||||
name: 'TestObject',
|
name: 'TestObject',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'doubleCol', type: Realm.Types.DOUBLE},
|
doubleCol: Realm.Types.DOUBLE,
|
||||||
]
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function PersonObject() {}
|
function PersonObject() {}
|
||||||
PersonObject.prototype.schema = {
|
PersonObject.prototype.schema = {
|
||||||
name: 'PersonObject',
|
name: 'PersonObject',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'name', type: Realm.Types.STRING},
|
name: Realm.Types.STRING,
|
||||||
{name: 'age', type: Realm.Types.DOUBLE},
|
age: Realm.Types.DOUBLE,
|
||||||
{name: 'married', type: Realm.Types.BOOL, default: false}
|
married: {type: Realm.Types.BOOL, default: false},
|
||||||
]
|
}
|
||||||
};
|
};
|
||||||
PersonObject.prototype.description = function() {
|
PersonObject.prototype.description = function() {
|
||||||
return this.name + ' ' + this.age;
|
return this.name + ' ' + this.age;
|
||||||
|
@ -29,79 +29,79 @@ exports.PersonObject = PersonObject;
|
||||||
|
|
||||||
exports.BasicTypes = {
|
exports.BasicTypes = {
|
||||||
name: 'BasicTypesObject',
|
name: 'BasicTypesObject',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'boolCol', type: Realm.Types.BOOL},
|
boolCol: Realm.Types.BOOL,
|
||||||
{name: 'intCol', type: Realm.Types.INT},
|
intCol: Realm.Types.INT,
|
||||||
{name: 'floatCol', type: Realm.Types.FLOAT},
|
floatCol: Realm.Types.FLOAT,
|
||||||
{name: 'doubleCol', type: Realm.Types.DOUBLE},
|
doubleCol: Realm.Types.DOUBLE,
|
||||||
{name: 'stringCol', type: Realm.Types.STRING},
|
stringCol: Realm.Types.STRING,
|
||||||
{name: 'dateCol', type: Realm.Types.DATE},
|
dateCol: Realm.Types.DATE,
|
||||||
{name: 'dataCol', type: Realm.Types.DATA},
|
dataCol: Realm.Types.DATA,
|
||||||
]
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.NullableBasicTypes = {
|
exports.NullableBasicTypes = {
|
||||||
name: 'NullableBasicTypesObject',
|
name: 'NullableBasicTypesObject',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'boolCol', type: Realm.Types.BOOL, optional: true},
|
boolCol: {type: Realm.Types.BOOL, optional: true},
|
||||||
{name: 'intCol', type: Realm.Types.INT, optional: true},
|
intCol: {type: Realm.Types.INT, optional: true},
|
||||||
{name: 'floatCol', type: Realm.Types.FLOAT, optional: true},
|
floatCol: {type: Realm.Types.FLOAT, optional: true},
|
||||||
{name: 'doubleCol', type: Realm.Types.DOUBLE, optional: true},
|
doubleCol: {type: Realm.Types.DOUBLE, optional: true},
|
||||||
{name: 'stringCol', type: Realm.Types.STRING, optional: true},
|
stringCol: {type: Realm.Types.STRING, optional: true},
|
||||||
{name: 'dateCol', type: Realm.Types.DATE, optional: true},
|
dateCol: {type: Realm.Types.DATE, optional: true},
|
||||||
{name: 'dataCol', type: Realm.Types.DATA, optional: true},
|
dataCol: {type: Realm.Types.DATA, optional: true},
|
||||||
]
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.LinkTypes = {
|
exports.LinkTypes = {
|
||||||
name: 'LinkTypesObject',
|
name: 'LinkTypesObject',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'objectCol', type: 'TestObject'},
|
objectCol: 'TestObject',
|
||||||
{name: 'objectCol1', type: Realm.Types.OBJECT, objectType: 'TestObject'},
|
objectCol1: {type: Realm.Types.OBJECT, objectType: 'TestObject'},
|
||||||
{name: 'arrayCol', type: Realm.Types.LIST, objectType: 'TestObject'},
|
arrayCol: {type: Realm.Types.LIST, objectType: 'TestObject'},
|
||||||
]
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.IntPrimary = {
|
exports.IntPrimary = {
|
||||||
name: 'IntPrimaryObject',
|
name: 'IntPrimaryObject',
|
||||||
primaryKey: 'primaryCol',
|
primaryKey: 'primaryCol',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'primaryCol', type: Realm.Types.INT},
|
primaryCol: Realm.Types.INT,
|
||||||
{name: 'valueCol', type: Realm.Types.STRING},
|
valueCol: Realm.Types.STRING,
|
||||||
]
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.AllTypes = {
|
exports.AllTypes = {
|
||||||
name: 'AllTypesObject',
|
name: 'AllTypesObject',
|
||||||
primaryKey: 'primaryCol',
|
primaryKey: 'primaryCol',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'primaryCol',type: Realm.Types.STRING},
|
primaryCol: Realm.Types.STRING,
|
||||||
{name: 'boolCol', type: Realm.Types.BOOL},
|
boolCol: Realm.Types.BOOL,
|
||||||
{name: 'intCol', type: Realm.Types.INT},
|
intCol: Realm.Types.INT,
|
||||||
{name: 'floatCol', type: Realm.Types.FLOAT},
|
floatCol: Realm.Types.FLOAT,
|
||||||
{name: 'doubleCol', type: Realm.Types.DOUBLE},
|
doubleCol: Realm.Types.DOUBLE,
|
||||||
{name: 'stringCol', type: Realm.Types.STRING},
|
stringCol: Realm.Types.STRING,
|
||||||
{name: 'dateCol', type: Realm.Types.DATE},
|
dateCol: Realm.Types.DATE,
|
||||||
{name: 'dataCol', type: Realm.Types.DATA},
|
dataCol: Realm.Types.DATA,
|
||||||
{name: 'objectCol', type: 'TestObject'},
|
objectCol: 'TestObject',
|
||||||
{name: 'arrayCol', type: Realm.Types.LIST, objectType: 'TestObject'},
|
arrayCol: {type: Realm.Types.LIST, objectType: 'TestObject'},
|
||||||
]
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.DefaultValues = {
|
exports.DefaultValues = {
|
||||||
name: 'DefaultValuesObject',
|
name: 'DefaultValuesObject',
|
||||||
properties: [
|
properties: {
|
||||||
{name: 'boolCol', type: Realm.Types.BOOL, default: true},
|
boolCol: {type: Realm.Types.BOOL, default: true},
|
||||||
{name: 'intCol', type: Realm.Types.INT, default: -1},
|
intCol: {type: Realm.Types.INT, default: -1},
|
||||||
{name: 'floatCol', type: Realm.Types.FLOAT, default: -1.1},
|
floatCol: {type: Realm.Types.FLOAT, default: -1.1},
|
||||||
{name: 'doubleCol', type: Realm.Types.DOUBLE, default: -1.11},
|
doubleCol: {type: Realm.Types.DOUBLE, default: -1.11},
|
||||||
{name: 'stringCol', type: Realm.Types.STRING, default: 'defaultString'},
|
stringCol: {type: Realm.Types.STRING, default: 'defaultString'},
|
||||||
{name: 'dateCol', type: Realm.Types.DATE, default: new Date(1.111)},
|
dateCol: {type: Realm.Types.DATE, default: new Date(1.111)},
|
||||||
{name: 'dataCol', type: Realm.Types.DATA, default: new ArrayBuffer(1)},
|
dataCol: {type: Realm.Types.DATA, default: new ArrayBuffer(1)},
|
||||||
{name: 'objectCol', type: 'TestObject', default: [1]},
|
objectCol: {type: 'TestObject', default: {doubleCol: 1}},
|
||||||
{name: 'nullObjectCol', type: 'TestObject', default: null},
|
nullObjectCol: {type: 'TestObject', default: null},
|
||||||
{name: 'arrayCol', type: Realm.Types.LIST, objectType: 'TestObject', default: [[2]]},
|
arrayCol: {type: Realm.Types.LIST, objectType: 'TestObject', default: [{doubleCol: 2}]},
|
||||||
]
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.QueryObject = {
|
exports.QueryObject = {
|
||||||
|
|
Loading…
Reference in New Issue