diff --git a/integration-tests/tests/src/objects.ts b/integration-tests/tests/src/objects.ts index 317a5c7864..aeee8a4b18 100644 --- a/integration-tests/tests/src/objects.ts +++ b/integration-tests/tests/src/objects.ts @@ -1,33 +1,239 @@ 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 - }); - }); - // 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); + 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 fetched with objectForPrimaryKey", () => { + const realm = new Realm({ schema: [PersonSchemaWithId] }); + const _id = "0e19bcb8-c77a-44e5-9713-d6a59702869f"; + + realm.write(() => { + realm.create(PersonSchemaWithId.name, { + _id, + name: "John Doe", + age: 42 + }); + }); + + const john = realm.objectForPrimaryKey( + PersonSchemaWithId.name, + _id + ); + + 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", () => { + 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}''.` + ); + + // Excpect only one instance of 'PersonSchemaWithId' in db after all updates + const persons = realm.objects(PersonSchemaWithId.name); + expect(persons.length).equals(1); + }); }); - 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 fetched with objectForPrimaryKey", () => { + const realm = new Realm({ schema: [PersonWithId] }); + const _id = "1d84d60b-8c64-4531-bfdc-87cdd9e029c3"; + + realm.write(() => { + realm.create(PersonWithId, { + _id, + name: "John Doe", + age: 42 + }); + }); + + const john = realm.objectForPrimaryKey(PersonWithId, _id); + + expect(john).instanceOf(PersonWithId); + expect(john._id).equals(_id); + 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}''.` + ); + + // Excpect only one instance of 'PersonWithId' in db after all updates + const persons = realm.objects(PersonWithId); + expect(persons.length).equals(1); }); }); }); 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 ); }); diff --git a/lib/index.d.ts b/lib/index.d.ts index 68f7e9b477..315b9168d3 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 @@ -988,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