From 70dd0b620e64e105a22608762cbce2f11a7ac59b Mon Sep 17 00:00:00 2001 From: Steffen Agger Date: Mon, 28 Sep 2020 11:38:03 +0200 Subject: [PATCH 1/9] Introduced overloading for partial updates added to create(...) - preserving deprecated create-declarations. --- lib/index.d.ts | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/index.d.ts b/lib/index.d.ts index 68f7e9b477..ca5a665b31 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -938,38 +938,40 @@ declare class Realm { /** * @param {string} type * @param {T} properties - * @param {boolean} update? + * @param {Realm.UpdateMode} mode? If not provided, `Realm.UpdateMode.Never` is used. * @returns T & Realm.Object - * - * @deprecated, to be removed in future versions. Use `create(type, properties, UpdateMode)` instead. */ - create(type: string, properties: RealmInsertionModel, update?: boolean): T & Realm.Object + create(type: string, properties: RealmInsertionModel, mode?: Realm.UpdateMode.Never): T & Realm.Object; + create(type: string, properties: Partial | Partial>, mode: Realm.UpdateMode.All | Realm.UpdateMode.Modified): T & Realm.Object; /** - * @param {Class} type + * @param {string} type * @param {T} properties * @param {boolean} update? - * @returns T + * @returns T & Realm.Object * * @deprecated, to be removed in future versions. Use `create(type, properties, UpdateMode)` instead. */ - create(type: {new(...arg: any[]): T; }, properties: RealmInsertionModel, update?: boolean): T + create(type: string, properties: RealmInsertionModel, update: boolean): T & Realm.Object; /** - * @param {string} type + * @param {Class} type * @param {T} properties * @param {Realm.UpdateMode} mode? If not provided, `Realm.UpdateMode.Never` is used. - * @returns T & Realm.Object + * @returns T */ - create(type: string, properties: RealmInsertionModel, mode?: Realm.UpdateMode): T & Realm.Object + create(type: {new(...arg: any[]): T; }, properties: RealmInsertionModel, mode?: Realm.UpdateMode.Never): T; + create(type: {new(...arg: any[]): T; }, properties: Partial | Partial>, mode: Realm.UpdateMode.All | Realm.UpdateMode.Modified): T; - /** + /** * @param {Class} type * @param {T} properties - * @param {Realm.UpdateMode} mode? If not provided, `Realm.UpdateMode.Never` is used. + * @param {boolean} update? * @returns T + * + * @deprecated, to be removed in future versions. Use `create(type, properties, UpdateMode)` instead. */ - create(type: {new(...arg: any[]): T; }, properties: RealmInsertionModel, mode?: Realm.UpdateMode): T + create(type: {new(...arg: any[]): T; }, properties: RealmInsertionModel, update: boolean): T /** * @param {Realm.Object|Realm.Object[]|Realm.List|Realm.Results|any} object From 50cec1d4b3a260b8b8c8dbdd0390ab6a61a8bccd Mon Sep 17 00:00:00 2001 From: Steffen Agger Date: Mon, 28 Sep 2020 11:38:41 +0200 Subject: [PATCH 2/9] Integration-tests for Objects extended w. Class Models & update tests. --- integration-tests/tests/src/objects.ts | 195 ++++++++++++++++++++++--- 1 file changed, 175 insertions(+), 20 deletions(-) diff --git a/integration-tests/tests/src/objects.ts b/integration-tests/tests/src/objects.ts index 317a5c7864..99e56d828a 100644 --- a/integration-tests/tests/src/objects.ts +++ b/integration-tests/tests/src/objects.ts @@ -1,33 +1,188 @@ import { expect } from "chai"; - -import { IPerson, PersonSchema } from "./schemas/person-and-dogs"; +import { + IPerson as IPersonWithId, + Person as PersonWithId, + PersonSchema as PersonSchemaWithId +} from "./schemas/person-and-dog-with-primary-ids"; +import { IPerson, Person, PersonSchema } from "./schemas/person-and-dogs"; describe("Realm objects", () => { - it("can be created", () => { - const realm = new Realm({ schema: [PersonSchema] }); - let john: IPerson; - realm.write(() => { - john = realm.create("Person", { - name: "John Doe", - age: 42 + describe("Interface & object literal", () => { + it("can be created", () => { + const realm = new Realm({ schema: [PersonSchema] }); + let john: IPerson; + + realm.write(() => { + john = realm.create(PersonSchema.name, { + name: "John Doe", + age: 42 + }); + }); + + // Expect John to be the one and only result + const persons = realm.objects(PersonSchema.name); + expect(persons.length).equals(1); + const [firstPerson] = persons; + expect(firstPerson).deep.equals(john); + }); + + it("can have it's properties read", () => { + const realm = new Realm({ schema: [PersonSchema] }); + let john: IPerson; + + realm.write(() => { + john = realm.create(PersonSchema.name, { + name: "John Doe", + age: 42 + }); + }); + + expect(john.name).equals("John Doe"); + expect(john.age).equals(42); + }); + + it("can be updated", () => { + const realm = new Realm({ schema: [PersonSchemaWithId] }); + let john: IPersonWithId; + const _id = "8ef4d2e2-a8be-468d-995d-36068d15b520"; + + realm.write(() => { + john = realm.create(PersonSchemaWithId.name, { + _id, + name: "John Doe", + age: 42 + }); + }); + + expect(john.name).equals("John Doe"); + expect(john.age).equals(42); + + realm.write(() => { + realm.create( + PersonSchemaWithId.name, + { _id, age: 43 }, + Realm.UpdateMode.All + ); + }); + + expect(john.name).equals("John Doe"); + expect(john.age).equals(43); + + const update: Partial = { + _id, + name: "Mr. John Doe" + }; + + realm.write(() => { + realm.create( + PersonSchemaWithId.name, + update, + Realm.UpdateMode.Modified + ); }); + + expect(john.name).equals("Mr. John Doe"); + expect(john.age).equals(43); + + expect(() => + realm.write(() => { + realm.create( + PersonSchemaWithId.name, + { _id, name: "John Doe", age: 42 }, + Realm.UpdateMode.Never + ); + }) + ).throws( + `Attempting to create an object of type '${ + PersonSchemaWithId.name + }' with an existing primary key value '${_id}'.` + ); }); - // Expect John to be the one and only result - const persons = realm.objects("Person"); - expect(persons.length).equals(1); - const [firstPerson] = persons; - expect(firstPerson).deep.equals(john); }); - it("can have it's properties read", () => { - const realm = new Realm({ schema: [PersonSchema] }); - realm.write(() => { - const john = realm.create("Person", { - name: "John Doe", - age: 42 + describe("Class Model", () => { + it("can be created", () => { + const realm = new Realm({ schema: [Person] }); + let john: Person; + + realm.write(() => { + john = realm.create(Person, { + name: "John Doe", + age: 42 + }); + }); + // Expect John to be the one and only result + const persons = realm.objects(Person); + expect(persons.length).equals(1); + const [firstPerson] = persons; + expect(firstPerson).deep.equals(john); + expect(firstPerson).instanceOf(Person); + }); + + it("can have it's properties read", () => { + const realm = new Realm({ schema: [Person] }); + realm.write(() => { + const john = realm.create(Person, { + name: "John Doe", + age: 42 + }); + expect(john.name).equals("John Doe"); + expect(john.age).equals(42); + }); + }); + + it("can be updated", () => { + const realm = new Realm({ schema: [PersonWithId] }); + let john: PersonWithId; + const _id = "e4762cd3-b92f-47ae-857a-26eba201e7db"; + + realm.write(() => { + john = realm.create(PersonWithId, { + _id, + name: "John Doe", + age: 42 + }); }); + expect(john.name).equals("John Doe"); expect(john.age).equals(42); + + realm.write(() => { + realm.create( + PersonWithId, + { _id, age: 43 }, + Realm.UpdateMode.All + ); + }); + + expect(john.name).equals("John Doe"); + expect(john.age).equals(43); + + const update: Partial = { + _id, + name: "Mr. John Doe" + }; + + realm.write(() => { + realm.create(PersonWithId, update, Realm.UpdateMode.Modified); + }); + + expect(john.name).equals("Mr. John Doe"); + expect(john.age).equals(43); + + expect(() => + realm.write(() => { + realm.create( + PersonWithId, + { _id, name: "John Doe", age: 42 }, + Realm.UpdateMode.Never + ); + }) + ).throws( + `Attempting to create an object of type '${ + PersonWithId.schema.name + }' with an existing primary key value '${_id}'.` + ); }); }); }); From b1e77e2d0eec8256b78730acefdf0ebcf512e8fa Mon Sep 17 00:00:00 2001 From: Steffen Agger Date: Mon, 28 Sep 2020 11:39:01 +0200 Subject: [PATCH 3/9] Fix for serialization test in different environments. --- integration-tests/tests/src/serialization.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/integration-tests/tests/src/serialization.ts b/integration-tests/tests/src/serialization.ts index 9af9ee5030..513e989ce0 100755 --- a/integration-tests/tests/src/serialization.ts +++ b/integration-tests/tests/src/serialization.ts @@ -261,8 +261,9 @@ describe("JSON serialization", () => { }); it("throws correct error on serialization", () => { - expect(() => JSON.stringify(persons[0])).throws( - "Converting circular structure to JSON" + expect(() => JSON.stringify(persons)).throws( + TypeError, + /circular|cyclic/i ); }); @@ -291,7 +292,8 @@ describe("JSON serialization", () => { it("throws correct error on serialization", () => { expect(() => JSON.stringify(persons)).throws( - "Converting circular structure to JSON" + TypeError, + /circular|cyclic/i ); }); From f1c661c42ef5d70ad977a48b5acdfe8ada5dad80 Mon Sep 17 00:00:00 2001 From: Steffen Agger Date: Mon, 28 Sep 2020 12:50:27 +0200 Subject: [PATCH 4/9] Passing tests, please note the added extra ' in the error message - is this intentional?! --- integration-tests/tests/src/objects.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-tests/tests/src/objects.ts b/integration-tests/tests/src/objects.ts index 99e56d828a..2631f82e42 100644 --- a/integration-tests/tests/src/objects.ts +++ b/integration-tests/tests/src/objects.ts @@ -95,7 +95,7 @@ describe("Realm objects", () => { ).throws( `Attempting to create an object of type '${ PersonSchemaWithId.name - }' with an existing primary key value '${_id}'.` + }' with an existing primary key value ''${_id}''.` ); }); }); @@ -181,7 +181,7 @@ describe("Realm objects", () => { ).throws( `Attempting to create an object of type '${ PersonWithId.schema.name - }' with an existing primary key value '${_id}'.` + }' with an existing primary key value ''${_id}''.` ); }); }); From c0b12a55999cabcbea30f2e531492bc19cf6b564 Mon Sep 17 00:00:00 2001 From: Steffen Agger Date: Mon, 28 Sep 2020 13:58:06 +0200 Subject: [PATCH 5/9] Added test: "can be fetched with objectForPrimaryKey" --- integration-tests/tests/src/objects.ts | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/integration-tests/tests/src/objects.ts b/integration-tests/tests/src/objects.ts index 2631f82e42..d5fc2381fa 100644 --- a/integration-tests/tests/src/objects.ts +++ b/integration-tests/tests/src/objects.ts @@ -41,6 +41,32 @@ describe("Realm objects", () => { expect(john.age).equals(42); }); + it("can be fetched with objectForPrimaryKey", () => { + const realm = new Realm({ schema: [PersonSchemaWithId] }); + const _id = "0e19bcb8-c77a-44e5-9713-d6a59702869f"; + + realm.write(() => { + const johnIn = realm.create(PersonWithId, { + _id, + name: "John Doe", + age: 42 + }); + expect(johnIn._id).equals(_id); + expect(johnIn.name).equals("John Doe"); + expect(johnIn.age).equals(42); + }); + + const johnOut = realm.objectForPrimaryKey( + PersonSchemaWithId.name, + _id + ); + + expect(johnOut).instanceOf(Realm.Object); + expect(johnOut._id).equals(_id); + expect(johnOut.name).equals("John Doe"); + expect(johnOut.age).equals(42); + }); + it("can be updated", () => { const realm = new Realm({ schema: [PersonSchemaWithId] }); let john: IPersonWithId; @@ -131,6 +157,29 @@ describe("Realm objects", () => { }); }); + it("can be fetched with objectForPrimaryKey", () => { + const realm = new Realm({ schema: [PersonWithId] }); + const _id = "1d84d60b-8c64-4531-bfdc-87cdd9e029c3"; + + realm.write(() => { + const johnIn = realm.create(PersonWithId, { + _id, + name: "John Doe", + age: 42 + }); + expect(johnIn._id).equals(_id); + expect(johnIn.name).equals("John Doe"); + expect(johnIn.age).equals(42); + }); + + const johnOut = realm.objectForPrimaryKey(PersonWithId, _id); + + expect(johnOut).instanceOf(PersonWithId); + expect(johnOut._id).equals(_id); + expect(johnOut.name).equals("John Doe"); + expect(johnOut.age).equals(42); + }); + it("can be updated", () => { const realm = new Realm({ schema: [PersonWithId] }); let john: PersonWithId; From 6da02c364d0f857400909b619c927e06f87aa2f6 Mon Sep 17 00:00:00 2001 From: Steffen Agger Date: Mon, 28 Sep 2020 14:25:53 +0200 Subject: [PATCH 6/9] objectForPrimaryKey updated to work similar to objects --- lib/index.d.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/index.d.ts b/lib/index.d.ts index ca5a665b31..315b9168d3 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -990,18 +990,18 @@ declare class Realm { deleteAll(): void; /** - * @param {string|Realm.ObjectType|Function} type + * @param {string} type * @param {number|string} key * @returns {T | undefined} */ - objectForPrimaryKey(type: string | Realm.ObjectType | Function, key: number | string): T & Realm.Object | undefined; + objectForPrimaryKey(type: string, key: number | string): (T & Realm.Object) | undefined; /** - * @param {string|Realm.ObjectType|Function} type - * @param {string} id + * @param {Class} type + * @param {number|string} key * @returns {T | undefined} */ - objectForPrimaryKey(type: string | Realm.ObjectType | Function, id: string): T & Realm.Object | undefined; + objectForPrimaryKey(type: {new(...arg: any[]): T; }, key: number | string): T | undefined; /** * @param {string} type From c71b92f102df8fad4d27548c31bc34430a424c2d Mon Sep 17 00:00:00 2001 From: Steffen Agger Date: Mon, 28 Sep 2020 14:47:42 +0200 Subject: [PATCH 7/9] objectForPrimaryKey typo update... --- integration-tests/tests/src/objects.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/integration-tests/tests/src/objects.ts b/integration-tests/tests/src/objects.ts index d5fc2381fa..818ea5ee10 100644 --- a/integration-tests/tests/src/objects.ts +++ b/integration-tests/tests/src/objects.ts @@ -46,11 +46,14 @@ describe("Realm objects", () => { const _id = "0e19bcb8-c77a-44e5-9713-d6a59702869f"; realm.write(() => { - const johnIn = realm.create(PersonWithId, { - _id, - name: "John Doe", - age: 42 - }); + const johnIn = realm.create( + PersonSchemaWithId.name, + { + _id, + name: "John Doe", + age: 42 + } + ); expect(johnIn._id).equals(_id); expect(johnIn.name).equals("John Doe"); expect(johnIn.age).equals(42); From 7848cdd0998377e196eb81be2a779638a8547422 Mon Sep 17 00:00:00 2001 From: Steffen Agger Date: Mon, 28 Sep 2020 15:32:46 +0200 Subject: [PATCH 8/9] Added final length-check to update-tests. --- integration-tests/tests/src/objects.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/integration-tests/tests/src/objects.ts b/integration-tests/tests/src/objects.ts index 818ea5ee10..14406fcfed 100644 --- a/integration-tests/tests/src/objects.ts +++ b/integration-tests/tests/src/objects.ts @@ -126,6 +126,10 @@ describe("Realm objects", () => { PersonSchemaWithId.name }' with an existing primary key value ''${_id}''.` ); + + // Excpect only one instance of 'PersonSchemaWithId' in db after all updates + const persons = realm.objects(PersonSchemaWithId.name); + expect(persons.length).equals(1); }); }); @@ -235,6 +239,10 @@ describe("Realm objects", () => { PersonWithId.schema.name }' with an existing primary key value ''${_id}''.` ); + + // Excpect only one instance of 'PersonWithId' in db after all updates + const persons = realm.objects(PersonWithId); + expect(persons.length).equals(1); }); }); }); From 84b2420f79c4c93111a8258cc4d9b3202d33b3e9 Mon Sep 17 00:00:00 2001 From: Steffen Agger Date: Mon, 28 Sep 2020 18:09:15 +0200 Subject: [PATCH 9/9] Removed duplicate tests --- integration-tests/tests/src/objects.ts | 41 ++++++++++---------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/integration-tests/tests/src/objects.ts b/integration-tests/tests/src/objects.ts index 14406fcfed..aeee8a4b18 100644 --- a/integration-tests/tests/src/objects.ts +++ b/integration-tests/tests/src/objects.ts @@ -46,28 +46,22 @@ describe("Realm objects", () => { const _id = "0e19bcb8-c77a-44e5-9713-d6a59702869f"; realm.write(() => { - const johnIn = realm.create( - PersonSchemaWithId.name, - { - _id, - name: "John Doe", - age: 42 - } - ); - expect(johnIn._id).equals(_id); - expect(johnIn.name).equals("John Doe"); - expect(johnIn.age).equals(42); + realm.create(PersonSchemaWithId.name, { + _id, + name: "John Doe", + age: 42 + }); }); - const johnOut = realm.objectForPrimaryKey( + const john = realm.objectForPrimaryKey( PersonSchemaWithId.name, _id ); - expect(johnOut).instanceOf(Realm.Object); - expect(johnOut._id).equals(_id); - expect(johnOut.name).equals("John Doe"); - expect(johnOut.age).equals(42); + expect(john).instanceOf(Realm.Object); + expect(john._id).equals(_id); + expect(john.name).equals("John Doe"); + expect(john.age).equals(42); }); it("can be updated", () => { @@ -169,22 +163,19 @@ describe("Realm objects", () => { const _id = "1d84d60b-8c64-4531-bfdc-87cdd9e029c3"; realm.write(() => { - const johnIn = realm.create(PersonWithId, { + realm.create(PersonWithId, { _id, name: "John Doe", age: 42 }); - expect(johnIn._id).equals(_id); - expect(johnIn.name).equals("John Doe"); - expect(johnIn.age).equals(42); }); - const johnOut = realm.objectForPrimaryKey(PersonWithId, _id); + const john = realm.objectForPrimaryKey(PersonWithId, _id); - expect(johnOut).instanceOf(PersonWithId); - expect(johnOut._id).equals(_id); - expect(johnOut.name).equals("John Doe"); - expect(johnOut.age).equals(42); + expect(john).instanceOf(PersonWithId); + expect(john._id).equals(_id); + expect(john.name).equals("John Doe"); + expect(john.age).equals(42); }); it("can be updated", () => {