Add list item setters in JS

Added a test and made other array tests syntactically consistent. Resolves #45
This commit is contained in:
Scott Kyle 2015-10-12 02:55:37 -07:00
parent 515ece8fdd
commit ae9ae4dc77
2 changed files with 82 additions and 15 deletions

View File

@ -82,6 +82,35 @@ JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
} }
} }
bool ArraySetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* jsException) {
try {
ObjectArray *array = RJSVerifiedMutableArray(object);
size_t size = array->size();
std::string indexStr = RJSStringForJSString(propertyName);
if (indexStr == "length") {
throw std::runtime_error("The 'length' property is readonly.");
}
size_t index = std::stol(indexStr);
if (index >= size) {
throw std::out_of_range("Cannot set list item beyond its bounds.");
}
array->link_view->set(index, RJSAccessor::to_object_index(ctx, array->realm, const_cast<JSValueRef &>(value), array->object_schema.name, false));
return true;
}
catch (std::invalid_argument &exp) {
// for stol failure this could be another property that is handled externally, so ignore
return false;
}
catch (std::exception &exp) {
if (jsException) {
*jsException = RJSMakeError(ctx, exp);
}
return false;
}
}
void ArrayPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) { void ArrayPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) {
ObjectArray *array = RJSVerifiedArray(object); ObjectArray *array = RJSVerifiedArray(object);
size_t size = array->size(); size_t size = array->size();
@ -216,6 +245,6 @@ const JSStaticFunction RJSArrayFuncs[] = {
}; };
JSClassRef RJSArrayClass() { JSClassRef RJSArrayClass() {
static JSClassRef s_arrayClass = RJSCreateWrapperClass<Object>("RealmArray", ArrayGetProperty, NULL, RJSArrayFuncs, NULL, ArrayPropertyNames); static JSClassRef s_arrayClass = RJSCreateWrapperClass<Object>("RealmArray", ArrayGetProperty, ArraySetProperty, RJSArrayFuncs, NULL, ArrayPropertyNames);
return s_arrayClass; return s_arrayClass;
} }

View File

@ -33,32 +33,71 @@ var ArrayTests = {
}); });
}, },
testArraySubscript: function() { testArraySubscriptGetters: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]}); var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
realm.write(function() { realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]); }); var array;
realm.write(function() {
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
array = obj.arrayCol;
});
var array = realm.objects('LinkTypesObject')[0].arrayCol;
TestCase.assertEqual(array[0].doubleCol, 3); TestCase.assertEqual(array[0].doubleCol, 3);
TestCase.assertEqual(array[1].doubleCol, 4); TestCase.assertEqual(array[1].doubleCol, 4);
TestCase.assertThrows(function() { array[2]; }, 'Invalid index'); TestCase.assertThrows(function() { array[2]; }, 'Invalid index');
TestCase.assertThrows(function() { array[-1]; }, 'Invalid index'); TestCase.assertThrows(function() { array[-1]; }, 'Invalid index');
}, },
testArraySubscriptSetters: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
var array;
realm.write(function() {
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
array = obj.arrayCol;
array[0] = [5];
array[1] = [6];
TestCase.assertEqual(array[0].doubleCol, 5);
TestCase.assertEqual(array[1].doubleCol, 6);
TestCase.assertThrows(function() {
array.length = 0;
}, 'cannot set length property on lists');
TestCase.assertThrows(function() {
array[2] = [1];
}, 'cannot set list item beyond its bounds');
});
TestCase.assertThrows(function() {
array[0] = [3];
}, 'cannot set list item outside write transaction');
},
testArrayInvalidProperty: function() { testArrayInvalidProperty: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]}); var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
realm.write(function() { realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]); }); var array;
realm.write(function() {
var obj = realm.create('LinkTypesObject', [[1], [2], [[3], [4]]]);
array = obj.arrayCol;
});
var array = realm.objects('LinkTypesObject')[0].arrayCol;
TestCase.assertEqual(undefined, array.ablasdf); TestCase.assertEqual(undefined, array.ablasdf);
}, },
testArrayEnumerate: function() { testArrayEnumerate: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]}); var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
realm.write(function() { realm.create('LinkTypesObject', [[1], [2], []]); }); var obj;
var obj = realm.objects('LinkTypesObject')[0]; realm.write(function() {
for (var object in obj.arrayCol) { obj = realm.create('LinkTypesObject', [[1], [2], []]);
TestCase.assertTrue(false, "No objects should have been enumerated: " + object); });
for (var index in obj.arrayCol) {
TestCase.assertTrue(false, "No objects should have been enumerated: " + index);
} }
realm.write(function() { realm.write(function() {
@ -67,9 +106,8 @@ var ArrayTests = {
}); });
var count = 0; var count = 0;
for (var object in obj.arrayCol) { for (var index in obj.arrayCol) {
count++; count++;
//TestCase.assertTrue(object instanceof Object);
} }
TestCase.assertEqual(2, count); TestCase.assertEqual(2, count);
}, },