diff --git a/lib/browser/index.js b/lib/browser/index.js index 93f8ab40..4e327bec 100644 --- a/lib/browser/index.js +++ b/lib/browser/index.js @@ -142,6 +142,12 @@ util.createMethods(Realm.prototype, objectTypes.REALM, [ ], true); Object.defineProperties(Realm, { + List: { + value: lists.List, + }, + Results: { + value: results.Results, + }, Types: { value: Object.freeze(propTypes), }, diff --git a/lib/browser/lists.js b/lib/browser/lists.js index 983bffa3..38beba2f 100644 --- a/lib/browser/lists.js +++ b/lib/browser/lists.js @@ -22,12 +22,13 @@ const constants = require('./constants'); const util = require('./util'); const {objectTypes} = constants; +class list {} module.exports = { + List, create, }; -class List {} // Non-mutating methods: util.createMethods(List.prototype, objectTypes.LIST, [ diff --git a/lib/browser/results.js b/lib/browser/results.js index dee2ea92..da5dbbff 100644 --- a/lib/browser/results.js +++ b/lib/browser/results.js @@ -21,11 +21,13 @@ const constants = require('./constants'); const util = require('./util'); +class Results {} + module.exports = { + Results, create, }; -class Results {} util.createMethods(Results.prototype, constants.objectTypes.RESULTS, [ 'filtered', diff --git a/src/js_init.cpp b/src/js_init.cpp index 4269e54f..d254c4ee 100644 --- a/src/js_init.cpp +++ b/src/js_init.cpp @@ -19,6 +19,8 @@ #include "js_init.h" #include "js_realm.hpp" #include "js_object.hpp" +#include "js_list.hpp" +#include "js_results.hpp" #include "js_util.hpp" #include "js_schema.hpp" #include "platform.hpp" @@ -54,27 +56,36 @@ JSClassRef RJSRealmTypeClass() { return JSClassCreate(&realmTypesDefinition); } +static JSObjectRef InvalidConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { + *exception = RJSMakeError(ctx, "Illegal constructor"); + return NULL; +} + static JSValueRef ClearTestState(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { RJSClearTestState(); return NULL; } JSObjectRef RJSConstructorCreate(JSContextRef ctx) { + static JSStringRef clearTestStateString = JSStringCreateWithUTF8CString("clearTestState"); + static JSStringRef listString = JSStringCreateWithUTF8CString("List"); + static JSStringRef resultsString = JSStringCreateWithUTF8CString("Results"); + static JSStringRef typeString = JSStringCreateWithUTF8CString("Types"); + JSObjectRef realmObject = JSObjectMake(ctx, RJSRealmConstructorClass(), NULL); - JSObjectRef typesObject = JSObjectMake(ctx, RJSRealmTypeClass(), NULL); - - JSValueRef exception = NULL; - JSStringRef typeString = JSStringCreateWithUTF8CString("Types"); JSPropertyAttributes attributes = kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete; - JSObjectSetProperty(ctx, realmObject, typeString, typesObject, attributes, &exception); - JSStringRelease(typeString); - assert(!exception); - JSStringRef clearTestStateString = JSStringCreateWithUTF8CString("clearTestState"); + JSObjectRef listConstructor = JSObjectMakeConstructor(ctx, RJSListClass(), InvalidConstructor); + RJSObjectSetProperty(ctx, realmObject, listString, listConstructor, attributes); + + JSObjectRef resultsContructor = JSObjectMakeConstructor(ctx, RJSResultsClass(), InvalidConstructor); + RJSObjectSetProperty(ctx, realmObject, resultsString, resultsContructor, attributes); + + JSObjectRef typesObject = JSObjectMake(ctx, RJSRealmTypeClass(), NULL); + RJSObjectSetProperty(ctx, realmObject, typeString, typesObject, attributes); + JSObjectRef clearTestStateFunction = JSObjectMakeFunctionWithCallback(ctx, clearTestStateString, ClearTestState); - JSObjectSetProperty(ctx, realmObject, clearTestStateString, clearTestStateFunction, attributes, &exception); - JSStringRelease(clearTestStateString); - assert(!exception); + RJSObjectSetProperty(ctx, realmObject, clearTestStateString, clearTestStateFunction, attributes); return realmObject; } diff --git a/src/js_util.hpp b/src/js_util.hpp index e08c8d1c..b02d4ed3 100644 --- a/src/js_util.hpp +++ b/src/js_util.hpp @@ -201,6 +201,14 @@ static inline size_t RJSValidatedListLength(JSContextRef ctx, JSObjectRef object return RJSValidatedValueToNumber(ctx, lengthValue); } +static inline void RJSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes = 0) { + JSValueRef exception = NULL; + JSObjectSetProperty(ctx, object, propertyName, value, attributes, &exception); + if (exception) { + throw RJSException(ctx, exception); + } +} + template T stot(const std::string s) { std::istringstream iss(s); diff --git a/tests/js/list-tests.js b/tests/js/list-tests.js index 37fcf1dc..37f8f4a5 100644 --- a/tests/js/list-tests.js +++ b/tests/js/list-tests.js @@ -24,7 +24,16 @@ var TestCase = require('./asserts'); var schemas = require('./schemas'); module.exports = BaseTest.extend({ - testArrayLength: function() { + testListConstructor: function() { + var realm = new Realm({schema: [schemas.PersonObject, schemas.PersonList]}); + + realm.write(function() { + var obj = realm.create('PersonList', {list: []}); + TestCase.assertTrue(obj.list instanceof Realm.List); + }); + }, + + testListLength: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var array; @@ -52,7 +61,7 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(array.length, 2); }, - testArraySubscriptGetters: function() { + testListSubscriptGetters: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var array; @@ -72,7 +81,7 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(array[-1], undefined); }, - testArraySubscriptSetters: function() { + testListSubscriptSetters: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var array; @@ -110,7 +119,7 @@ module.exports = BaseTest.extend({ }, 'cannot set list item outside write transaction'); }, - testArrayInvalidProperty: function() { + testListInvalidProperty: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var array; @@ -127,7 +136,7 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(undefined, array.ablasdf); }, - testArrayEnumerate: function() { + testListEnumerate: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var obj; @@ -160,7 +169,7 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(keys.length, 2); }, - testPush: function() { + testListPush: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var array; @@ -194,7 +203,7 @@ module.exports = BaseTest.extend({ }, 'can only push in a write transaction'); }, - testPop: function() { + testListPop: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var array; @@ -222,7 +231,7 @@ module.exports = BaseTest.extend({ }, 'can only pop in a write transaction'); }, - testUnshift: function() { + testListUnshift: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var array; @@ -252,7 +261,7 @@ module.exports = BaseTest.extend({ }, 'can only unshift in a write transaction'); }, - testShift: function() { + testListShift: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var array; @@ -280,7 +289,7 @@ module.exports = BaseTest.extend({ }, 'can only shift in a write transaction'); }, - testSplice: function() { + testListSplice: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var array; @@ -345,7 +354,7 @@ module.exports = BaseTest.extend({ }, 'can only splice in a write transaction'); }, - testDeletions: function() { + testListDeletions: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var object; var array; @@ -424,7 +433,7 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(objects.length, 4); }, - testStaticResults: function() { + testListSnapshot: function() { var realm = new Realm({schema: [schemas.LinkTypes, schemas.TestObject]}); var objects = realm.objects('TestObject'); var array;