diff --git a/src/RJSSchema.mm b/src/RJSSchema.mm index da01f7f0..c9a4e247 100644 --- a/src/RJSSchema.mm +++ b/src/RJSSchema.mm @@ -49,10 +49,20 @@ static inline Property RJSParseProperty(JSContextRef ctx, JSObjectRef propertyOb static JSStringRef nameString = JSStringCreateWithUTF8CString("name"); static JSStringRef typeString = JSStringCreateWithUTF8CString("type"); static JSStringRef objectTypeString = JSStringCreateWithUTF8CString("objectType"); + static JSStringRef optionalString = JSStringCreateWithUTF8CString("optional"); Property prop; prop.name = RJSValidatedStringProperty(ctx, propertyObject, nameString); + prop.is_nullable = false; + JSValueRef optionalValue = JSObjectGetProperty(ctx, propertyObject, optionalString, NULL); + if (!JSValueIsUndefined(ctx, optionalValue)) { + if (!JSValueIsBoolean(ctx, optionalValue)) { + throw std::runtime_error("Property expected to be of type boolean"); + } + prop.is_nullable = JSValueToBoolean(ctx, optionalValue); + } + std::string type = RJSValidatedStringProperty(ctx, propertyObject, typeString); if (type == "PropTypesBOOL") { prop.type = PropertyTypeBool; @@ -75,19 +85,14 @@ static inline Property RJSParseProperty(JSContextRef ctx, JSObjectRef propertyOb else if (type == "PropTypesDATA") { prop.type = PropertyTypeData; } - else if (type == "PropTypesOBJECT") { - prop.type = PropertyTypeObject; - prop.object_type = RJSValidatedStringProperty(ctx, propertyObject, objectTypeString); - prop.is_nullable = true; - } else if (type == "PropTypesLIST") { prop.type = PropertyTypeArray; prop.object_type = RJSValidatedStringProperty(ctx, propertyObject, objectTypeString); } else { prop.type = PropertyTypeObject; - prop.object_type = type; prop.is_nullable = true; + prop.object_type = type == "PropTypesOBJECT" ? RJSValidatedStringProperty(ctx, propertyObject, objectTypeString) : type; } return prop; } diff --git a/tests/ObjectTests.js b/tests/ObjectTests.js index 47aab7ab..abf413ff 100644 --- a/tests/ObjectTests.js +++ b/tests/ObjectTests.js @@ -47,6 +47,19 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(object.nonexistent, undefined); }, + testNullableBasicTypesPropertyGetters: function() { + var basicTypesValues = [null, null, null, null, null, null, null]; + var realm = new Realm({schema: [schemas.NullableBasicTypes]}); + var object = null; + realm.write(function() { + object = realm.create('NullableBasicTypesObject', basicTypesValues); + }); + + for (var i = 0; i < schemas.BasicTypes.properties.length; i++) { + var prop = schemas.BasicTypes.properties[i]; + TestCase.assertEqual(object[prop.name], null); + } + }, testBasicTypesPropertySetters: function() { var basicTypesValues = [true, 1, 1.1, 1.11, 'string', new Date(1), 'DATA']; var realm = new Realm({schema: [schemas.BasicTypes]}); diff --git a/tests/schemas.js b/tests/schemas.js index 407bf171..f75f4341 100644 --- a/tests/schemas.js +++ b/tests/schemas.js @@ -53,6 +53,19 @@ exports.BasicTypes = { ] }; +exports.NullableBasicTypes = { + name: 'NullableBasicTypes', + properties: [ + {name: 'boolCol', type: Realm.Types.BOOL, optional: true}, + {name: 'intCol', type: Realm.Types.INT, optional: true}, + {name: 'floatCol', type: Realm.Types.FLOAT, optional: true}, + {name: 'doubleCol', type: Realm.Types.DOUBLE, optional: true}, + {name: 'stringCol', type: Realm.Types.STRING, optional: true}, + {name: 'dateCol', type: Realm.Types.DATE, optional: true}, + {name: 'dataCol', type: Realm.Types.DATA, optional: true}, + ] +}; + exports.LinkTypes = { name: 'LinkTypesObject', properties: [