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) {
ObjectArray *array = RJSVerifiedArray(object);
size_t size = array->size();
@ -216,6 +245,6 @@ const JSStaticFunction RJSArrayFuncs[] = {
};
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;
}

View File

@ -30,35 +30,74 @@ var ArrayTests = {
obj.arrayCol = [[1], [2]];
TestCase.assertEqual(obj.arrayCol.length, 2);
});
});
},
testArraySubscript: function() {
testArraySubscriptGetters: function() {
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[1].doubleCol, 4);
TestCase.assertThrows(function() { array[2]; }, 'Invalid index');
TestCase.assertThrows(function() { array[-1]; }, 'Invalid index');
},
testArrayInvalidProperty: function() {
testArraySubscriptSetters: function() {
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;
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() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
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);
},
testArrayEnumerate: function() {
var realm = new Realm({schema: [LinkTypesObjectSchema, TestObjectSchema]});
realm.write(function() { realm.create('LinkTypesObject', [[1], [2], []]); });
var obj;
var obj = realm.objects('LinkTypesObject')[0];
for (var object in obj.arrayCol) {
TestCase.assertTrue(false, "No objects should have been enumerated: " + object);
realm.write(function() {
obj = realm.create('LinkTypesObject', [[1], [2], []]);
});
for (var index in obj.arrayCol) {
TestCase.assertTrue(false, "No objects should have been enumerated: " + index);
}
realm.write(function() {
@ -67,10 +106,9 @@ var ArrayTests = {
});
var count = 0;
for (var object in obj.arrayCol) {
for (var index in obj.arrayCol) {
count++;
//TestCase.assertTrue(object instanceof Object);
}
}
TestCase.assertEqual(2, count);
},