From 1022b5afbf5e6bc7f036ad9ac0f004f837ee504c Mon Sep 17 00:00:00 2001 From: gagik Date: Wed, 22 Feb 2023 13:37:38 +0100 Subject: [PATCH 01/15] BSON ObjectID alias --- packages/realm/src/bson.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/realm/src/bson.ts b/packages/realm/src/bson.ts index 075ba29acd..b1623850df 100644 --- a/packages/realm/src/bson.ts +++ b/packages/realm/src/bson.ts @@ -26,6 +26,8 @@ import * as bson from "bson"; export namespace BSON { export const ObjectId = bson.ObjectId; export type ObjectId = bson.ObjectId; + export const ObjectID = bson.ObjectID; + export type ObjectID = bson.ObjectID; export const Decimal128 = bson.Decimal128; export type Decimal128 = bson.Decimal128; export const UUID = bson.UUID; From e4b25eeb8e54602c9c0b3e89a91b2dbdd35f3ef1 Mon Sep 17 00:00:00 2001 From: gagik Date: Wed, 22 Feb 2023 13:38:33 +0100 Subject: [PATCH 02/15] Delete with interface type and unnecessary import --- .../tests/src/tests/credentials/function.ts | 10 +++++----- integration-tests/tests/src/tests/dictionary.ts | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/integration-tests/tests/src/tests/credentials/function.ts b/integration-tests/tests/src/tests/credentials/function.ts index e74392fb2d..fe5ec40cf5 100644 --- a/integration-tests/tests/src/tests/credentials/function.ts +++ b/integration-tests/tests/src/tests/credentials/function.ts @@ -27,18 +27,18 @@ describe.skipIf(environment.missingServer, "custom-function credentials", () => exports = async function (loginPayload) { // Get a handle for the app.users collection const users = context.services.get("mongodb").db("app").collection("users"); - + // Parse out custom data from the FunctionCredential - + const { username, secret } = loginPayload; - + if (secret !== "v3ry-s3cret") { throw new Error("Ah ah ah, you didn't say the magic word"); } // Query for an existing user document with the specified username - + const user = await users.findOne({ username }); - + if (user) { // If the user document exists, return its unique ID return user._id.toString(); diff --git a/integration-tests/tests/src/tests/dictionary.ts b/integration-tests/tests/src/tests/dictionary.ts index 89bed0af9c..329ee55bd7 100644 --- a/integration-tests/tests/src/tests/dictionary.ts +++ b/integration-tests/tests/src/tests/dictionary.ts @@ -363,8 +363,7 @@ describe("Dictionary", () => { expect(stringifiedAndParsed).deep.equals({ dict: values }); }); - // TODO: Unskip once https://github.com/realm/realm-core/issues/4805 is fixed - it.skip("throws a meaningful error if accessed after deletion", function (this: RealmContext) { + it("throws a meaningful error if accessed after deletion", function (this: RealmContext) { this.realm.write(() => { const item = this.realm.create("Item", {}); const dict = item.dict; From 7777d3e493b6c19fb9f5070e322d283aa958b22a Mon Sep 17 00:00:00 2001 From: gagik Date: Wed, 22 Feb 2023 13:47:24 +0100 Subject: [PATCH 03/15] Specify sync configuration --- .../tests/src/tests/sync/client-reset.ts | 30 ++++++++++++------- .../tests/src/utils/open-realm.ts | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/integration-tests/tests/src/tests/sync/client-reset.ts b/integration-tests/tests/src/tests/sync/client-reset.ts index 78066c7c12..99236c26f8 100644 --- a/integration-tests/tests/src/tests/sync/client-reset.ts +++ b/integration-tests/tests/src/tests/sync/client-reset.ts @@ -17,7 +17,15 @@ //////////////////////////////////////////////////////////////////////////// import { expect } from "chai"; -import Realm, { ClientResetMode, SessionStopPolicy, BSON } from "realm"; +import Realm, { + BSON, + ClientResetMode, + SessionStopPolicy, + User, + App, + Configuration, + ConfigurationWithSync, +} from "realm"; import { authenticateUserBefore, importAppBefore } from "../../hooks"; import { DogSchema, PersonSchema } from "../../schemas/person-and-dog-with-object-ids"; import { expectClientResetError } from "../../utils/expect-sync-error"; @@ -34,7 +42,7 @@ const FlexibleDogSchema = { ...DogSchema, properties: { ...DogSchema.properties, */ function addSubscriptions(realm: Realm): void { const subs = realm.subscriptions; - subs.update((mutableSubs: Realm.App.Sync.MutableSubscriptionSet) => { + subs.update((mutableSubs) => { mutableSubs.add(realm.objects(FlexiblePersonSchema.name)); mutableSubs.add(realm.objects(FlexibleDogSchema.name)); }); @@ -59,7 +67,7 @@ async function waitServerSideClientResetDiscardUnsyncedChangesCallbacks( const resetHandle = createPromiseHandle(); let afterCalled = false; let beforeCalled = false; - const config: Configuration = { + const config: ConfigurationWithSync = { schema, sync: { user, @@ -107,7 +115,7 @@ async function waitServerSideClientResetRecoveryCallbacks( let afterCalled = false; let beforeCalled = false; - const config: Configuration = { + const config: ConfigurationWithSync = { schema, sync: { user, @@ -154,7 +162,7 @@ async function waitSimulatedClientResetDiscardUnsyncedChangesCallbacks( let afterCalled = false; let beforeCalled = false; - const config: Configuration = { + const config: ConfigurationWithSync = { schema, sync: { user, @@ -204,7 +212,7 @@ async function waitSimulatedClientResetRecoverCallbacks( let afterCalled = false; let beforeCalled = false; - const config: Configuration = { + const config: ConfigurationWithSync = { schema, sync: { user, @@ -290,7 +298,7 @@ function getSchema(useFlexibleSync: boolean) { it(`manual client reset requires either error handler, client reset callback or both (${getPartialTestTitle( useFlexibleSync, )} sync)`, async function (this: RealmContext) { - const config: Configuration = { + const config: ConfigurationWithSync = { schema: getSchema(useFlexibleSync), sync: { // @ts-expect-error this setting is not for users to consume @@ -342,8 +350,8 @@ function getSchema(useFlexibleSync: boolean) { it(`handles manual simulated client resets by callback with ${getPartialTestTitle( useFlexibleSync, )} sync enabled`, async function (this: RealmContext) { - return new Promise((resolve, _) => { - const config: Configuration = { + return new Promise((resolve) => { + const config: ConfigurationWithSync = { schema: getSchema(useFlexibleSync), sync: { // @ts-expect-error this setting is not for users to consume @@ -352,7 +360,7 @@ function getSchema(useFlexibleSync: boolean) { user: this.user, clientReset: { mode: ClientResetMode.Manual, - onManual: (session: Realm.App.Sync.Session, path: string) => { + onManual: (session, path) => { expect(session).to.be.not.null; expect(path).to.not.empty; resolve(); @@ -376,7 +384,7 @@ function getSchema(useFlexibleSync: boolean) { useFlexibleSync, )} sync enabled`, async function (this: RealmContext) { return new Promise((resolve, reject) => { - const config: Configuration = { + const config: ConfigurationWithSync = { schema: getSchema(useFlexibleSync), sync: { // @ts-expect-error this setting is not for users to consume diff --git a/integration-tests/tests/src/utils/open-realm.ts b/integration-tests/tests/src/utils/open-realm.ts index 6d6f210ec4..902868e690 100644 --- a/integration-tests/tests/src/utils/open-realm.ts +++ b/integration-tests/tests/src/utils/open-realm.ts @@ -35,7 +35,7 @@ export type OpenRealmConfiguration = LocalConfiguration | SyncedConfiguration; * @returns */ export async function openRealm( - partialConfig: LocalConfiguration | SyncedConfiguration = {}, + partialConfig: LocalConfiguration | Partial = {}, user: User | undefined, ): Promise<{ config: Configuration; realm: Realm }> { if (!partialConfig.sync) { From fc76aff6cf9710bf2bd9f195c977297e016db8b7 Mon Sep 17 00:00:00 2001 From: gagik Date: Wed, 22 Feb 2023 14:28:11 +0100 Subject: [PATCH 04/15] Expect error issues. --- integration-tests/tests/src/utils/expect-sync-error.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/integration-tests/tests/src/utils/expect-sync-error.ts b/integration-tests/tests/src/utils/expect-sync-error.ts index 7099fb0509..33fc9cdddf 100644 --- a/integration-tests/tests/src/utils/expect-sync-error.ts +++ b/integration-tests/tests/src/utils/expect-sync-error.ts @@ -17,10 +17,9 @@ //////////////////////////////////////////////////////////////////////////// import { expect } from "chai"; +import { SyncError } from "realm"; import { openRealm } from "./open-realm"; -type Error = Realm.SyncError | (Realm.ClientResetError & { message: string; code: number }); - /** * Open a new Realm and perform an action, expecting a sync error to occur. Will * never resolve and therefore timeout if a sync error does not occur. @@ -36,7 +35,7 @@ export async function expectSyncError( config: Realm.Configuration, user: Realm.User, action: (realm: Realm) => void, - expectation: (error: Error) => void, + expectation: (error: SyncError) => void, ): Promise { return new Promise((resolve, reject) => { if (!config.sync) { @@ -48,7 +47,7 @@ export async function expectSyncError( ...config, sync: { ...config.sync, - onError(_, error: Error) { + onError(_, error: SyncError) { try { expectation(error); resolve(); From ee31b58a3c70e744ea3b1bfc01472b0dde06ab46 Mon Sep 17 00:00:00 2001 From: gagik Date: Wed, 22 Feb 2023 15:32:56 +0100 Subject: [PATCH 05/15] Fixes all over --- .../src/performance-tests/property-reads.ts | 12 ++++++--- .../tests/src/tests/listeners.ts | 3 +++ integration-tests/tests/src/tests/queries.ts | 9 ++++--- .../tests/src/tests/sync/asymmetric.ts | 1 + .../tests/src/tests/sync/client-reset.ts | 25 +++++++++++-------- .../tests/src/tests/sync/flexible.ts | 1 + .../tests/src/utils/benchmark.ts | 6 ++++- .../tests/src/utils/open-realm.ts | 19 +++++++++++--- 8 files changed, 54 insertions(+), 22 deletions(-) diff --git a/integration-tests/tests/src/performance-tests/property-reads.ts b/integration-tests/tests/src/performance-tests/property-reads.ts index e9e7e64e20..58273a1c51 100644 --- a/integration-tests/tests/src/performance-tests/property-reads.ts +++ b/integration-tests/tests/src/performance-tests/property-reads.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import Realm from "realm"; +import Realm, { ObjectSchema, PropertySchema } from "realm"; import { describePerformance } from "../utils/benchmark"; @@ -47,10 +47,16 @@ function describeTypeRead({ type, value, schema = [] }: TestParameters) { const objectSchemaName = type + "Class"; const propertyName = type + "Prop"; - const defaultSchema = { + const defaultSchema: ObjectSchema = { name: objectSchemaName, properties: { - [propertyName]: type, + [propertyName]: + typeof type === "object" + ? type + : ({ + type, + optional: true, + } as PropertySchema), }, }; diff --git a/integration-tests/tests/src/tests/listeners.ts b/integration-tests/tests/src/tests/listeners.ts index 63945a7eec..2f0a3ab258 100644 --- a/integration-tests/tests/src/tests/listeners.ts +++ b/integration-tests/tests/src/tests/listeners.ts @@ -66,6 +66,7 @@ describe("Realm Listeners", () => { }); this.realm.write(() => { + //@ts-expect-error Internal method this.realm._updateSchema([...this.realm.schema, { name: "MyClass", properties: { myField: "string" } }]); }); }); @@ -126,6 +127,7 @@ describe("Realm Listeners", () => { } }); this.realm.write(() => { + //@ts-expect-error Internal method this.realm._updateSchema([...this.realm.schema, { name: "MyClass", properties: { myField: "string" } }]); }); this.realm.write(() => { @@ -168,6 +170,7 @@ describe("Realm Listeners", () => { this.realm.create("Person", { age: 3, name: "Tom" }); }); this.realm.write(() => { + //@ts-expect-error Internal method this.realm._updateSchema([...this.realm.schema, { name: "MyClass", properties: { myField: "string" } }]); }); }); diff --git a/integration-tests/tests/src/tests/queries.ts b/integration-tests/tests/src/tests/queries.ts index dbadb9dfd0..a6450f6ff4 100644 --- a/integration-tests/tests/src/tests/queries.ts +++ b/integration-tests/tests/src/tests/queries.ts @@ -1689,9 +1689,12 @@ describe("Queries", () => { ); }); - persons = this.realm.objects(PersonSchema.name); - contacts = this.realm.objects(ContactSchema.name); - primitives = this.realm.objects(PrimitiveSchema.name); + //@ts-expect-error Test about to change + persons = realm.objects(PersonSchema.name); + //@ts-expect-error Test about to change + contacts = realm.objects(ContactSchema.name); + //@ts-expect-error Test about to change + primitives = realm.objects(PrimitiveSchema.name); }); describe("All objects", () => { diff --git a/integration-tests/tests/src/tests/sync/asymmetric.ts b/integration-tests/tests/src/tests/sync/asymmetric.ts index 9eeb3297c1..04529dedab 100644 --- a/integration-tests/tests/src/tests/sync/asymmetric.ts +++ b/integration-tests/tests/src/tests/sync/asymmetric.ts @@ -79,6 +79,7 @@ describe.skipIf(environment.missingServer, "Asymmetric sync", function () { it("an asymmetric schema cannot be queried through '_objectForObjectKey()'", function (this: RealmContext) { expect(() => { // A valid objectKey is not needed for this test + //@ts-expect-error Should not be correct usage this.realm._objectForObjectKey(PersonSchema.name, "12345"); }).to.throw("You cannot query an asymmetric object."); }); diff --git a/integration-tests/tests/src/tests/sync/client-reset.ts b/integration-tests/tests/src/tests/sync/client-reset.ts index 99236c26f8..d1068aea0b 100644 --- a/integration-tests/tests/src/tests/sync/client-reset.ts +++ b/integration-tests/tests/src/tests/sync/client-reset.ts @@ -25,6 +25,7 @@ import Realm, { App, Configuration, ConfigurationWithSync, + SyncError, } from "realm"; import { authenticateUserBefore, importAppBefore } from "../../hooks"; import { DogSchema, PersonSchema } from "../../schemas/person-and-dog-with-object-ids"; @@ -317,18 +318,20 @@ function getSchema(useFlexibleSync: boolean) { it(`handles manual simulated client resets with ${getPartialTestTitle( useFlexibleSync, )} sync enabled`, async function (this: RealmContext) { - await expectClientResetError( - { - schema: getSchema(useFlexibleSync), - sync: { - _sessionStopPolicy: SessionStopPolicy.Immediately, - ...(useFlexibleSync ? { flexible: true } : { partitionValue: getPartitionValue() }), - user: this.user, - clientReset: { - mode: ClientResetMode.Manual, - }, + const config: ConfigurationWithSync = { + schema: getSchema(useFlexibleSync), + sync: { + //@ts-expect-error Internal field + _sessionStopPolicy: SessionStopPolicy.Immediately, + ...(useFlexibleSync ? { flexible: true } : { partitionValue: getPartitionValue() }), + user: this.user, + clientReset: { + mode: ClientResetMode.Manual, }, }, + }; + await expectClientResetError( + config, this.user, (realm) => { if (useFlexibleSync) { @@ -339,7 +342,7 @@ function getSchema(useFlexibleSync: boolean) { // @ts-ignore calling undocumented method _simulateError session._simulateError(211, "Simulate Client Reset", "realm::sync::ProtocolError", false); // 211 -> diverging histories }, - (error) => { + (error: SyncError) => { expect(error.name).to.equal("ClientReset"); expect(error.message).to.equal("Simulate Client Reset"); expect(error.code).to.equal(211); diff --git a/integration-tests/tests/src/tests/sync/flexible.ts b/integration-tests/tests/src/tests/sync/flexible.ts index 60d502958e..1405a77fdc 100644 --- a/integration-tests/tests/src/tests/sync/flexible.ts +++ b/integration-tests/tests/src/tests/sync/flexible.ts @@ -216,6 +216,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("accepts { flexible: undefined } and a partition value", function () { expect(() => { + //@ts-expect-error Should show an error when defining flexible field with partition value. new Realm({ sync: { _sessionStopPolicy: SessionStopPolicy.Immediately, diff --git a/integration-tests/tests/src/utils/benchmark.ts b/integration-tests/tests/src/utils/benchmark.ts index 218b2f47fc..12a0052726 100644 --- a/integration-tests/tests/src/utils/benchmark.ts +++ b/integration-tests/tests/src/utils/benchmark.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import type { BenchmarkOpts } from "@thi.ng/bench"; +import type { BenchmarkOpts, BenchmarkResult } from "@thi.ng/bench"; import { openRealmBefore } from "../hooks"; @@ -26,6 +26,10 @@ const maxTimeMs = parseInt(typeof performanceMaxTime === "string" ? performanceM const DEFAULT_OPTIONS: Partial = { output: false, iter: 1000, size: 1000 }; +type BenchmarkContext = { + result: BenchmarkResult; +} & Mocha.Context; + export function itPerforms(title: string, fn: () => void, options?: Partial): void { it(title, async function (this: Partial & Mocha.Context) { const { benchmark } = await import("@thi.ng/bench"); diff --git a/integration-tests/tests/src/utils/open-realm.ts b/integration-tests/tests/src/utils/open-realm.ts index 902868e690..105e68c231 100644 --- a/integration-tests/tests/src/utils/open-realm.ts +++ b/integration-tests/tests/src/utils/open-realm.ts @@ -16,15 +16,26 @@ // //////////////////////////////////////////////////////////////////////////// -import Realm, { Configuration, SyncConfiguration, User, BSON } from "realm"; - // Either the sync property is left out (local Realm) export type LocalConfiguration = Omit & { sync?: never }; // Or the sync parameter is present export type SyncedConfiguration = Omit & { sync?: Partial; }; -export type OpenRealmConfiguration = LocalConfiguration | SyncedConfiguration; +import Realm, { + Configuration, + User, + BSON, + ConfigurationWithSync, + ConfigurationWithoutSync, + SyncConfiguration, +} from "realm"; + +type ConfigurationWithSyncPartial = Omit & { + sync: Partial; +}; + +export type OpenRealmConfiguration = ConfigurationWithoutSync | ConfigurationWithSyncPartial; /** * Open a Realm for test usage with the specified config. By default this will use @@ -36,7 +47,7 @@ export type OpenRealmConfiguration = LocalConfiguration | SyncedConfiguration; */ export async function openRealm( partialConfig: LocalConfiguration | Partial = {}, - user: User | undefined, + user: User, ): Promise<{ config: Configuration; realm: Realm }> { if (!partialConfig.sync) { const config = createLocalConfig(partialConfig as LocalConfiguration); From ccc2c4eb7067cc1c5d1a95e83ad0be11d8e425ed Mon Sep 17 00:00:00 2001 From: Gagik Amaryan Date: Fri, 24 Feb 2023 11:52:37 +0100 Subject: [PATCH 06/15] Apply suggestions from code review Co-authored-by: Andrew Meyer --- integration-tests/tests/src/tests/sync/asymmetric.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/tests/src/tests/sync/asymmetric.ts b/integration-tests/tests/src/tests/sync/asymmetric.ts index 04529dedab..288edb3996 100644 --- a/integration-tests/tests/src/tests/sync/asymmetric.ts +++ b/integration-tests/tests/src/tests/sync/asymmetric.ts @@ -79,7 +79,7 @@ describe.skipIf(environment.missingServer, "Asymmetric sync", function () { it("an asymmetric schema cannot be queried through '_objectForObjectKey()'", function (this: RealmContext) { expect(() => { // A valid objectKey is not needed for this test - //@ts-expect-error Should not be correct usage + //@ts-expect-error Internal method this.realm._objectForObjectKey(PersonSchema.name, "12345"); }).to.throw("You cannot query an asymmetric object."); }); From c8fffaee76858d8a89cc53f50b628f8e19d6957c Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Fri, 4 Aug 2023 11:48:42 +0200 Subject: [PATCH 07/15] Fix failing tests --- integration-tests/tests/src/tests/dictionary.ts | 4 +++- integration-tests/tests/src/tests/queries.ts | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/integration-tests/tests/src/tests/dictionary.ts b/integration-tests/tests/src/tests/dictionary.ts index 329ee55bd7..68364df9c3 100644 --- a/integration-tests/tests/src/tests/dictionary.ts +++ b/integration-tests/tests/src/tests/dictionary.ts @@ -370,7 +370,9 @@ describe("Dictionary", () => { this.realm.delete(item); expect(() => { JSON.stringify(dict); - }).throws("Access to invalidated Dictionary object"); + }).throws( + "Dictionary is no longer valid. Either the parent object was deleted or the containing Realm has been invalidated or closed.", + ); }); }); diff --git a/integration-tests/tests/src/tests/queries.ts b/integration-tests/tests/src/tests/queries.ts index a6450f6ff4..f1f016a9e0 100644 --- a/integration-tests/tests/src/tests/queries.ts +++ b/integration-tests/tests/src/tests/queries.ts @@ -1690,11 +1690,11 @@ describe("Queries", () => { }); //@ts-expect-error Test about to change - persons = realm.objects(PersonSchema.name); + persons = this.realm.objects(PersonSchema.name); //@ts-expect-error Test about to change - contacts = realm.objects(ContactSchema.name); + contacts = this.realm.objects(ContactSchema.name); //@ts-expect-error Test about to change - primitives = realm.objects(PrimitiveSchema.name); + primitives = this.realm.objects(PrimitiveSchema.name); }); describe("All objects", () => { From 2b302d110ce6bf640c0487db3906bd690f0dc002 Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Wed, 9 Aug 2023 14:46:27 +0200 Subject: [PATCH 08/15] Remove errors form open-behavior --- .../tests/src/tests/sync/open-behavior.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/integration-tests/tests/src/tests/sync/open-behavior.ts b/integration-tests/tests/src/tests/sync/open-behavior.ts index ea47bf7563..6127d64e6c 100644 --- a/integration-tests/tests/src/tests/sync/open-behavior.ts +++ b/integration-tests/tests/src/tests/sync/open-behavior.ts @@ -129,7 +129,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error const enum is removed at runtime, should either remove const or leave this as is. _sessionStopPolicy: "immediately", //@ts-expect-error const enum is removed at runtime, should either remove const or leave this as is. newRealmFileBehavior: { type: "downloadBeforeOpen" }, @@ -188,7 +187,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", //@ts-expect-error TYPEBUG: cannot access const enum at runtime existingRealmFileBehavior: { type: "downloadBeforeOpen" }, @@ -209,7 +207,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", newRealmFileBehavior: { //@ts-expect-error TYPEBUG: cannot access const enum at runtime @@ -255,7 +252,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", existingRealmFileBehavior: { //@ts-expect-error TYPEBUG: cannot access const enum at runtime @@ -318,7 +314,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", newRealmFileBehavior: { //@ts-expect-error TYPEBUG: cannot access const enum at runtime @@ -399,7 +394,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", existingRealmFileBehavior: { //@ts-expect-error TYPEBUG: cannot access const enum at runtime @@ -466,7 +460,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", existingRealmFileBehavior: { //@ts-expect-error TYPEBUG: cannot access const enum at runtime @@ -495,7 +488,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", //@ts-expect-error TYPEBUG: cannot access const enum at runtime newRealmFileBehavior: { type: "downloadBeforeOpen" }, @@ -530,7 +522,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", //@ts-expect-error TYPEBUG: cannot access const enum at runtime newRealmFileBehavior: { type: "downloadBeforeOpen" }, @@ -553,7 +544,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", //@ts-expect-error TYPEBUG: cannot access const enum at runtime newRealmFileBehavior: { type: "downloadBeforeOpen" }, @@ -595,7 +585,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", //@ts-expect-error testing invalid value for newRealmFileBehaviour newRealmFileBehavior: { type: "foo" }, @@ -609,7 +598,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", //@ts-expect-error testing invalid value for newRealmFileBehaviour newRealmFileBehavior: { type: "openLocalRealm", timeOutBehavior: "foo" }, @@ -623,7 +611,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", //@ts-expect-error testing invalid value for newRealmFileBehaviour newRealmFileBehavior: { type: "openLocalRealm", timeOut: "bar" }, From 60bbcee04d62dc707102e900e11e145294f8be1f Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Thu, 10 Aug 2023 09:06:09 +0200 Subject: [PATCH 09/15] Fix a few more types --- integration-tests/tests/src/hooks/import-app-before.ts | 4 ++-- integration-tests/tests/src/hooks/open-realm-before.ts | 4 +--- integration-tests/tests/src/tests/dictionary.ts | 2 +- integration-tests/tests/src/tests/sync/open-behavior.ts | 1 - 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/integration-tests/tests/src/hooks/import-app-before.ts b/integration-tests/tests/src/hooks/import-app-before.ts index 9b63ef7780..3ee60685dd 100644 --- a/integration-tests/tests/src/hooks/import-app-before.ts +++ b/integration-tests/tests/src/hooks/import-app-before.ts @@ -40,7 +40,7 @@ export function importAppBefore(config: AppConfig | { config: AppConfig }, sdkCo return importAppBefore(config.config, sdkConfig); } - before(importAppBefore.name, async function (this: Partial & Mocha.Context) { + before(importAppBefore.name, async function (this: AppContext & Mocha.Context) { // Importing an app might take up to 5 minutes when the app has a MongoDB Atlas service enabled. this.longTimeout(); if (this.app) { @@ -55,7 +55,7 @@ export function importAppBefore(config: AppConfig | { config: AppConfig }, sdkCo .map(([service]) => { if ("sync" in service.config) { return service.config.sync.database_name; - } else if ("flexible_sync" in service.config) { + } else { return service.config.flexible_sync.database_name; } }) diff --git a/integration-tests/tests/src/hooks/open-realm-before.ts b/integration-tests/tests/src/hooks/open-realm-before.ts index cf7b1e46d1..bd18d6c71b 100644 --- a/integration-tests/tests/src/hooks/open-realm-before.ts +++ b/integration-tests/tests/src/hooks/open-realm-before.ts @@ -29,9 +29,7 @@ import { openRealm, OpenRealmConfiguration } from "../utils/open-realm"; * @returns Promise which resolves when complete */ export function openRealmHook(config: OpenRealmConfiguration = {}) { - return async function openRealmHandler( - this: Partial & Partial & Mocha.Context, - ): Promise { + return async function openRealmHandler(this: Partial & UserContext & Mocha.Context): Promise { this.longTimeout(); if (this.realm) { throw new Error("Unexpected realm on context, use only one openRealmBefore per test"); diff --git a/integration-tests/tests/src/tests/dictionary.ts b/integration-tests/tests/src/tests/dictionary.ts index 68364df9c3..5420204729 100644 --- a/integration-tests/tests/src/tests/dictionary.ts +++ b/integration-tests/tests/src/tests/dictionary.ts @@ -52,7 +52,7 @@ const EmbeddedChild = { }, }; -const DictTypedSchema = { +const DictTypedSchema: Realm.ObjectSchema = { name: "TypedDictionary", properties: { dict1: { type: "dictionary", objectType: "Children" }, // dictionary of objects is nullable by default diff --git a/integration-tests/tests/src/tests/sync/open-behavior.ts b/integration-tests/tests/src/tests/sync/open-behavior.ts index 6127d64e6c..8e5b3612fe 100644 --- a/integration-tests/tests/src/tests/sync/open-behavior.ts +++ b/integration-tests/tests/src/tests/sync/open-behavior.ts @@ -460,7 +460,6 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - _sessionStopPolicy: "immediately", existingRealmFileBehavior: { //@ts-expect-error TYPEBUG: cannot access const enum at runtime type: "downloadBeforeOpen", From 53f56a2e1f0e791be9b330fa82022a94791527c5 Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Thu, 10 Aug 2023 09:40:03 +0200 Subject: [PATCH 10/15] Allow any list or result to enter the delete method --- packages/realm/src/Realm.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/realm/src/Realm.ts b/packages/realm/src/Realm.ts index 228226622c..ffdfd5e9ff 100644 --- a/packages/realm/src/Realm.ts +++ b/packages/realm/src/Realm.ts @@ -18,7 +18,9 @@ import { AggregatePipelineStage, + AnyList, AnyRealmObject, + AnyResults, ApiKey, ApiKeyAuth, App, @@ -882,7 +884,7 @@ export class Realm { * Deletes the provided Realm object, or each one inside the provided collection. * @param subject - The Realm object to delete, or a collection containing multiple Realm objects to delete. */ - delete(subject: AnyRealmObject | AnyRealmObject[] | List | Results): void { + delete(subject: AnyRealmObject | AnyRealmObject[] | AnyList | AnyResults): void { assert.inTransaction(this, "Can only delete objects within a transaction."); assert.object(subject, "subject"); if (subject instanceof RealmObject) { From 6eb0d88585b9de998fce380a29591f462adf558e Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Thu, 10 Aug 2023 11:50:54 +0200 Subject: [PATCH 11/15] More fixes --- .../tests/src/hooks/open-realm-before.ts | 6 +- .../tests/src/tests/linking-objects.ts | 2 +- integration-tests/tests/src/tests/list.ts | 2 +- .../tests/src/tests/sync/realm.ts | 118 +++++++++--------- .../tests/src/tests/sync/sync-session.ts | 11 +- integration-tests/tests/src/typings.d.ts | 10 +- packages/realm/src/ClassMap.ts | 7 +- packages/realm/src/Realm.ts | 16 +-- packages/realm/src/RealmListeners.ts | 6 +- packages/realm/src/app-services/App.ts | 6 +- .../src/app-services/FunctionsFactory.ts | 2 +- .../src/app-services/MongoDBCollection.ts | 2 +- packages/realm/src/app-services/User.ts | 22 ++-- packages/realm/src/schema/types.ts | 5 - 14 files changed, 103 insertions(+), 112 deletions(-) diff --git a/integration-tests/tests/src/hooks/open-realm-before.ts b/integration-tests/tests/src/hooks/open-realm-before.ts index bd18d6c71b..40c3bebcb9 100644 --- a/integration-tests/tests/src/hooks/open-realm-before.ts +++ b/integration-tests/tests/src/hooks/open-realm-before.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import Realm from "realm"; +import Realm, { User } from "realm"; import { openRealm, OpenRealmConfiguration } from "../utils/open-realm"; @@ -37,7 +37,7 @@ export function openRealmHook(config: OpenRealmConfiguration = {}) { this.closeRealm = async () => { console.warn("🤷 Skipped closing a Realm that failed to open"); }; - const { realm, config: actualConfig } = await openRealm(config, this.user); + const { realm, config: actualConfig } = await openRealm(config, this.user as unknown as User); this.realm = realm; this.closeRealm = async ({ clearTestState = true, @@ -56,7 +56,7 @@ export function openRealmHook(config: OpenRealmConfiguration = {}) { Realm.clearTestState(); } if (reopen) { - const { realm } = await openRealm(actualConfig, this.user); + const { realm } = await openRealm(actualConfig, this.user as unknown as User); this.realm = realm; } }; diff --git a/integration-tests/tests/src/tests/linking-objects.ts b/integration-tests/tests/src/tests/linking-objects.ts index b34839d0ec..55f6e939a5 100644 --- a/integration-tests/tests/src/tests/linking-objects.ts +++ b/integration-tests/tests/src/tests/linking-objects.ts @@ -21,7 +21,7 @@ import { expect } from "chai"; import Realm from "realm"; import { openRealmBeforeEach } from "../hooks"; -function names(results: Realm.Collection | Realm.Results) { +function names(results: Realm.Results | Realm.Results) { return results.map(function (object: IPersonSchema) { return object.name; }); diff --git a/integration-tests/tests/src/tests/list.ts b/integration-tests/tests/src/tests/list.ts index 76571460f6..8f7f07c3bd 100644 --- a/integration-tests/tests/src/tests/list.ts +++ b/integration-tests/tests/src/tests/list.ts @@ -30,7 +30,7 @@ const DATE1 = new Date(1); const DATE2 = new Date(2); const DATE3 = new Date(3); -const PersonSchema: Realm.ObjectSchema = { +const PersonSchema = { name: "PersonObject", properties: { name: "string", diff --git a/integration-tests/tests/src/tests/sync/realm.ts b/integration-tests/tests/src/tests/sync/realm.ts index a198d3b1ca..dc18ec11cf 100644 --- a/integration-tests/tests/src/tests/sync/realm.ts +++ b/integration-tests/tests/src/tests/sync/realm.ts @@ -152,7 +152,7 @@ const IndexedTypesSchema = { }, }; -const DefaultValuesSchema = { +const DefaultValuesSchema: Realm.ObjectSchema = { name: "DefaultValuesObject", properties: { boolCol: { type: "bool", default: true }, @@ -168,14 +168,14 @@ const DefaultValuesSchema = { }, }; -const ObjectSchema = { +const ObjectSchema: Realm.ObjectSchema = { name: "IntObject", properties: { intCol: { type: "int", default: 1 }, }, }; -const LinkTypesSchema = { +const LinkTypesSchema: Realm.ObjectSchema = { name: "LinkTypesObject", properties: { objectCol: "TestObject", @@ -185,7 +185,7 @@ const LinkTypesSchema = { }, }; -const LinkingObjectsObjectSchema = { +const LinkingObjectsObjectSchema: Realm.ObjectSchema = { name: "LinkingObjectsObject", properties: { value: "int", @@ -789,10 +789,10 @@ describe("Realmtest", () => { }); it("diffed updates only trigger notifications for changed values", async function (this: RealmContext) { - type iAllPrimaryTypesChanges = [Realm.Collection, CollectionChangeSet]; + type iAllPrimaryTypesChanges = [Realm.Results, CollectionChangeSet]; let resolve: ((value: iAllPrimaryTypesChanges) => void) | undefined; this.realm.objects(AllPrimaryTypesSchema.name).addListener((objects, changes) => { - resolve?.([objects, changes]); + resolve?.([objects as unknown as Realm.Results, changes]); resolve = undefined; }); @@ -977,13 +977,11 @@ describe("Realmtest", () => { objectCol: { doubleCol: 0 }, arrayCol: [{ doubleCol: 2 }], }, - //@ts-expect-error: TYPEBUG: expects a Realm.UpdateMode instead of boolean "true" true, ); const objects = this.realm.objects(AllPrimaryTypesSchema.name); expect(objects.length).equals(2); this.realm.create( - //@ts-expect-error: TYPEBUG: expects a Realm.UpdateMode instead of boolean "true" AllPrimaryTypesSchema.name, { primaryCol: "0", @@ -1009,15 +1007,12 @@ describe("Realmtest", () => { expect(obj0.dataCol.byteLength).equals(2); expect(obj0.objectCol).equals(null); expect(obj0.arrayCol.length).equals(1); - //@ts-expect-error: TYPEBUG: expects a Realm.UpdateMode instead of boolean "true" this.realm.create(AllPrimaryTypesSchema.name, { primaryCol: "0" }, true); - //@ts-expect-error: TYPEBUG: expects a Realm.UpdateMode instead of boolean "true" this.realm.create(AllPrimaryTypesSchema.name, { primaryCol: "1" }, true); expect(obj0.stringCol).equals("2"); expect(obj0.objectCol).equals(null); expect(obj1.objectCol.doubleCol).equals(0); this.realm.create( - //@ts-expect-error: TYPEBUG: expects a Realm.UpdateMode instead of boolean "true" AllPrimaryTypesSchema.name, { primaryCol: "0", @@ -1035,9 +1030,7 @@ describe("Realmtest", () => { expect(obj0.dataCol.byteLength).equals(2); expect(obj0.objectCol.doubleCol).equals(0); expect(obj0.arrayCol.length).equals(1); - //@ts-expect-error: TYPEBUG: expects a Realm.UpdateMode instead of boolean "true" this.realm.create(AllPrimaryTypesSchema.name, { primaryCol: "0", objectCol: undefined }, true); - //@ts-expect-error: TYPEBUG: expects a Realm.UpdateMode instead of boolean "true" this.realm.create(AllPrimaryTypesSchema.name, { primaryCol: "1", objectCol: null }, true); expect(obj0.objectCol.doubleCol).equals(0); expect(obj1.objectCol).equals(null); @@ -1048,7 +1041,6 @@ describe("Realmtest", () => { }); expect(obj.valueCol).equals(0); this.realm.create( - //@ts-expect-error: TYPEBUG: expects a Realm.UpdateMode instead of boolean "true" StringPrimarySchema.name, { primaryCol: "0", @@ -1087,12 +1079,13 @@ describe("Realmtest", () => { const createAndTestObject = () => { const object = realm.create(ObjectSchema.name, {}); + //@ts-expect-error intCol is an object, but typings indicate it could be a string expect(object.intCol).equals(ObjectSchema.properties.intCol.default); }; realm.write(createAndTestObject); - ObjectSchema.properties.intCol.default++; + ((ObjectSchema.properties.intCol as unknown as Realm.PropertySchema).default as number)++; realm = new Realm({ schema: [ObjectSchema] }); realm.write(createAndTestObject); @@ -1117,11 +1110,13 @@ describe("Realmtest", () => { return {}; } + //@ts-expect-error InvalidObject is not a proper schema expect(() => new Realm({ schema: [InvalidObject] })).throws("Class 'InvalidObject' must extend Realm.Object"); Object.setPrototypeOf(InvalidObject, Realm.Object); Object.setPrototypeOf(InvalidObject.prototype, Realm.Object.prototype); + //@ts-expect-error InvalidObject is not a proper schema expect(() => new Realm({ schema: [InvalidObject] })).throws( "Expected 'schema static' to be an object, got undefined", ); @@ -1133,10 +1128,11 @@ describe("Realmtest", () => { }, }; Object.setPrototypeOf(InvalidObject, Realm.Object); + //@ts-expect-error InvalidObject is not a proper schema let realm = new Realm({ schema: [CustomObject, InvalidObject] }); realm.write(() => { - let object = realm.create("CustomObject", { intCol: 1 }); + let object: CustomObject = realm.create("CustomObject", { intCol: 1 }); expect(object).instanceof(CustomObject); expect(customCreated).equals(0); @@ -1163,6 +1159,7 @@ describe("Realmtest", () => { }).throws("Constructor was not registered in the schema for this Realm"); realm.close(); + //@ts-expect-error Invalid object is not a proper schema realm = new Realm({ schema: [CustomObject, InvalidObject] }); const obj = realm.objects("CustomObject")[0]; expect(realm.objects("CustomObject")[0]).instanceof(CustomObject); @@ -1224,52 +1221,52 @@ describe("Realmtest", () => { }); }); - // TODO: Refactor and re-enable - it.skip("writeCopyTo works", async function (this: RealmContext) { - const realm = new Realm({ - schema: [schemas.IntPrimary, schemas.AllTypes, schemas.TestObject, schemas.LinkToAllTypes], - }); + // TODO: Refactor and re-enable/uncomment (commented out to avoid type errors) + // it.skip("writeCopyTo works", async function (this: RealmContext) { + // const realm = new Realm({ + // schema: [schemas.IntPrimary, schemas.AllTypes, schemas.TestObject, schemas.LinkToAllTypes], + // }); - realm.write(() => { - realm.create("TestObject", { doubleCol: 1 }); - }); - TestCase.assertEqual(1, realm.objects("TestObject").length); + // realm.write(() => { + // realm.create("TestObject", { doubleCol: 1 }); + // }); + // TestCase.assertEqual(1, realm.objects("TestObject").length); - TestCase.assertThrowsContaining(() => { - realm.writeCopyTo(); - }, "Expected value to be an object, got undefined"); + // TestCase.assertThrowsContaining(() => { + // realm.writeCopyTo(); + // }, "Expected value to be an object, got undefined"); - TestCase.assertThrowsContaining(() => { - realm.writeCopyTo(34); - }, "Expected value to be an object, got a number"); + // TestCase.assertThrowsContaining(() => { + // realm.writeCopyTo(34); + // }, "Expected value to be an object, got a number"); - // make sure that copies are in the same directory as the original file - // that is important for running tests on mobile devices, - // so we don't have issues with permissisons - const copyName = realm.path + ".copy.realm"; + // // make sure that copies are in the same directory as the original file + // // that is important for running tests on mobile devices, + // // so we don't have issues with permissisons + // const copyName = realm.path + ".copy.realm"; - const copyConfig = { path: copyName }; - realm.writeCopyTo(copyConfig); + // const copyConfig = { path: copyName }; + // realm.writeCopyTo(copyConfig); - const realmCopy = new Realm(copyConfig); - TestCase.assertEqual(1, realmCopy.objects("TestObject").length); - realmCopy.close(); + // const realmCopy = new Realm(copyConfig); + // TestCase.assertEqual(1, realmCopy.objects("TestObject").length); + // realmCopy.close(); - const encryptedCopyName = realm.path + ".copy-encrypted.realm"; + // const encryptedCopyName = realm.path + ".copy-encrypted.realm"; - const encryptionKey = new Int8Array(64); - for (let i = 0; i < 64; i++) { - encryptionKey[i] = 1; - } - realm.writeCopyTo({ path: encryptedCopyName, encryptionKey }); + // const encryptionKey = new Int8Array(64); + // for (let i = 0; i < 64; i++) { + // encryptionKey[i] = 1; + // } + // realm.writeCopyTo({ path: encryptedCopyName, encryptionKey }); - const encryptedCopyConfig = { path: encryptedCopyName, encryptionKey: encryptionKey }; - const encryptedRealmCopy = new Realm(encryptedCopyConfig); - TestCase.assertEqual(1, encryptedRealmCopy.objects("TestObject").length); - encryptedRealmCopy.close(); + // const encryptedCopyConfig = { path: encryptedCopyName, encryptionKey: encryptionKey }; + // const encryptedRealmCopy = new Realm(encryptedCopyConfig); + // TestCase.assertEqual(1, encryptedRealmCopy.objects("TestObject").length); + // encryptedRealmCopy.close(); - realm.close(); - }); + // realm.close(); + // }); it("creating objects without properties work", async function (this: RealmContext) { this.realm.write(() => { @@ -1322,7 +1319,6 @@ describe("Realmtest", () => { }); realm.close(); - //@ts-expect-error TYPEBUG: opening without a config works in legacy test but is not accepted by typesystem. return Realm.open().then((realm) => { const objects = realm.objects("TestObject"); expect(objects.length).equals(1); @@ -1461,7 +1457,7 @@ describe("Realmtest", () => { }); }); - const NotIndexed = { + const NotIndexed: Realm.ObjectSchema = { name: "NotIndexedObject", properties: { floatCol: { type: "float", indexed: false }, @@ -1521,7 +1517,7 @@ describe("Realmtest", () => { Realm.clearTestState(); }); - it("onFirstOpen properly intializes data", () => { + it("onFirstOpen properly initializes data", () => { const data = [1, 2, 3]; const initializer = (r: Realm) => { data.forEach((n) => r.create(IntOnlySchema.name, { intCol: n })); @@ -1674,7 +1670,6 @@ describe("Realmtest", () => { "Object type 'InvalidClass' not found in schema.", ); - //@ts-expect-error objectForprimaryKey with object as key expect(() => this.realm.objectForPrimaryKey("IntPrimaryObject", { foo: "bar" })).throws( "Expected value to be a number or bigint, got an object", ); @@ -1727,6 +1722,7 @@ describe("Realmtest", () => { expect(notificationCount).equals(3); expect(secondNotificationCount).equals(1); + // @ts-expect-error Invalid listener event // eslint-disable-next-line @typescript-eslint/no-empty-function expect(() => this.realm.addListener("invalid", () => {})).throws( "Unknown event name 'invalid': only 'change', 'schema' and 'beforenotify' are supported.", @@ -1767,11 +1763,11 @@ describe("Realmtest", () => { prop.optional = val.optional || false; prop.indexed = val.indexed || false; } else { - prop = { type: val as unknown as string, indexed: false, optional: false }; + prop = { type: val as unknown as Realm.PropertyTypeName, indexed: false, optional: false }; } if (prop.type.includes("?")) { prop.optional = true; - prop.type = prop.type.replace("?", ""); + prop.type = prop.type.replace("?", "") as unknown as Realm.PropertyTypeName; } if (prop.type.includes("[]")) { prop.objectType = prop.type.replace("[]", ""); @@ -1839,12 +1835,12 @@ describe("Realmtest", () => { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { - realm1.addListener("schema", (realm: Realm, event: string, schema: Realm.ObjectSchema[]) => { + realm1.addListener("schema", (realm, event, schema) => { try { expect(event).equals("schema"); - expect(schema.length).equals(1); + expect(schema?.length).equals(1); expect(realm.schema.length).equals(1); - expect(schema[0].name).equals("TestObject"); + expect(schema?.[0]?.name).equals("TestObject"); expect(realm1.schema.length).equals(1); expect(realm.schema[0].name).equals("TestObject"); resolve(); diff --git a/integration-tests/tests/src/tests/sync/sync-session.ts b/integration-tests/tests/src/tests/sync/sync-session.ts index 89395e494b..88a15bc3bc 100644 --- a/integration-tests/tests/src/tests/sync/sync-session.ts +++ b/integration-tests/tests/src/tests/sync/sync-session.ts @@ -65,8 +65,8 @@ function waitForConnectionState(session: Realm.App.Sync.Session, state: string) }; } -function getSyncConfiguration(user: Realm.User, partition: string): Realm.Configuration { - const realmConfig = { +function getSyncConfiguration(user: Realm.User, partition: string): Realm.ConfigurationWithSync { + const realmConfig: Realm.Configuration = { schema: [ { name: "Dog", @@ -116,10 +116,7 @@ function createObjects(user: Realm.User, partition: string): Promise { }); } -async function seedDataWithExternalUser( - app: Realm.App, - partition: string, -) { +async function seedDataWithExternalUser(app: Realm.App, partition: string) { const credentials = Realm.Credentials.anonymous(); const user = await app.logIn(credentials); const realm = await createObjects(user, partition); @@ -183,7 +180,7 @@ describe("SessionTest", () => { config.sync.customHttpHeaders = { language: "English" }; const realm = new Realm(config); const session = realm.syncSession; - expect(session.config.customHttpHeaders.language).equals( + expect(session?.config.customHttpHeaders?.language).equals( "English", "Synced realm does not contain the expected customHttpHeader", ); diff --git a/integration-tests/tests/src/typings.d.ts b/integration-tests/tests/src/typings.d.ts index f6d4cfafbd..aef8b05e3f 100644 --- a/integration-tests/tests/src/typings.d.ts +++ b/integration-tests/tests/src/typings.d.ts @@ -16,10 +16,6 @@ // //////////////////////////////////////////////////////////////////////////// -type RealmObject = import("realm").Object; -type App = import("realm").App; -type User = import("realm").User; -type Configuration = import("realm").Configuration; //type BenchmarkResult = import("@thi.ng/bench").BenchmarkResult; interface fs { @@ -160,8 +156,8 @@ declare namespace Mocha { } // Mocha contexts made available by hooks -type AppContext = { app: App; databaseName: string } & Mocha.Context; -type UserContext = { user: User } & Mocha.Context; +type AppContext = { app: Realm.App; databaseName: string } & Mocha.Context; +type UserContext = { user: Realm.User } & Mocha.Context; type CloseRealmOptions = { deleteFile: boolean; clearTestState: boolean; reopen: boolean }; type RealmContext = { realm: Realm; @@ -172,7 +168,7 @@ type RealmContext = { closeRealm(options?: Partial): Promise; } & Mocha.Context; type RealmObjectContext> = { - object: RealmObject & T; + object: Realm.Object & T; } & RealmContext; // type BenchmarkContext = { // result: BenchmarkResult; diff --git a/packages/realm/src/ClassMap.ts b/packages/realm/src/ClassMap.ts index 11b3fe784f..76a40ec2b8 100644 --- a/packages/realm/src/ClassMap.ts +++ b/packages/realm/src/ClassMap.ts @@ -18,7 +18,6 @@ import { CanonicalObjectSchema, - CanonicalRealmSchema, Constructor, INTERNAL, KEY_ARRAY, @@ -110,7 +109,11 @@ export class ClassMap { }); } - constructor(realm: Realm, realmSchema: readonly binding.ObjectSchema[], canonicalRealmSchema: CanonicalRealmSchema) { + constructor( + realm: Realm, + realmSchema: readonly binding.ObjectSchema[], + canonicalRealmSchema: CanonicalObjectSchema[], + ) { this.mapping = Object.fromEntries( realmSchema.map((objectSchema, index) => { const canonicalObjectSchema: CanonicalObjectSchema = canonicalRealmSchema[index]; diff --git a/packages/realm/src/Realm.ts b/packages/realm/src/Realm.ts index ffdfd5e9ff..c3cb318e89 100644 --- a/packages/realm/src/Realm.ts +++ b/packages/realm/src/Realm.ts @@ -1295,10 +1295,10 @@ function isEmbedded(objectSchema: binding.ObjectSchema): boolean { // We need these type aliases because of https://github.com/Swatinem/rollup-plugin-dts/issues/223 // We cannot move this to a different file and rely on module declarations because of https://github.com/Swatinem/rollup-plugin-dts/issues/168 -type AppType = App< - FunctionsFactoryType, - CustomDataType ->; +type AppType< + FunctionsFactoryType extends DefaultFunctionsFactory = DefaultFunctionsFactory, + CustomDataType extends DefaultObject = DefaultObject, +> = App; type BSONType = typeof BSON; type ClientResetModeType = ClientResetMode; type CollectionType< @@ -1338,10 +1338,10 @@ type TypesType = typeof Types; type UpdateModeType = UpdateMode; type UserStateType = UserState; type UserType< - FunctionsFactoryType = DefaultFunctionsFactory, - CustomDataType = DefaultObject, - UserProfileDataType = DefaultUserProfileData, -> = User; + UserFunctionsType extends DefaultFunctionsFactory = DefaultFunctionsFactory, + UserCustomDataType extends DefaultObject = DefaultObject, + UserProfileDataType extends DefaultUserProfileData = DefaultUserProfileData, +> = User; type BaseSubscriptionSetType = BaseSubscriptionSet; type LogLevelType = LogLevel; diff --git a/packages/realm/src/RealmListeners.ts b/packages/realm/src/RealmListeners.ts index 5ac74ee954..7b0ac10bcc 100644 --- a/packages/realm/src/RealmListeners.ts +++ b/packages/realm/src/RealmListeners.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import { CanonicalRealmSchema, Realm } from "./internal"; +import { CanonicalObjectSchema, Realm } from "./internal"; export enum RealmEvent { Change = "change", @@ -24,7 +24,7 @@ export enum RealmEvent { BeforeNotify = "beforenotify", } -export type RealmListenerCallback = (realm: Realm, name: RealmEvent, schema?: CanonicalRealmSchema) => void; +export type RealmListenerCallback = (realm: Realm, name: RealmEvent, schema?: CanonicalObjectSchema[]) => void; // Temporary functions to work between event names and corresponding enums // TODO: We should update the external API to take a `RealmEvent` instead of a string. @@ -41,7 +41,7 @@ class RealmListeners { private listeners = new Set(); // Combined callback which runs all listener callbacks in one call. - notify(schema?: CanonicalRealmSchema): void { + notify(schema?: CanonicalObjectSchema[]): void { // Spreading to an array to avoid firing listeners that gets added from another listener for (const callback of [...this.listeners]) { callback(this.realm, this.eventType, schema); diff --git a/packages/realm/src/app-services/App.ts b/packages/realm/src/app-services/App.ts index 3ae02efe07..8351463294 100644 --- a/packages/realm/src/app-services/App.ts +++ b/packages/realm/src/app-services/App.ts @@ -20,6 +20,7 @@ import { AnyUser, Credentials, DefaultFunctionsFactory, + DefaultObject, EmailPasswordAuth, Listeners, Sync, @@ -104,7 +105,10 @@ type AppListenerToken = binding.AppSubscriptionToken; * const app = new App({ id: "my-app-qwert" }); * ``` */ -export class App> { +export class App< + FunctionsFactoryType extends DefaultFunctionsFactory = DefaultFunctionsFactory, + CustomDataType extends DefaultObject = DefaultObject, +> { // eslint-disable-next-line @typescript-eslint/no-explicit-any private static appById = new Map>(); // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/realm/src/app-services/FunctionsFactory.ts b/packages/realm/src/app-services/FunctionsFactory.ts index 1c6b87b9e2..ee089269fe 100644 --- a/packages/realm/src/app-services/FunctionsFactory.ts +++ b/packages/realm/src/app-services/FunctionsFactory.ts @@ -33,7 +33,7 @@ export type DefaultFunctionsFactory = { [name: string]: AppServicesFunction; }; -export function createFactory(user: User, serviceName: string | undefined): T { +export function createFactory(user: User, serviceName: string | undefined): T { return new Proxy( {}, { diff --git a/packages/realm/src/app-services/MongoDBCollection.ts b/packages/realm/src/app-services/MongoDBCollection.ts index 1aa02665f0..297d931cfa 100644 --- a/packages/realm/src/app-services/MongoDBCollection.ts +++ b/packages/realm/src/app-services/MongoDBCollection.ts @@ -397,7 +397,7 @@ export class MongoDBCollection { /** @internal */ constructor( - /** @internal */ private user: User, + /** @internal */ private user: User, public readonly serviceName: string, public readonly databaseName: string, private readonly collectionName: string, diff --git a/packages/realm/src/app-services/User.ts b/packages/realm/src/app-services/User.ts index 33ba049125..82e060cc48 100644 --- a/packages/realm/src/app-services/User.ts +++ b/packages/realm/src/app-services/User.ts @@ -81,9 +81,9 @@ type UserListenerToken = binding.SyncUserSubscriptionToken; * Representation of an authenticated user of an {@link App}. */ export class User< - FunctionsFactoryType = DefaultFunctionsFactory, - CustomDataType = DefaultObject, - UserProfileDataType = DefaultUserProfileData, + UserFunctionsFactoryType extends DefaultFunctionsFactory = DefaultFunctionsFactory, + UserCustomDataType extends DefaultObject = DefaultObject, + UserProfileDataType extends DefaultUserProfileData = DefaultUserProfileData, > { /** @internal */ public app: App; @@ -105,9 +105,9 @@ export class User< /** @internal */ public static get< - FunctionsFactoryType = DefaultFunctionsFactory, - CustomDataType = DefaultObject, - UserProfileDataType = DefaultUserProfileData, + FunctionsFactoryType extends DefaultFunctionsFactory = DefaultFunctionsFactory, + CustomDataType extends DefaultObject = DefaultObject, + UserProfileDataType extends DefaultUserProfileData = DefaultUserProfileData, >(internal: binding.SyncUser, app?: AnyApp) { // Update the static user reference to the current app if (app) { @@ -214,12 +214,12 @@ export class User< * If this value has not been configured, it will be empty. * @returns The custom data as an object. */ - get customData(): CustomDataType { + get customData(): UserCustomDataType { const result = this.internal.customData; if (result === undefined) { - return {} as CustomDataType; + return {} as UserCustomDataType; } - return result as CustomDataType; + return result as UserCustomDataType; } /** @@ -237,7 +237,7 @@ export class User< * Use this to call functions defined by the Atlas App Services application, as this user. * @returns A {@link FunctionsFactory} that can be used to call the app's functions. */ - get functions(): FunctionsFactoryType { + get functions(): UserFunctionsFactoryType { return createFactory(this as User, undefined); } @@ -319,7 +319,7 @@ export class User< * Refresh the access token and derive custom data from it. * @returns A promise that resolves to the refreshed custom data. */ - async refreshCustomData(): Promise { + async refreshCustomData(): Promise { await this.app.internal.refreshCustomData(this.internal); return this.customData; } diff --git a/packages/realm/src/schema/types.ts b/packages/realm/src/schema/types.ts index bffd329356..fdc1004902 100644 --- a/packages/realm/src/schema/types.ts +++ b/packages/realm/src/schema/types.ts @@ -71,11 +71,6 @@ export type RelationshipPropertyTypeName = "object" | "linkingObjects"; */ export type UserTypeName = string; -/** - * The list of object schemas belonging to a specific {@link Realm}. - */ -export type CanonicalRealmSchema = CanonicalObjectSchema[]; - /** * @deprecated Will be removed in v13.0.0. Please use {@link CanonicalPropertySchema}. */ From ecd37a093221dba44d5e8c1fb5f1755c631729c1 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Fri, 11 Aug 2023 11:31:44 +0200 Subject: [PATCH 12/15] Fix type errors in integration test (#6057) Co-authored-by: Andrew Meyer --- .../tests/src/hooks/import-app-before.ts | 6 +- .../schemas/person-and-dog-with-object-ids.ts | 4 +- .../tests/src/tests/iterators.ts | 10 +- .../tests/src/tests/linking-objects.ts | 117 +++-- integration-tests/tests/src/tests/list.ts | 83 ++-- .../tests/src/tests/migrations.ts | 4 +- .../tests/src/tests/notifications.ts | 12 +- integration-tests/tests/src/tests/objects.ts | 26 +- integration-tests/tests/src/tests/queries.ts | 155 +++++-- .../tests/src/tests/realm-constructor.ts | 3 - integration-tests/tests/src/tests/results.ts | 35 +- integration-tests/tests/src/tests/schema.ts | 17 +- integration-tests/tests/src/tests/sets.ts | 2 +- .../tests/src/tests/shared-realms.ts | 2 +- integration-tests/tests/src/tests/sync/app.ts | 4 - .../tests/src/tests/sync/flexible.ts | 433 ++++++++---------- .../tests/src/tests/sync/mongo-db-client.ts | 2 +- .../tests/src/tests/sync/open-behavior.ts | 48 +- .../tests/src/tests/sync/realm-conversions.ts | 4 +- .../tests/src/tests/sync/realm.ts | 47 +- .../tests/src/tests/sync/sync-session.ts | 11 +- .../tests/src/tests/sync/user.ts | 2 + integration-tests/tests/src/typings.d.ts | 3 + .../src/utils/ExtendedAppConfigBuilder.ts | 9 +- .../tests/src/utils/credentials.ts | 4 +- .../tests/src/utils/open-realm.ts | 4 +- .../src/AppConfigBuilder.ts | 15 +- packages/realm/src/OrderedCollection.ts | 2 +- packages/realm/src/Realm.ts | 6 +- .../src/app-services/BaseSubscriptionSet.ts | 2 +- 30 files changed, 570 insertions(+), 502 deletions(-) diff --git a/integration-tests/tests/src/hooks/import-app-before.ts b/integration-tests/tests/src/hooks/import-app-before.ts index 3ee60685dd..8dd6c38c98 100644 --- a/integration-tests/tests/src/hooks/import-app-before.ts +++ b/integration-tests/tests/src/hooks/import-app-before.ts @@ -50,17 +50,17 @@ export function importAppBefore(config: AppConfig | { config: AppConfig }, sdkCo this.app = new Realm.App({ id: appId, baseUrl, ...sdkConfig }); // Extract the sync database name from the config - const databaseNames: string[] = config.services + const databaseNames: (string | undefined)[] = config.services .filter(([service]) => service.type === mongodbServiceType) .map(([service]) => { if ("sync" in service.config) { return service.config.sync.database_name; - } else { + } else if ("flexible_sync" in service.config) { return service.config.flexible_sync.database_name; } }) .filter((name) => typeof name === "string"); - if (databaseNames.length === 1) { + if (databaseNames.length === 1 && databaseNames[0]) { this.databaseName = databaseNames[0]; } else if (databaseNames.length > 1) { throw new Error("Expected at most 1 database name in the config"); diff --git a/integration-tests/tests/src/schemas/person-and-dog-with-object-ids.ts b/integration-tests/tests/src/schemas/person-and-dog-with-object-ids.ts index 6a36e4459e..09d5b0e2c5 100755 --- a/integration-tests/tests/src/schemas/person-and-dog-with-object-ids.ts +++ b/integration-tests/tests/src/schemas/person-and-dog-with-object-ids.ts @@ -39,7 +39,7 @@ export const PersonSchema: Realm.ObjectSchema = { }, }; -export class Person extends Realm.Object implements IPerson { +export class Person extends Realm.Object { _id!: Realm.BSON.ObjectId; name!: string; age!: number; @@ -67,7 +67,7 @@ export const DogSchema: Realm.ObjectSchema = { }, }; -export class Dog extends Realm.Object implements IDog { +export class Dog extends Realm.Object { _id!: Realm.BSON.ObjectId; name!: string; age!: number; diff --git a/integration-tests/tests/src/tests/iterators.ts b/integration-tests/tests/src/tests/iterators.ts index da0aa6f890..7432da90fb 100644 --- a/integration-tests/tests/src/tests/iterators.ts +++ b/integration-tests/tests/src/tests/iterators.ts @@ -111,10 +111,10 @@ describe("Iterating", () => { }).throws("Object type 'SomeOtherClass' not found in schema"); }); - type CollectionContext = { collection: Collection } & RealmContext; - type OrderedCollectionContext = { collection: OrderedCollection } & RealmContext; + type CollectionContext = { collection: Realm.Collection } & RealmContext; + type OrderedCollectionContext = { collection: Realm.OrderedCollection } & RealmContext; - function ifOrderedCollectionIt(title: string, test: (collection: OrderedCollection) => void) { + function ifOrderedCollectionIt(title: string, test: (collection: Realm.OrderedCollection) => void) { it(title, function (this: OrderedCollectionContext) { const { collection } = this; if (!(collection instanceof OrderedCollection)) { @@ -124,7 +124,9 @@ describe("Iterating", () => { }); } - function collectionBefore(getCollection: (realm: Realm) => Collection) { + function collectionBefore( + getCollection: (realm: Realm) => Realm.Collection, + ) { before(function (this: CollectionContext) { this.collection = getCollection(this.realm); }); diff --git a/integration-tests/tests/src/tests/linking-objects.ts b/integration-tests/tests/src/tests/linking-objects.ts index 55f6e939a5..1338ecf013 100644 --- a/integration-tests/tests/src/tests/linking-objects.ts +++ b/integration-tests/tests/src/tests/linking-objects.ts @@ -21,34 +21,12 @@ import { expect } from "chai"; import Realm from "realm"; import { openRealmBeforeEach } from "../hooks"; -function names(results: Realm.Results | Realm.Results) { - return results.map(function (object: IPersonSchema) { +function names(results: Realm.OrderedCollection | Realm.Results) { + return results.map(function (object: Person) { return object.name; }); } -const PersonSchema: Realm.ObjectSchema = { - name: "PersonObject", - properties: { - name: "string", - age: "double", - married: { type: "bool", default: false }, - children: { type: "list", objectType: "PersonObject" }, - parents: { type: "linkingObjects", objectType: "PersonObject", property: "children" }, - }, -}; - -const NameSchema: Realm.ObjectSchema = { - name: "NameObject", - primaryKey: "_id", - properties: { - _id: "objectId", - family: "string", - given: "string[]", - prefix: "string[]", - }, -}; - const ParentSchema: Realm.ObjectSchema = { name: "ParentObject", primaryKey: "_id", @@ -75,21 +53,6 @@ const CountrySchema: Realm.ObjectSchema = { }, }; -interface IPersonSchema { - name: string; - age: number; - married: boolean; - children: Realm.List; - parents: Realm.Collection; -} - -interface INameSchema { - _id: BSON.ObjectId; - family: string; - given: string[]; - prefix: string[]; -} - interface IParentSchema { _id: BSON.ObjectId; id: number; @@ -106,30 +69,52 @@ interface ICountrySchema { languages: ILanguageSchema[]; } -class Person extends Realm.Object implements IPersonSchema { +class Person extends Realm.Object { name!: string; age!: number; married!: boolean; - children!: Realm.List; - parents!: Realm.Collection; + children!: Realm.List; + parents!: Realm.OrderedCollection; + + static schema: Realm.ObjectSchema = { + name: "PersonObject", + properties: { + name: "string", + age: "double", + married: { type: "bool", default: false }, + children: { type: "list", objectType: "PersonObject" }, + parents: { type: "linkingObjects", objectType: "PersonObject", property: "children" }, + }, + }; } -class Name extends Realm.Object implements INameSchema { +class Name extends Realm.Object { _id!: BSON.ObjectId; family!: string; given!: string[]; prefix!: string[]; + + static schema: Realm.ObjectSchema = { + name: "NameObject", + primaryKey: "_id", + properties: { + _id: "objectId", + family: "string", + given: "string[]", + prefix: "string[]", + }, + }; } describe("Linking objects", () => { describe("Same class", () => { - openRealmBeforeEach({ schema: [PersonSchema] }); + openRealmBeforeEach({ schema: [Person] }); it("add and delete propagate to linking object", function (this: RealmContext) { - let olivier: IPersonSchema; - let oliviersParents!: Realm.Collection; + let olivier: Person; + let oliviersParents!: Realm.OrderedCollection; this.realm.write(() => { - olivier = this.realm.create(PersonSchema.name, { name: "Olivier", age: 0 }); - this.realm.create(PersonSchema.name, { name: "Christine", age: 25, children: [olivier] }); + olivier = this.realm.create(Person, { name: "Olivier", age: 0 }); + this.realm.create(Person, { name: "Christine", age: 25, children: [olivier] }); oliviersParents = olivier.parents; expect(names(oliviersParents)).eql(["Christine"]); }); @@ -137,7 +122,7 @@ describe("Linking objects", () => { expect(names(oliviersParents)).eql(["Christine"]); this.realm.write(() => { - this.realm.create(PersonSchema.name, { name: "JP", age: 28, children: [olivier] }); + this.realm.create(Person, { name: "JP", age: 28, children: [olivier] }); expect(names(oliviersParents)).eql(["Christine", "JP"]); }); @@ -150,16 +135,16 @@ describe("Linking objects", () => { }); it("filters work on linking object", function (this: RealmContext) { this.realm.write(() => { - const olivier = this.realm.create(PersonSchema.name, { name: "Olivier", age: 0 }); - this.realm.create(PersonSchema.name, { + const olivier = this.realm.create(Person, { name: "Olivier", age: 0 }); + this.realm.create(Person, { name: "Christine", age: 25, children: [olivier], }); - this.realm.create(PersonSchema.name, { name: "JP", age: 28, children: [olivier] }); + this.realm.create(Person, { name: "JP", age: 28, children: [olivier] }); }); - const people = this.realm.objects("PersonObject"); + const people = this.realm.objects(Person); expect(people.filtered("parents.age > 25").length).equals(1); expect(people.filtered("parents.age > 25")[0].name).equals("Olivier"); expect(people.filtered("parents.@count == 2").length).equals(1); @@ -170,7 +155,7 @@ describe("Linking objects", () => { it("throws on invalid input", function (this: RealmContext) { let person: Person; this.realm.write(() => { - person = this.realm.create(PersonSchema.name, { name: "Person 1", age: 50 }); + person = this.realm.create(Person, { name: "Person 1", age: 50 }); }); expect(() => person.linkingObjects("NoSuchSchema", "noSuchProperty")).throws( "Object type 'NoSuchSchema' not found in schema.", @@ -182,16 +167,16 @@ describe("Linking objects", () => { "'PersonObject#name' is not a relationship to 'PersonObject'", ); let olivier: Person; - let oliviersParents: Realm.Results; + let oliviersParents: Realm.OrderedCollection; this.realm.write(() => { - olivier = this.realm.create(PersonSchema.name, { name: "Olivier", age: 0 }); - this.realm.create(PersonSchema.name, { name: "Christine", age: 25, children: [olivier] }); - oliviersParents = olivier.linkingObjects("PersonObject", "children"); + olivier = this.realm.create(Person, { name: "Olivier", age: 0 }); + this.realm.create(Person, { name: "Christine", age: 25, children: [olivier] }); + oliviersParents = olivier.linkingObjects(Person, "children"); expect(names(oliviersParents)).eql(["Christine"]); }); this.realm.write(() => { - this.realm.create(PersonSchema.name, { name: "JP", age: 28, children: [olivier] }); + this.realm.create(Person, { name: "JP", age: 28, children: [olivier] }); expect(names(oliviersParents)).eql(["Christine", "JP"]); }); @@ -204,7 +189,7 @@ describe("Linking objects", () => { it("supports count operation", function (this: RealmContext) { let john!: Person; this.realm.write(() => { - john = this.realm.create(PersonSchema.name, { name: "John", age: 50 }); + john = this.realm.create(Person, { name: "John", age: 50 }); }); expect(john.linkingObjectsCount()).equals(0); @@ -212,9 +197,9 @@ describe("Linking objects", () => { let olivier!: Person; let key; this.realm.write(() => { - olivier = this.realm.create(PersonSchema.name, { name: "Olivier", age: 0 }); + olivier = this.realm.create(Person, { name: "Olivier", age: 0 }); key = olivier._objectKey(); - this.realm.create(PersonSchema.name, { name: "Christine", age: 25, children: [olivier] }); + this.realm.create(Person, { name: "Christine", age: 25, children: [olivier] }); }); expect(olivier.linkingObjectsCount()).equals(1); @@ -233,7 +218,7 @@ describe("Linking objects", () => { }); }); describe("Non recursive", () => { - openRealmBeforeEach({ schema: [ParentSchema, NameSchema] }); + openRealmBeforeEach({ schema: [ParentSchema, Name] }); it("count operation", function (this: RealmContext) { let parent: IParentSchema; this.realm.write(() => { @@ -247,7 +232,7 @@ describe("Linking objects", () => { let child!: Name; this.realm.write(() => { - child = this.realm.create(NameSchema.name, { + child = this.realm.create(Name, { _id: new BSON.ObjectId("0000002a9a7969d24bea4cf6"), family: "Johnson", given: ["Olivier"], @@ -256,14 +241,14 @@ describe("Linking objects", () => { this.realm.create("ParentObject", { _id: new BSON.ObjectId("0000002a9a7969d24bea4cf7"), id: 1, name: [child] }); }); expect(this.realm.objects(ParentSchema.name).length).equals(2); - expect(this.realm.objects(NameSchema.name).length).equals(1); + expect(this.realm.objects(Name).length).equals(1); expect(child.linkingObjectsCount()).equals(1); this.realm.write(() => { parent.name.push(child); }); expect(this.realm.objects(ParentSchema.name).length).equals(2); - expect(this.realm.objects(NameSchema.name).length).equals(1); + expect(this.realm.objects(Name).length).equals(1); expect(child.linkingObjectsCount()).equals(2); }); }); diff --git a/integration-tests/tests/src/tests/list.ts b/integration-tests/tests/src/tests/list.ts index 8f7f07c3bd..1497978e34 100644 --- a/integration-tests/tests/src/tests/list.ts +++ b/integration-tests/tests/src/tests/list.ts @@ -21,7 +21,6 @@ import { expectArraysEqual, expectSimilar } from "../utils/comparisons"; import { expect } from "chai"; import { CanonicalObjectSchema } from "realm"; import { openRealmBeforeEach, openRealmBefore } from "../hooks"; -import { select } from "../utils/select"; const DATA1 = new Uint8Array([0x01]); const DATA2 = new Uint8Array([0x02]); @@ -30,7 +29,7 @@ const DATE1 = new Date(1); const DATE2 = new Date(2); const DATE3 = new Date(3); -const PersonSchema = { +const PersonSchema: Realm.ObjectSchema = { name: "PersonObject", properties: { name: "string", @@ -85,12 +84,6 @@ const PrimitiveArraysSchema: Realm.ObjectSchema = { }, }; -const PersonListSchema: Realm.ObjectSchema = { - name: "PersonList", - properties: { - list: "PersonObject[]", - }, -}; const UuidListSchema: Realm.ObjectSchema = { name: "PrimUuidListsObject", primaryKey: "_id", @@ -240,6 +233,20 @@ interface IPersonSchema { parents: Realm.Collection; } +class Person extends Realm.Object { + name!: string; + age!: number; + married!: boolean; + children!: Realm.List; + parents!: Realm.Collection; + + constructor(realm: Realm, name: string, age: number, married: boolean) { + super(realm, { name, age, married }); + } + + static schema: Realm.ObjectSchema = PersonSchema; +} + interface ILinkTypeSchema { objectCol: ITestObjectSchema; objectCol1: ITestObjectSchema; @@ -275,10 +282,27 @@ interface IPrimitiveArraysSchema { optUuid: Realm.List; } +const PersonListSchema: Realm.ObjectSchema = { + name: "PersonList", + properties: { + list: "PersonObject[]", + }, +}; + interface IPersonListSchema { list: Realm.List; } +class PersonList extends Realm.Object { + list!: Realm.List; + + constructor(realm: Realm) { + super(realm, {}); + } + + static schema: Realm.ObjectSchema = PersonListSchema; +} + interface IUuidListSchema { _id: BSON.UUID; list: BSON.UUID[]; @@ -335,7 +359,7 @@ interface IMultiListObjectSchema { list2: string[]; } -class PrimitiveArrays extends Realm.Object implements IPrimitiveArraysSchema { +class PrimitiveArrays extends Realm.Object { bool!: Realm.List; int!: Realm.List; float!: Realm.List; @@ -357,6 +381,8 @@ class PrimitiveArrays extends Realm.Object implements IPrimitiveArraysSchema { optDecimal128!: Realm.List; optObjectId!: Realm.List; optUuid!: Realm.List; + + static schema: Realm.ObjectSchema = PrimitiveArraysSchema; } class TodoItem extends Realm.Object { @@ -404,14 +430,14 @@ describe("Lists", () => { }); }); describe("types", () => { - openRealmBeforeEach({ schema: [LinkTypeSchema, TestObjectSchema, PrimitiveArraysSchema] }); + openRealmBeforeEach({ schema: [LinkTypeSchema, TestObjectSchema, PrimitiveArrays] }); it("instancetypes are correct", function (this: RealmContext) { let obj!: ILinkTypeSchema; let prim!: PrimitiveArrays; this.realm.write(() => { obj = this.realm.create(LinkTypeSchema.name, {}); - prim = this.realm.create(PrimitiveArraysSchema.name, {}); + prim = this.realm.create(PrimitiveArrays, {}); }); // Check instance type @@ -506,7 +532,6 @@ describe("Lists", () => { //@ts-expect-error TYPEBUG: type missmatch, forcecasting shouldn't be done obj.arrayCol = [{ doubleCol: 1 }, { doubleCol: 2 }]; expect(array.length).equals(2); - //@ts-expect-error assignment to read only list property length should not be allowed expect(() => (array.length = 0)).throws(Error, "Cannot assign to read only property 'length'"); expect(array.length).equals(2); @@ -514,7 +539,7 @@ describe("Lists", () => { }); }); describe("subscripts", () => { - openRealmBeforeEach({ schema: [LinkTypeSchema, TestObjectSchema, PrimitiveArraysSchema] }); + openRealmBeforeEach({ schema: [LinkTypeSchema, TestObjectSchema, PrimitiveArrays] }); //TODO figure out why undefined is not returned in react-native https://github.com/realm/realm-js/issues/5463. it.skipIf(environment.reactNative, "invalid object access returns undefined", function (this: RealmContext) { this.realm.write(() => { @@ -538,7 +563,7 @@ describe("Lists", () => { arrayCol: [{ doubleCol: 3 }, { doubleCol: 4 }], arrayCol1: [{ doubleCol: 5 }, { doubleCol: 6 }], }); - prim = this.realm.create(PrimitiveArraysSchema.name, { + prim = this.realm.create(PrimitiveArrays, { bool: [true, false], int: [1, 2], float: [1.1, 2.2], @@ -996,14 +1021,12 @@ describe("Lists", () => { array = obj.arrayCol; let removed; - //@ts-expect-error TYPEBUG: the typesystem doesn't allow us to pass multiple paramaters as object. removed = array.splice(0, 0, obj.objectCol, obj.objectCol1); expect(removed.length).equals(0); expect(array.length).equals(4); expect(array[0].doubleCol).equals(1); expect(array[1].doubleCol).equals(2); - //@ts-expect-error TYPEBUG: the typesystem doesn't allow us to pass multiple paramaters as object. removed = array.splice(2, 2, { doubleCol: 5 }, { doubleCol: 6 }); expect(removed.length).equals(2); expect(removed[0].doubleCol).equals(3); @@ -1048,6 +1071,7 @@ describe("Lists", () => { //@ts-expect-error can not pass string that is non-convertible to number. expect(() => array.splice("cat", 1)).throws("Expected 'start' to be a number, got a string"); + //@ts-expect-error the third argument should not be a number. expect(() => array.splice(0, 0, 0)).throws("Expected 'element of arrayCol' to be an object, got a number"); }); expect(() => array.splice(0, 0, { doubleCol: 1 })).throws( @@ -1438,28 +1462,28 @@ describe("Lists", () => { }); }); describe("array-methods", () => { - openRealmBeforeEach({ schema: [PersonSchema, PersonListSchema, PrimitiveArraysSchema] }); + openRealmBeforeEach({ schema: [Person, PersonList, PrimitiveArrays] }); it("works on differentProperties", function (this: RealmContext) { - let object!: IPersonListSchema; - let prim!: IPrimitiveArraysSchema; + let object!: PersonList; + let prim!: PrimitiveArrays; this.realm.write(() => { - object = this.realm.create(PersonListSchema.name, { + object = this.realm.create(PersonListSchema.name, { list: [ { name: "Ari", age: 10 }, { name: "Tim", age: 11 }, { name: "Bjarne", age: 12 }, ], }); - prim = this.realm.create(PrimitiveArraysSchema.name, { int: [10, 11, 12] }); + prim = this.realm.create(PrimitiveArrays, { int: [10, 11, 12] }); }); - for (const list of [object.list, this.realm.objects(PersonSchema.name) as Realm.Results]) { + for (const list of [object.list, this.realm.objects(PersonList)[0].list]) { expect(list.slice().length).equals(3); expect(list.slice(-1).length).equals(1); - expect((list.slice(-1)[0] as IPersonSchema).age).equals(12); + expect((list.slice(-1)[0] as Person).age).equals(12); expect(list.slice(1, 3).length).equals(2); - expect((list.slice(1, 3)[1] as IPersonSchema).age).equals(12); + expect((list.slice(1, 3)[1] as Person).age).equals(12); expect(list.map((p) => p.name).join(" ")).equals("Ari Tim Bjarne"); let count = 0; @@ -1474,17 +1498,17 @@ describe("Lists", () => { [10, 11, 12], ); expect(list.some((p) => p.age > 10)).is.true; - expect(list.every((p) => p.age > 0)).is.true; + expect(list.every((p: Person) => p.age > 0)).is.true; - const person = list.find((p) => p.name == "Tim"); + const person = list.find((p: Person) => p.name == "Tim"); expect(person?.name).equals("Tim"); const index = list.findIndex((p) => p.name == "Tim"); expect(index).equals(1); - expect(list.indexOf(list[index])).equals(index); + expect(list.indexOf(list[index] as Person)).equals(index); - expect(list.reduce((n, p) => n + p.age, 0)).equals(33); - expect(list.reduceRight((n, p) => n + p.age, 0)).equals(33); + expect(list.reduce((n: number, p: Person) => n + p.age, 0)).equals(33); + expect(list.reduceRight((n: number, p: Person) => n + p.age, 0)).equals(33); // eslint-disable-next-line no-undef const iteratorMethodNames: (string | symbol)[] = ["entries", "keys", "values"]; @@ -1935,7 +1959,6 @@ describe("Lists", () => { }); const names = realm2.objects(NameObjectLocalSchema.name); expect(names.length).equals(1); - //@ts-expect-error TYPEBUG: our List type-definition expects index accesses to be done with a number , should probably be extended. expect(names[0]["family"]).equals("Smith"); //@ts-expect-error TYPEBUG: our List type-definition expects index accesses to be done with a number , should probably be extended. expect(names[0]["given"].length).equals(2); diff --git a/integration-tests/tests/src/tests/migrations.ts b/integration-tests/tests/src/tests/migrations.ts index b7f4afc09b..5cd58d506b 100644 --- a/integration-tests/tests/src/tests/migrations.ts +++ b/integration-tests/tests/src/tests/migrations.ts @@ -212,7 +212,7 @@ describe("Migrations", () => { }); it("should be able to add optional new properties", () => { - const TestSchemaWithOptionalNewProperty = { + const TestSchemaWithOptionalNewProperty: Realm.ObjectSchema = { ...TestSchema, properties: { ...TestSchema.properties, @@ -399,7 +399,7 @@ describe("Migrations", () => { Realm.clearTestState(); }); - const PersonWithDogsSchema = { + const PersonWithDogsSchema: Realm.ObjectSchema = { ...PersonSchema, properties: { ...PersonSchema.properties, diff --git a/integration-tests/tests/src/tests/notifications.ts b/integration-tests/tests/src/tests/notifications.ts index 7900cf0d45..0e08c2921f 100644 --- a/integration-tests/tests/src/tests/notifications.ts +++ b/integration-tests/tests/src/tests/notifications.ts @@ -20,9 +20,9 @@ import { expect } from "chai"; import Realm from "realm"; import { openRealmBeforeEach } from "../hooks"; -class ListObject extends Realm.Object { +class ListObject extends Realm.Object { list!: Realm.List; - static schema = { + static schema: Realm.ObjectSchema = { name: "ListObject", properties: { list: { type: "list", objectType: "TestObject" }, @@ -30,7 +30,7 @@ class ListObject extends Realm.Object { }; } -class TestObject extends Realm.Object { +class TestObject extends Realm.Object { doubleCol!: Realm.Types.Double; static schema = { name: "TestObject", @@ -40,7 +40,7 @@ class TestObject extends Realm.Object { }; } -class StringOnlyObject extends Realm.Object { +class StringOnlyObject extends Realm.Object { stringCol!: Realm.Types.String; static schema = { name: "StringOnlyObject", @@ -165,7 +165,7 @@ describe("Notifications", () => { onEnd: () => void | Mocha.Done, changesOnRun: Realm.CollectionChangeSet[], ) => { - return (_: Realm.Collection, changes: Realm.CollectionChangeSet) => { + return (_: Realm.OrderedCollection, changes: Realm.CollectionChangeSet) => { runCount++; expect(changes.insertions).deep.equals(changesOnRun[runCount - 1].insertions); @@ -183,7 +183,7 @@ describe("Notifications", () => { }; describe("Results notifications", () => { - let testObjects: Realm.Collection; + let testObjects: Realm.OrderedCollection; openRealmBeforeEach({ schema: [TestObject] }); diff --git a/integration-tests/tests/src/tests/objects.ts b/integration-tests/tests/src/tests/objects.ts index 61a10e2efc..0946458aae 100644 --- a/integration-tests/tests/src/tests/objects.ts +++ b/integration-tests/tests/src/tests/objects.ts @@ -27,7 +27,6 @@ import { import { openRealmBeforeEach } from "../hooks"; import { expectArraysEqual, expectSimilar } from "../utils/comparisons"; import jsrsasign from "jsrsasign"; -import { select } from "../utils/select"; const RANDOM_DATA = new Uint8Array([ 0xd8, 0x21, 0xd6, 0xe8, 0x00, 0x57, 0xbc, 0xb2, 0x6a, 0x15, 0x77, 0x30, 0xac, 0x77, 0x96, 0xd9, 0x67, 0x1e, 0x40, @@ -143,7 +142,7 @@ const DateObjectSchema = { }, }; -const DefaultValuesSchema = { +const DefaultValuesSchema: Realm.ObjectSchema = { name: "DefaultValuesObject", properties: { boolCol: { type: "bool", default: true }, @@ -159,7 +158,7 @@ const DefaultValuesSchema = { }, }; -const LinkTypesSchema = { +const LinkTypesSchema: Realm.ObjectSchema = { name: "LinkTypesObject", properties: { objectCol: "TestObject", @@ -195,7 +194,7 @@ const CollectionSchema: Realm.ObjectSchema = { }, }; -const AllTypesSchema = { +const AllTypesSchema: Realm.ObjectSchema = { name: "AllTypesObject", properties: { boolCol: "bool", @@ -847,7 +846,6 @@ describe("Realm.Object", () => { } function tryAssign(name: string, value: any) { - //@ts-expect-error TYPEBUG: indexing with string is not allowed by typesystem. const prop = AllTypesSchema.properties[name]; const type = typeof prop == "object" ? prop.type : prop; //@ts-expect-error TYPEBUG: indexing with string is not allowed by typesystem. @@ -1079,12 +1077,12 @@ describe("Realm.Object", () => { }); it("getPropertyType gives correct properties", function (this: Mocha.Context & RealmContext) { - let obj!: Realm.Object; - let mixedNull!: Realm.Object; - let mixedInt!: Realm.Object; - let mixedString!: Realm.Object; - let mixedFloat!: Realm.Object; - let mixedBool!: Realm.Object; + let obj!: Realm.Object; + let mixedNull!: Realm.Object; + let mixedInt!: Realm.Object; + let mixedString!: Realm.Object; + let mixedFloat!: Realm.Object; + let mixedBool!: Realm.Object; this.realm.write(() => { obj = this.realm.create(AllTypesSchema.name, allTypesValues); @@ -1327,14 +1325,14 @@ describe("Realm.Object", () => { const objKey = obj._objectKey(); //@ts-expect-error uses private method. - const objFromKey = this.realm._objectForObjectKey(AgeSchema.name, objKey); + const objFromKey = this.realm._objectForObjectKey(AgeSchema.name, objKey); this.realm.write(() => { - objFromKey.age = 7; + objFromKey!.age = 7; }); expect(obj.age).equals(7); - expect(objFromKey.age).equals(7); + expect(objFromKey?.age).equals(7); }); }); }); diff --git a/integration-tests/tests/src/tests/queries.ts b/integration-tests/tests/src/tests/queries.ts index f1f016a9e0..0dabee7cf5 100644 --- a/integration-tests/tests/src/tests/queries.ts +++ b/integration-tests/tests/src/tests/queries.ts @@ -16,7 +16,6 @@ // //////////////////////////////////////////////////////////////////////////// import Realm, { - ObjectSchema, BSON, GeoBox, GeoCircle, @@ -29,7 +28,6 @@ import Realm, { } from "realm"; import { expect } from "chai"; import { openRealmBeforeEach } from "../hooks"; -import { IPerson, PersonSchema } from "../schemas/person-and-dogs"; import { ContactSchema, IContact } from "../schemas/contact"; interface INullableTypesObject { @@ -57,7 +55,7 @@ class NullableTypesObject extends Realm.Object implements INullableTypesObject { objectIdCol?: Realm.Types.ObjectId; uuidCol?: Realm.Types.UUID; - static schema = { + static schema: Realm.ObjectSchema = { name: "NullableTypesObject", properties: { boolCol: "bool?", @@ -74,16 +72,72 @@ class NullableTypesObject extends Realm.Object implements INullableTypesObject { }; } +export interface IDog { + name: string; + age: number; + owner: IPerson; +} + +export const DogSchema: Realm.ObjectSchema = { + name: "Dog", + properties: { + age: "int", + name: "string", + owner: "Person", + }, +}; + +export class Dog extends Realm.Object implements IDog { + name!: string; + age!: number; + owner!: Person; + + constructor(realm: Realm, name: string, age: number, owner: Person) { + super(realm, { name, age, owner }); + } + + static schema: Realm.ObjectSchema = DogSchema; +} +export interface IPerson { + name: string; + age: number; + friends: Realm.List; + dogs: Realm.Results; +} + +export const PersonSchema: Realm.ObjectSchema = { + name: "Person", + primaryKey: "name", + properties: { + age: "int", + name: "string", + friends: "Person[]", + }, +}; + +export class Person extends Realm.Object implements IPerson { + name!: string; + age!: number; + friends!: Realm.List; + dogs!: Realm.Results; + + constructor(realm: Realm, name: string, age: number) { + super(realm, { name, age }); + } + + static schema: Realm.ObjectSchema = PersonSchema; +} + interface IStory { title?: string; content?: string; } -class Story extends Realm.Object implements IStory { +class Story extends Realm.Object implements IStory { title?: string; content?: string; - static schema: ObjectSchema = { + static schema: Realm.ObjectSchema = { name: "Story", properties: { title: { type: "string" }, @@ -101,7 +155,7 @@ class MyGeoPoint implements CanonicalGeoPoint { this.coordinates = [long, lat]; } - static schema: ObjectSchema = { + static schema: Realm.ObjectSchema = { name: "MyGeoPoint", embedded: true, properties: { @@ -122,7 +176,7 @@ class PointOfInterest extends Realm.Object implements IPointOfInterest { location = new MyGeoPoint(0, 0); locations = [new MyGeoPoint(0, 0)]; - static schema: ObjectSchema = { + static schema: Realm.ObjectSchema = { name: "PointOfInterest", properties: { id: "int", @@ -141,11 +195,7 @@ type QueryResultsPair = [ExpectedResults: any[], Query: string, ...QueryArgs: Ar * Helper method which runs an array of queries and asserts them to given expected length * For example: (r, "Obj", [1, "intCol == 0"]) => querying "intCol == 0" should return 1 elements. */ -const expectQueryLength = ( - realm: Realm, - objectSchema: string | Realm.ObjectClass, - queryLengthPairs: QueryLengthPair[], -) => { +const expectQueryLength = (realm: Realm, objectSchema: Realm.ObjectClass, queryLengthPairs: QueryLengthPair[]) => { queryLengthPairs.forEach(([expectedLength, queryString, ...queryArgs]) => { const filtered = realm.objects(objectSchema).filtered(queryString, ...queryArgs); expect(filtered.length).equal( @@ -162,7 +212,7 @@ const expectQueryLength = ( */ const expectQueryException = ( realm: Realm, - objectSchema: string | Realm.ObjectClass, + objectSchema: Realm.ObjectClass, queryExceptionPairs: QueryExceptionPair[], ) => { queryExceptionPairs.forEach(([expectedException, queryString, ...queryArgs]) => { @@ -183,15 +233,34 @@ const expectQueryException = ( */ const expectQueryResultValues = ( realm: Realm, - objectSchema: string | Realm.ObjectClass, + objectSchema: Realm.ObjectClass, + propertyToCompare: string, + queryResultPairs: QueryResultsPair[], +) => { + queryResultPairs.forEach(([expectedResults, queryString, ...queryArgs]) => { + let results = realm.objects(objectSchema); + results = results.filtered(queryString, ...queryArgs); + expect(results.length).to.equal(expectedResults.length); + expect(results.map((el) => (el as any)[propertyToCompare])).to.deep.equal( + expectedResults, + ` + Expected results not returned from query: ${queryString} ${JSON.stringify(queryArgs)}, + `, + ); + }); +}; + +const expectQueryResultValuesByName = ( + realm: Realm, + objectSchemaName: string, propertyToCompare: string, queryResultPairs: QueryResultsPair[], ) => { queryResultPairs.forEach(([expectedResults, queryString, ...queryArgs]) => { - let results = realm.objects(objectSchema); + let results = realm.objects(objectSchemaName); results = results.filtered(queryString, ...queryArgs); expect(results.length).to.equal(expectedResults.length); - expect(results.map((el) => el[propertyToCompare])).to.deep.equal( + expect(results.map((el) => (el as any)[propertyToCompare])).to.deep.equal( expectedResults, ` Expected results not returned from query: ${queryString} ${JSON.stringify(queryArgs)}, @@ -1247,14 +1316,14 @@ describe("Queries", () => { beforeEach(function (this: RealmContext) { objects = this.realm.write(() => { return [ - this.realm.create("NullableTypesObject", { + this.realm.create("NullableTypesObject", { dataCol: new Uint8Array([1, 100, 233, 255, 0]), }), - this.realm.create("NullableTypesObject", { dataCol: new Uint8Array([1, 100]) }), - this.realm.create("NullableTypesObject", { dataCol: new Uint8Array([100]) }), - this.realm.create("NullableTypesObject", { dataCol: new Uint8Array([2]) }), - this.realm.create("NullableTypesObject", { dataCol: new Uint8Array([255, 0]) }), - this.realm.create("NullableTypesObject", { dataCol: undefined }), + this.realm.create("NullableTypesObject", { dataCol: new Uint8Array([1, 100]) }), + this.realm.create("NullableTypesObject", { dataCol: new Uint8Array([100]) }), + this.realm.create("NullableTypesObject", { dataCol: new Uint8Array([2]) }), + this.realm.create("NullableTypesObject", { dataCol: new Uint8Array([255, 0]) }), + this.realm.create("NullableTypesObject", { dataCol: undefined }), ]; }); }); @@ -1310,13 +1379,13 @@ describe("Queries", () => { beforeEach(function (this: RealmContext) { objects = this.realm.write(() => { return [ - this.realm.create("NullableTypesObject", { objectIdCol: new BSON.ObjectId("6001c033600510df3bbfd864") }), - this.realm.create("NullableTypesObject", { objectIdCol: new BSON.ObjectId("6001c04b3bc6feeda9ef44f3") }), - this.realm.create("NullableTypesObject", { objectIdCol: new BSON.ObjectId("6001c05521acef4e39acfd6f") }), - this.realm.create("NullableTypesObject", { objectIdCol: new BSON.ObjectId("6001c05e73ac00af232fb7f6") }), - this.realm.create("NullableTypesObject", { objectIdCol: new BSON.ObjectId("6001c069c2f8b350ddeeceaa") }), - this.realm.create("NullableTypesObject", { objectIdCol: undefined }), - this.realm.create("NullableTypesObject", { objectIdCol: undefined }), + this.realm.create(NullableTypesObject, { objectIdCol: new BSON.ObjectId("6001c033600510df3bbfd864") }), + this.realm.create(NullableTypesObject, { objectIdCol: new BSON.ObjectId("6001c04b3bc6feeda9ef44f3") }), + this.realm.create(NullableTypesObject, { objectIdCol: new BSON.ObjectId("6001c05521acef4e39acfd6f") }), + this.realm.create(NullableTypesObject, { objectIdCol: new BSON.ObjectId("6001c05e73ac00af232fb7f6") }), + this.realm.create(NullableTypesObject, { objectIdCol: new BSON.ObjectId("6001c069c2f8b350ddeeceaa") }), + this.realm.create(NullableTypesObject, { objectIdCol: undefined }), + this.realm.create(NullableTypesObject, { objectIdCol: undefined }), ]; }); }); @@ -1349,13 +1418,13 @@ describe("Queries", () => { beforeEach(function (this: RealmContext) { objects = this.realm.write(() => [ - this.realm.create("NullableTypesObject", { uuidCol: new BSON.UUID("d1b186e1-e9e0-4768-a1a7-c492519d47ee") }), - this.realm.create("NullableTypesObject", { uuidCol: new BSON.UUID("08c35c66-69bd-4b28-8177-f9135553711f") }), - this.realm.create("NullableTypesObject", { uuidCol: new BSON.UUID("35f8f06b-dc77-4781-8b5e-9a09759db989") }), - this.realm.create("NullableTypesObject", { uuidCol: new BSON.UUID("39e2d5ce-087d-4d0c-a149-05acc74c53f1") }), - this.realm.create("NullableTypesObject", { uuidCol: new BSON.UUID("b521bc19-4e92-4e23-ae85-df937abfd89c") }), - this.realm.create("NullableTypesObject", { uuidCol: undefined }), - this.realm.create("NullableTypesObject", { uuidCol: undefined }), + this.realm.create(NullableTypesObject, { uuidCol: new BSON.UUID("d1b186e1-e9e0-4768-a1a7-c492519d47ee") }), + this.realm.create(NullableTypesObject, { uuidCol: new BSON.UUID("08c35c66-69bd-4b28-8177-f9135553711f") }), + this.realm.create(NullableTypesObject, { uuidCol: new BSON.UUID("35f8f06b-dc77-4781-8b5e-9a09759db989") }), + this.realm.create(NullableTypesObject, { uuidCol: new BSON.UUID("39e2d5ce-087d-4d0c-a149-05acc74c53f1") }), + this.realm.create(NullableTypesObject, { uuidCol: new BSON.UUID("b521bc19-4e92-4e23-ae85-df937abfd89c") }), + this.realm.create(NullableTypesObject, { uuidCol: undefined }), + this.realm.create(NullableTypesObject, { uuidCol: undefined }), ]); }); @@ -1428,9 +1497,9 @@ describe("Queries", () => { beforeEach(function (this: RealmContext) { objects = this.realm.write(() => [ - this.realm.create("LinkObject", { linkCol: { intCol: 1 } }), - this.realm.create("LinkObject", { linkCol: { intCol: 2 } }), - this.realm.create("LinkObject", { linkCol: undefined }), + this.realm.create(LinkObject, { linkCol: { intCol: 1 } }), + this.realm.create(LinkObject, { linkCol: { intCol: 2 } }), + this.realm.create(LinkObject, { linkCol: undefined }), ]); }); @@ -1446,7 +1515,7 @@ describe("Queries", () => { }); it("throws with invalid queries", function (this: RealmContext) { - expectQueryException(this.realm, "LinkObject", [ + expectQueryException(this.realm, LinkObject, [ ["Unsupported operator", "linkCol > $0", objects[0].linkCol], ["'LinkObject' has no property 'intCol'", "intCol = $0", objects[0].linkCol], ]); @@ -1521,7 +1590,7 @@ describe("Queries", () => { }); it("returns correct results", function (this: RealmContext) { - expectQueryResultValues(this.realm, "LinkTypesObject", "id", [ + expectQueryResultValuesByName(this.realm, "LinkTypesObject", "id", [ [[0, 2], "basicLink.intCol == 1"], [[1], "linkLink.basicLink.intCol == 1"], [[1, 3], "linkLink.basicLink.intCol > 0"], @@ -1562,7 +1631,7 @@ describe("Queries", () => { }); it("returns correct results", function (this: RealmContext) { - expectQueryResultValues(this.realm, "Person", "id", [ + expectQueryResultValuesByName(this.realm, "Person", "id", [ [[1, 3], "age > 20 SORT(age DESC) DISTINCT(name)"], [[2, 0], "age > 20 SORT(age ASC) DISTINCT(name)"], [[2, 0], "age > 20 SORT(age ASC, name DESC) DISTINCT(name)"], @@ -1615,7 +1684,7 @@ describe("Queries", () => { }); it("returns correct results", function (this: RealmContext) { - expectQueryResultValues(this.realm, "Movie", "id", [ + expectQueryResultValuesByName(this.realm, "Movie", "id", [ [[0, 1, 2], "tags =[c] 'science fiction'"], [[0, 1, 2], "tags BEGINSWITH[c] 'science'"], [[], "NONE tags CONTAINS ' '"], diff --git a/integration-tests/tests/src/tests/realm-constructor.ts b/integration-tests/tests/src/tests/realm-constructor.ts index ac18121244..6c17650425 100644 --- a/integration-tests/tests/src/tests/realm-constructor.ts +++ b/integration-tests/tests/src/tests/realm-constructor.ts @@ -337,7 +337,6 @@ describe("Realm#constructor", () => { realm1.write(() => { realm1.create("TestObject", [1]); }); - //@ts-expect-error TYPEBUG: isInMemory property does not exist expect(realm1.isInMemory).to.be.true; // open a second instance of the same realm and check that they share data @@ -345,7 +344,6 @@ describe("Realm#constructor", () => { const objects = realm2.objects(TestObject.schema.name); expect(objects.length).equals(1); expect(objects[0].doubleCol).equals(1.0); - //@ts-expect-error TYPEBUG: isInMemory property does not exist expect(realm2.isInMemory).equals(true); realm1.close(); @@ -358,7 +356,6 @@ describe("Realm#constructor", () => { realm1.write(() => { realm1.create("TestObject", [1]); }); - //@ts-expect-error TYPEBUG: isInMemory property does not exist expect(realm1.isInMemory).to.be.true; // Close realm (this should delete the realm since there are no more // references to it). diff --git a/integration-tests/tests/src/tests/results.ts b/integration-tests/tests/src/tests/results.ts index 815d3e2e1f..fe027232e9 100644 --- a/integration-tests/tests/src/tests/results.ts +++ b/integration-tests/tests/src/tests/results.ts @@ -19,12 +19,11 @@ import { expect } from "chai"; import Realm, { BSON } from "realm"; import { openRealmBeforeEach } from "../hooks"; -import { select } from "../utils/select"; const { Decimal128, ObjectId, UUID } = Realm.BSON; class TestObject extends Realm.Object { doubleCol!: Realm.Types.Double; - static schema = { + static schema: Realm.ObjectSchema = { name: "TestObject", properties: { doubleCol: "double", @@ -32,7 +31,7 @@ class TestObject extends Realm.Object { }; } -const IntPrimarySchema = { +const IntPrimarySchema: Realm.ObjectSchema = { name: "IntPrimaryObject", primaryKey: "primaryCol", properties: { @@ -41,12 +40,13 @@ const IntPrimarySchema = { }, }; -interface IntPrimaryObject { - primaryCol: Realm.Types.Int; - valueCol: string; +class IntPrimaryObject extends Realm.Object { + primaryCol!: Realm.Types.Int; + valueCol!: string; + static schema: Realm.ObjectSchema = IntPrimarySchema; } -const BasicTypesSchema = { +const BasicTypesSchema: Realm.ObjectSchema = { name: "BasicTypesObject", properties: { boolCol: "bool", @@ -75,7 +75,7 @@ interface BasicTypesObject { uuidCol: Realm.Types.UUID; } -const LinkTypesSchema = { +const LinkTypesSchema: Realm.ObjectSchema = { name: "LinkTypesObject", properties: { objectCol: "TestObject", @@ -85,7 +85,7 @@ const LinkTypesSchema = { }, }; -const NullableBasicTypesSchema = { +const NullableBasicTypesSchema: Realm.ObjectSchema = { name: "NullableBasicTypesObject", properties: { boolCol: "bool?", @@ -154,7 +154,7 @@ describe("Results", () => { }); // Search in base table - const objects = this.realm.objects("TestObject"); + const objects = this.realm.objects("TestObject"); expect(objects.indexOf(object1)).equals(0); expect(objects.indexOf(object2)).equals(1); expect(objects.indexOf(object3)).equals(2); @@ -196,7 +196,6 @@ describe("Results", () => { objects[1] = { doubleCol: 0 }; }).throws("Assigning into a Results is not supported"); expect(() => { - //@ts-expect-error Should be an invalid write to read-only object. objects.length = 0; }).throws("Cannot assign to read only property 'length'"); }); @@ -400,7 +399,7 @@ describe("Results", () => { married!: boolean; children!: Realm.List; parents!: Realm.List; - static schema = { + static schema: Realm.ObjectSchema = { name: "PersonObject", properties: { name: "string", @@ -453,14 +452,14 @@ describe("Results", () => { it("implements sorted", () => { const realm = new Realm({ schema: [IntPrimarySchema] }); - let objects = realm.objects("IntPrimaryObject"); + let objects = realm.objects(IntPrimaryObject); realm.write(function () { - realm.create("IntPrimaryObject", { primaryCol: 2, valueCol: "a" }); - realm.create("IntPrimaryObject", { primaryCol: 3, valueCol: "a" }); - realm.create("IntPrimaryObject", { primaryCol: 1, valueCol: "b" }); - realm.create("IntPrimaryObject", { primaryCol: 4, valueCol: "c" }); - realm.create("IntPrimaryObject", { primaryCol: 0, valueCol: "c" }); + realm.create(IntPrimaryObject, { primaryCol: 2, valueCol: "a" }); + realm.create(IntPrimaryObject, { primaryCol: 3, valueCol: "a" }); + realm.create(IntPrimaryObject, { primaryCol: 1, valueCol: "b" }); + realm.create(IntPrimaryObject, { primaryCol: 4, valueCol: "c" }); + realm.create(IntPrimaryObject, { primaryCol: 0, valueCol: "c" }); }); const primaries = function (results: Realm.Results) { diff --git a/integration-tests/tests/src/tests/schema.ts b/integration-tests/tests/src/tests/schema.ts index 948907c8ec..2e06adc9dd 100644 --- a/integration-tests/tests/src/tests/schema.ts +++ b/integration-tests/tests/src/tests/schema.ts @@ -86,16 +86,17 @@ describe("Realm schema", () => { describe("Schema validation", () => { it("throws on invalid indexed type", () => { + const TestPropSchema: Realm.ObjectSchema = { + name: "testProp", + properties: { + //@ts-expect-error indexed is an invalid value in this test. + content: { type: "string", indexed: 22 }, + }, + }; + expect(() => { new Realm({ - schema: [ - { - name: "testProp", - properties: { - content: { type: "string", indexed: 22 }, - }, - }, - ], + schema: [TestPropSchema], }); }).throws( "Invalid type declaration for property 'content' on 'testProp': Expected 'content.indexed' on 'testProp' to be a boolean or 'full-text'", diff --git a/integration-tests/tests/src/tests/sets.ts b/integration-tests/tests/src/tests/sets.ts index 013bef4b82..90e4400688 100644 --- a/integration-tests/tests/src/tests/sets.ts +++ b/integration-tests/tests/src/tests/sets.ts @@ -47,7 +47,7 @@ describe("Sets", () => { it("short (JS) and canonical schema types yield the same results", () => { const shorthandSchema = IntSetObjectSchema; - const canonicalSchema = { + const canonicalSchema: Realm.ObjectSchema = { name: "CanonicalSchema", properties: { intSet: { type: "set", objectType: "int" }, diff --git a/integration-tests/tests/src/tests/shared-realms.ts b/integration-tests/tests/src/tests/shared-realms.ts index aa3c4df5cb..417190f2b7 100644 --- a/integration-tests/tests/src/tests/shared-realms.ts +++ b/integration-tests/tests/src/tests/shared-realms.ts @@ -104,7 +104,7 @@ describe("SharedRealm operations", () => { }); describe("List#unshift", () => { - type Person = { name: string; friends: List }; + type Person = { name: string; friends: Realm.List }; openRealmBeforeEach({ schema: [{ name: "Person", primaryKey: "name", properties: { name: "string", friends: "Person[]" } }], }); diff --git a/integration-tests/tests/src/tests/sync/app.ts b/integration-tests/tests/src/tests/sync/app.ts index c7ad5afd06..503ae07862 100644 --- a/integration-tests/tests/src/tests/sync/app.ts +++ b/integration-tests/tests/src/tests/sync/app.ts @@ -283,9 +283,7 @@ describe("App", () => { _sessionStopPolicy: "immediately", // Make it safe to delete files after realm.close() }, }; - //@ts-expect-error TYPEBUG: SyncConfiguration interfaces misses a user property. Realm.deleteFile(realmConfig); - //@ts-expect-error TYPEBUG: SyncConfiguration interfaces misses a user property. const realm = await Realm.open(realmConfig); expect(nCalls).equals(1); realm.write(() => { @@ -308,10 +306,8 @@ describe("App", () => { expect(realm.objects("Dog").length).equals(2); realm.close(); - //@ts-expect-error TYPEBUG: SyncConfiguration interfaces misses a user property. Realm.deleteFile(realmConfig); - //@ts-expect-error TYPEBUG: SyncConfiguration interfaces misses a user property. const realm2 = await Realm.open(realmConfig); expect(nCalls).equals(2); await realm2.syncSession?.downloadAllServerChanges(); diff --git a/integration-tests/tests/src/tests/sync/flexible.ts b/integration-tests/tests/src/tests/sync/flexible.ts index 1405a77fdc..c6a749710c 100644 --- a/integration-tests/tests/src/tests/sync/flexible.ts +++ b/integration-tests/tests/src/tests/sync/flexible.ts @@ -42,19 +42,58 @@ import Realm, { } from "realm"; import { authenticateUserBefore, importAppBefore, openRealmBeforeEach } from "../../hooks"; -import { DogSchema, IPerson, PersonSchema, IDog } from "../../schemas/person-and-dog-with-object-ids"; import { closeRealm } from "../../utils/close-realm"; import { expectClientResetError } from "../../utils/expect-sync-error"; import { createSyncConfig } from "../../utils/open-realm"; import { createPromiseHandle } from "../../utils/promise-handle"; import { buildAppConfig } from "../../utils/build-app-config"; -const FlexiblePersonSchema = { ...PersonSchema, properties: { ...PersonSchema.properties, nonQueryable: "string?" } }; +export const PersonSchema: Realm.ObjectSchema = { + name: "Person", + primaryKey: "_id", + properties: { + _id: "objectId", + age: "int", + name: "string", + friends: "Person[]", + nonQueryable: "string?", + }, +}; + +export class Person extends Realm.Object { + _id!: Realm.BSON.ObjectId; + name!: string; + age!: number; + friends!: Realm.List; + dogs!: Realm.Collection; + + static schema: Realm.ObjectSchema = PersonSchema; +} -type AddSubscriptionResult = { +export const DogSchema: Realm.ObjectSchema = { + name: "Dog", + primaryKey: "_id", + properties: { + _id: "objectId", + age: "int", + name: "string", + owner: "Person", + }, +}; + +export class Dog extends Realm.Object { + _id!: Realm.BSON.ObjectId; + name!: string; + age!: number; + owner!: Person; + + static schema: Realm.ObjectSchema = DogSchema; +} + +type AddSubscriptionResult> = { subs: Realm.App.Sync.SubscriptionSet; sub: Realm.App.Sync.Subscription; - query: Realm.Results; + query: Realm.Results; }; /** @@ -68,8 +107,8 @@ type AddSubscriptionResult = { function addSubscriptionForPerson( realm: Realm, options: Realm.App.Sync.SubscriptionOptions | undefined = undefined, -): AddSubscriptionResult { - return addSubscription(realm, realm.objects(FlexiblePersonSchema.name), options); +): AddSubscriptionResult { + return addSubscription(realm, realm.objects(Person), options); } /** @@ -83,8 +122,8 @@ function addSubscriptionForPerson( async function addSubscriptionForPersonAndSync( realm: Realm, options: Realm.App.Sync.SubscriptionOptions | undefined = undefined, -): Promise> { - return addSubscriptionAndSync(realm, realm.objects(FlexiblePersonSchema.name), options); +): Promise> { + return addSubscriptionAndSync(realm, realm.objects(Person), options); } /** @@ -96,9 +135,9 @@ async function addSubscriptionForPersonAndSync( * @returns Promise, resolving to an object containing the subscription set, the * added subscription and the query used for the subscription */ -function addSubscription( +function addSubscription>( realm: Realm, - query: Realm.Results>, + query: Realm.Results, options: Realm.App.Sync.SubscriptionOptions | undefined = undefined, ): AddSubscriptionResult { const subs = realm.subscriptions; @@ -119,9 +158,9 @@ function addSubscription( * @returns Promise, resolving to an object containing the subscription set, the * added subscription and the query used for the subscription */ -async function addSubscriptionAndSync( +async function addSubscriptionAndSync>( realm: Realm, - query: Realm.Results, + query: Realm.Results, options: Realm.App.Sync.SubscriptionOptions | undefined = undefined, ): Promise> { const subs = realm.subscriptions; @@ -216,7 +255,6 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("accepts { flexible: undefined } and a partition value", function () { expect(() => { - //@ts-expect-error Should show an error when defining flexible field with partition value. new Realm({ sync: { _sessionStopPolicy: SessionStopPolicy.Immediately, @@ -234,7 +272,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { initialSubscriptions: Realm.FlexibleSyncConfiguration["initialSubscriptions"], ): Realm.Configuration { return { - schema: [FlexiblePersonSchema, DogSchema], + schema: [Person, DogSchema], sync: { // @ts-expect-error Using an internal API _sessionStopPolicy: SessionStopPolicy.Immediately, @@ -297,7 +335,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { function getSuccessConfig(user: Realm.User, extraConfig: ExtraConfig = {}) { return getConfig(user, { update: (subs, realm) => { - subs.add(realm.objects(FlexiblePersonSchema.name)); + subs.add(realm.objects(Person)); }, ...extraConfig, }); @@ -433,8 +471,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { expect((compensatingWrites[1].primaryKey as BSON.ObjectId).equals(person2Id)).to.be.true; expect((compensatingWrites[2].primaryKey as BSON.ObjectId).equals(dogId)).to.be.true; - expect(compensatingWrites[0].objectName).to.equal(FlexiblePersonSchema.name); - expect(compensatingWrites[1].objectName).to.equal(FlexiblePersonSchema.name); + expect(compensatingWrites[0].objectName).to.equal(Person); + expect(compensatingWrites[1].objectName).to.equal(Person); expect(compensatingWrites[2].objectName).to.equal(DogSchema.name); expect(compensatingWrites[0].reason).to.contain("object is outside of the current query view"); @@ -445,7 +483,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }; const realm = await Realm.open({ - schema: [FlexiblePersonSchema, DogSchema], + schema: [Person, DogSchema], sync: { flexible: true, user: this.user, @@ -454,28 +492,28 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); await realm.subscriptions.update((mutableSubs) => { - mutableSubs.add(realm.objects(FlexiblePersonSchema.name).filtered("age < 30")); + mutableSubs.add(realm.objects(Person).filtered("age < 30")); mutableSubs.add(realm.objects(DogSchema.name).filtered("age > 5")); }); realm.write(() => { //Outside subscriptions - const tom = realm.create(FlexiblePersonSchema.name, { + const tom = realm.create(Person, { _id: person1Id, name: "Tom", age: 36, }); - realm.create(FlexiblePersonSchema.name, { _id: person2Id, name: "Maria", age: 44 }); - realm.create(DogSchema.name, { _id: dogId, name: "Puppy", age: 1, owner: tom }); + realm.create(Person, { _id: person2Id, name: "Maria", age: 44 }); + realm.create(Dog, { _id: dogId, name: "Puppy", age: 1, owner: tom }); //Inside subscriptions - const luigi = realm.create(FlexiblePersonSchema.name, { + const luigi = realm.create(Person, { _id: new BSON.ObjectId(), name: "Luigi", age: 20, }); - realm.create(FlexiblePersonSchema.name, { _id: new BSON.ObjectId(), name: "Mario", age: 22 }); - realm.create(DogSchema.name, { _id: new BSON.ObjectId(), name: "Oldy", age: 6, owner: luigi }); + realm.create(Person, { _id: new BSON.ObjectId(), name: "Mario", age: 22 }); + realm.create(Dog, { _id: new BSON.ObjectId(), name: "Oldy", age: 6, owner: luigi }); }); await realm.syncSession?.uploadAllLocalChanges(); @@ -485,9 +523,10 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { describe("with realm opened before", function () { openRealmBeforeEach({ - schema: [FlexiblePersonSchema, DogSchema], + schema: [Person, DogSchema], sync: { flexible: true, + //@ts-expect-error Using an internal API _sessionStopPolicy: SessionStopPolicy.Immediately, }, }); @@ -509,7 +548,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("throws an error if the Realm does not have a sync config", function (this: RealmContext) { - const realm = new Realm({ schema: [FlexiblePersonSchema] }); + const realm = new Realm({ schema: [Person] }); expect(() => realm.subscriptions).to.throw( "`subscriptions` can only be accessed if flexible sync is enabled, but sync is currently disabled for your app. Add a flexible sync config when opening the Realm, for example: { sync: { user, flexible: true } }", ); @@ -517,7 +556,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("throws an error if the Realm has a partition based sync config", function (this: RealmContext) { const realm = new Realm({ - schema: [FlexiblePersonSchema], + schema: [Person], sync: { user: this.user, partitionValue: "test" }, }); expect(() => realm.subscriptions).to.throw( @@ -554,7 +593,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("has an objectType", function (this: RealmContext) { const { sub } = addSubscriptionForPerson(this.realm); - expect(sub.objectType).to.equal(FlexiblePersonSchema.name); + expect(sub.objectType).to.equal(Person); }); it("has a default queryString", function (this: RealmContext) { @@ -563,26 +602,17 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("has a specified queryString", function (this: RealmContext) { - const { sub } = addSubscription( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - ); + const { sub } = addSubscription(this.realm, this.realm.objects(Person).filtered("age > 10")); expect(sub.queryString).to.equal("age > 10"); }); it("contains interpolated arguments in the queryString", function (this: RealmContext) { - const { sub } = addSubscription( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > $0", 10), - ); + const { sub } = addSubscription(this.realm, this.realm.objects(Person).filtered("age > $0", 10)); expect(sub.queryString).to.equal("age > 10"); }); it("does not include sort in the query string", function (this: RealmContext) { - const { sub } = addSubscription( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10").sorted("name"), - ); + const { sub } = addSubscription(this.realm, this.realm.objects(Person).filtered("age > 10").sorted("name")); expect(sub.queryString).to.equal("age > 10"); }); }); @@ -622,10 +652,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { // Should only pass if `"development_mode_enabled": true` it("does not throw if querying a not explicitly queryable field (ONLY VALID IN DEV MODE)", async function (this: RealmContext) { - const { subs } = addSubscription( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'"), - ); + const { subs } = addSubscription(this.realm, this.realm.objects(Person).filtered("nonQueryable == 'test'")); expect(subs.state).to.equal(Realm.App.Sync.SubscriptionSetState.Pending); await subs.waitForSynchronization(); @@ -636,10 +663,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { // TODO: Enable test when we can find another way of triggering a `SubscriptionSetState.Error`. // (This is due to non queryable fields now being queryable since BaaS automatically adds them when in Dev Mode) it.skip("is rejected if there is an error synchronising subscriptions", async function (this: RealmContext) { - const { subs } = addSubscription( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'"), - ); + const { subs } = addSubscription(this.realm, this.realm.objects(Person).filtered("nonQueryable == 'test'")); expect(subs.state).to.equal(Realm.App.Sync.SubscriptionSetState.Pending); await expect(subs.waitForSynchronization()).to.be.rejectedWith( @@ -652,10 +676,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { // TODO: Enable test when we can find another way of triggering a `SubscriptionSetState.Error`. // (This is due to non queryable fields now being queryable since BaaS automatically adds them when in Dev Mode) it.skip("is rejected if subscriptions are already in an error state", async function (this: RealmContext) { - const { subs } = addSubscription( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'"), - ); + const { subs } = addSubscription(this.realm, this.realm.objects(Person).filtered("nonQueryable == 'test'")); await expect(subs.waitForSynchronization()).to.be.rejectedWith( 'Client provided query with bad syntax: unsupported query for table "Person": key "nonQueryable" is not a queryable field', @@ -719,7 +740,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { expect(subs.isEmpty).to.be.true; await subs.update((mutableSubs) => { - sub = mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name)); + sub = mutableSubs.add(this.realm.objects(Person)); }); expect(subs.isEmpty).to.be.false; @@ -749,14 +770,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { describe("array-like access", function () { async function addThreeSubscriptions(this: RealmContext) { addSubscriptionForPerson(this.realm); - await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - ); - return await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age < 50"), - ); + await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age > 10")); + return await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age < 50")); } it("returns an empty array if there are no subscriptions", function (this: RealmContext) { @@ -768,6 +783,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { const { subs } = await addSubscriptionForPersonAndSync(this.realm); expect(subs).to.have.length(1); + //@ts-expect-error Accessing a SubscriptionSet using index operator expect(subs[0]).to.be.undefined; }); @@ -802,10 +818,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { const snapshot = subs; expect(snapshot).to.have.length(1); - await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - ); + await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age > 10")); expect(snapshot).to.have.length(1); }); @@ -825,7 +838,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { describe("#find", function () { it("returns null if the query is not subscribed to", function (this: RealmContext) { - expect(this.realm.subscriptions.findByQuery(this.realm.objects(FlexiblePersonSchema.name))).to.be.null; + const query = this.realm.objects(Person); + expect(this.realm.subscriptions.findByQuery(query)).to.be.null; }); it("returns a query's subscription by reference", async function (this: RealmContext) { @@ -836,21 +850,21 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("returns a filtered query's subscription", async function (this: RealmContext) { - const query = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + const query = this.realm.objects(Person).filtered("age > 10"); const { subs, sub } = await addSubscriptionAndSync(this.realm, query); expect(subs.findByQuery(query)).to.deep.equal(sub); }); it("returns a sorted query's subscription", async function (this: RealmContext) { - const query = this.realm.objects(FlexiblePersonSchema.name).sorted("age"); + const query = this.realm.objects(Person).sorted("age"); const { subs, sub } = await addSubscriptionAndSync(this.realm, query); expect(subs.findByQuery(query)).to.deep.equal(sub); }); it("returns a filtered and sorted query's subscription", async function (this: RealmContext) { - const query = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10").sorted("age"); + const query = this.realm.objects(Person).filtered("age > 10").sorted("age"); const { subs, sub } = await addSubscriptionAndSync(this.realm, query); expect(subs.findByQuery(query)).to.deep.equal(sub); @@ -859,7 +873,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("returns the subscription for a query which has an identical RQL representation (it does not need to be the same exact object)", async function (this: RealmContext) { const { subs, sub } = await addSubscriptionForPersonAndSync(this.realm); - expect(subs.findByQuery(this.realm.objects(FlexiblePersonSchema.name))).to.deep.equal(sub); + expect(subs.findByQuery(this.realm.objects(Person))).to.deep.equal(sub); }); }); @@ -880,10 +894,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { // (This is due to non queryable fields now being queryable since BaaS automatically adds them when in Dev Mode) it.skip("is Error if there is an error during synchronisation", async function (this: RealmContext) { await expect( - addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'"), - ), + addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("nonQueryable == 'test'")), ).to.be.rejectedWith( 'Client provided query with bad syntax: unsupported query for table "Person": key "nonQueryable" is not a queryable field', ); @@ -895,10 +906,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { // (This is due to non queryable fields now being queryable since BaaS automatically adds them when in Dev Mode) it.skip("is Error if there are two errors in a row", async function (this: RealmContext) { await expect( - addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'"), - ), + addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("nonQueryable == 'test'")), ).to.be.rejectedWith( 'Client provided query with bad syntax: unsupported query for table "Person": key "nonQueryable" is not a queryable field', ); @@ -906,10 +914,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { expect(this.realm.subscriptions.state).to.equal(Realm.App.Sync.SubscriptionSetState.Error); await expect( - addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'"), - ), + addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("nonQueryable == 'test'")), ).to.be.rejectedWith( 'Client provided query with bad syntax: unsupported query for table "Person": key "nonQueryable" is not a queryable field', ); @@ -956,10 +961,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { // (This is due to non queryable fields now being queryable since BaaS automatically adds them when in Dev Mode) it.skip("contains the error message if there was an error synchronising subscriptions", async function (this: RealmContext) { await expect( - addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'"), - ), + addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("nonQueryable == 'test'")), ).to.be.rejected; expect(this.realm.subscriptions.error).to.equal( @@ -971,10 +973,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { // (This is due to non queryable fields now being queryable since BaaS automatically adds them when in Dev Mode) it.skip("is null if there was an error but it was subsequently corrected", async function (this: RealmContext) { await expect( - addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'"), - ), + addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("nonQueryable == 'test'")), ).to.be.rejected; expect(this.realm.subscriptions.error).to.equal( @@ -984,7 +983,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { await expect( this.realm.subscriptions.update((mutableSubs) => { mutableSubs.removeAll(); - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(this.realm.objects(Person)); }), ).to.be.fulfilled; @@ -995,10 +994,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { // (This is due to non queryable fields now being queryable since BaaS automatically adds them when in Dev Mode) it.skip("still contains the erroring subscription in the set if there was an error synchronising", async function (this: RealmContext) { await expect( - addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'"), - ), + addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("nonQueryable == 'test'")), ).to.be.rejected; expect(this.realm.subscriptions).to.have.length(1); @@ -1014,7 +1010,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { const subsAsMutable = subscriptionInfo.subs as Realm.App.Sync.MutableSubscriptionSet; const calls = [ - () => subsAsMutable.add(this.realm.objects(FlexiblePersonSchema.name)), + () => subsAsMutable.add(this.realm.objects(Person)), () => subsAsMutable.remove(subscriptionInfo.query), () => subsAsMutable.removeByName("test"), () => subsAsMutable.removeSubscription(subscriptionInfo.sub), @@ -1034,7 +1030,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { expect( subs.update(async () => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(this.realm.objects(Person)); }), ).to.be.rejectedWith(/Wrong transactional state.*/); }); @@ -1049,7 +1045,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); expect(() => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(this.realm.objects(Person)); }).throws(/Wrong transactional state.*/); }); @@ -1077,7 +1073,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("mutates the SubscriptionSet instance", async function (this: RealmContext) { const subs = this.realm.subscriptions; await subs.update((mutableSubs) => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(this.realm.objects(Person)); }); expect(subs).to.have.length(1); @@ -1087,7 +1083,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { const subs = this.realm.subscriptions; const subs2 = this.realm.subscriptions; await subs.update((mutableSubs) => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(this.realm.objects(Person)); }); expect(subs2).to.have.length(0); @@ -1099,7 +1095,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("returns a promise", async function (this: RealmContext) { const subs = this.realm.subscriptions; const result = subs.update((mutableSubs) => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(this.realm.objects(Person)); }); expect(result).to.be.an.instanceOf(Promise); @@ -1110,7 +1106,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { this.longTimeout(); const subs = this.realm.subscriptions; await subs.update((mutableSubs) => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(this.realm.objects(Person)); }); expect(subs.state).to.equal(Realm.App.Sync.SubscriptionSetState.Complete); @@ -1123,7 +1119,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { await expect( subs.update((mutableSubs) => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'")); + mutableSubs.add(this.realm.objects(Person).filtered("nonQueryable == 'test'")); }), ).to.be.rejectedWith( 'Client provided query with bad syntax: unsupported query for table "Person": key "nonQueryable" is not a queryable field', @@ -1136,7 +1132,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("does not wait for subscriptions to be in a Complete state", async function (this: RealmContext) { const subs = this.realm.subscriptions; const result = subs.update((mutableSubs) => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(this.realm.objects(Person)); }); expect(subs.state).to.equal(Realm.App.Sync.SubscriptionSetState.Pending); @@ -1149,8 +1145,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { await subs.update((mutableSubs) => { mutableSubs.remove(query); - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered("age < 10")); - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered("age > 20")); + mutableSubs.add(this.realm.objects(Person).filtered("age < 10")); + mutableSubs.add(this.realm.objects(Person).filtered("age > 20")); mutableSubs.add(this.realm.objects(DogSchema.name).filtered("age > 30")); }); @@ -1158,10 +1154,10 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { const subsCopy = [...subs]; expect(subsCopy[0].queryString).to.equal("age < 10"); - expect(subsCopy[0].objectType).to.equal(FlexiblePersonSchema.name); + expect(subsCopy[0].objectType).to.equal(Person); expect(subsCopy[1].queryString).to.equal("age > 20"); - expect(subsCopy[1].objectType).to.equal(FlexiblePersonSchema.name); + expect(subsCopy[1].objectType).to.equal(Person); expect(subsCopy[2].queryString).to.equal("age > 30"); expect(subsCopy[2].objectType).to.equal(DogSchema.name); @@ -1172,11 +1168,11 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { await subs.update((mutableSubs) => { mutableSubs.remove(query); - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered("age < 10")); + mutableSubs.add(this.realm.objects(Person).filtered("age < 10")); }); await subs.update((mutableSubs) => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered("age > 20")); + mutableSubs.add(this.realm.objects(Person).filtered("age > 20")); mutableSubs.add(this.realm.objects(DogSchema.name).filtered("age > 30")); }); @@ -1184,10 +1180,10 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { const subsCopy = [...subs]; expect(subsCopy[0].queryString).to.equal("age < 10"); - expect(subsCopy[0].objectType).to.equal(FlexiblePersonSchema.name); + expect(subsCopy[0].objectType).to.equal(Person); expect(subsCopy[1].queryString).to.equal("age > 20"); - expect(subsCopy[1].objectType).to.equal(FlexiblePersonSchema.name); + expect(subsCopy[1].objectType).to.equal(Person); expect(subsCopy[2].queryString).to.equal("age > 30"); expect(subsCopy[2].objectType).to.equal(DogSchema.name); @@ -1200,8 +1196,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { await expect( subs.update((mutableSubs) => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered("age < 10")); - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered("nonQueryable == 'test'")); + mutableSubs.add(this.realm.objects(Person).filtered("age < 10")); + mutableSubs.add(this.realm.objects(Person).filtered("nonQueryable == 'test'")); mutableSubs.add(this.realm.objects(DogSchema.name).filtered("age > 30")); }), ).to.be.rejected; @@ -1224,7 +1220,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { /*const { subs } = addSubscriptionForPerson(this.realm); const result = await subs.update((mutableSubs) => { - return mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered("age < 10")); + return mutableSubs.add(this.realm.objects(Person).filtered("age < 10")); }); expect(result).to.be.an.instanceOf(Realm.App.Sync.Subscription); @@ -1265,34 +1261,24 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("adds a second subscription with the same object type and a different filter", async function (this: RealmContext) { - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name)); - await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - ); + addSubscription(this.realm, this.realm.objects(Person)); + await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age > 10")); expect(this.realm.subscriptions).to.have.lengthOf(2); }); it("does not add a second subscription with the same query and a different sort", async function (this: RealmContext) { - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name)); - const { subs } = await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).sorted("name"), - ); + addSubscription(this.realm, this.realm.objects(Person)); + const { subs } = await addSubscriptionAndSync(this.realm, this.realm.objects(Person).sorted("name")); expect(subs).to.have.lengthOf(1); }); it("updates an existing subscription with the same name and different query", async function (this: RealmContext) { - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name), { name: "test" }); - const { subs } = await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - { - name: "test", - }, - ); + addSubscription(this.realm, this.realm.objects(Person), { name: "test" }); + const { subs } = await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age > 10"), { + name: "test", + }); expect(subs).to.have.lengthOf(1); expect([...subs][0].queryString).to.equal("age > 10"); @@ -1301,17 +1287,10 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("allows an anonymous and a named subscription for the same query to exist", async function (this: RealmContext) { this.longTimeout(); - const { sub } = addSubscription( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - { - name: "test", - }, - ); - const { subs } = await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - ); + const { sub } = addSubscription(this.realm, this.realm.objects(Person).filtered("age > 10"), { + name: "test", + }); + const { subs } = await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age > 10")); expect(subs).to.have.lengthOf(2); expect([...subs][1].id).to.not.equal(sub.id); @@ -1387,7 +1366,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("returns true and removes the subscription if the subscription is found", async function (this: RealmContext) { - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10")); + addSubscription(this.realm, this.realm.objects(Person).filtered("age > 10")); const { subs } = addSubscriptionForPerson(this.realm, { name: "test" }); expect(subs).to.have.length(2); @@ -1401,7 +1380,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("returns true and removes a subscription with an empty name", async function (this: RealmContext) { - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10")); + addSubscription(this.realm, this.realm.objects(Person).filtered("age > 10")); const { subs } = addSubscriptionForPerson(this.realm, { name: "" }); expect(subs).to.have.length(2); @@ -1416,7 +1395,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { describe("#remove", function () { it("returns false and does not remove any subscriptions if the subscription for the query is not found", async function (this: RealmContext) { - const query = this.realm.objects(FlexiblePersonSchema.name); + const query = this.realm.objects(Person); const query2 = this.realm.objects(DogSchema.name); const { subs } = addSubscription(this.realm, query); @@ -1429,7 +1408,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("returns true and removes the subscription for the query if it is found", async function (this: RealmContext) { - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10")); + addSubscription(this.realm, this.realm.objects(Person).filtered("age > 10")); const { subs, query } = addSubscriptionForPerson(this.realm); expect(subs).to.have.length(2); @@ -1443,17 +1422,17 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("removes multiple subscriptions", async function (this: RealmContext) { - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("age > 15")); - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("name == 'John'")); - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("name BEGINSWITH 'A'")); + addSubscription(this.realm, this.realm.objects(Person).filtered("age > 15")); + addSubscription(this.realm, this.realm.objects(Person).filtered("name == 'John'")); + addSubscription(this.realm, this.realm.objects(Person).filtered("name BEGINSWITH 'A'")); const subs = this.realm.subscriptions; expect(subs).to.have.length(3); await subs.update((mutableSubs) => { - mutableSubs.remove(this.realm.objects(FlexiblePersonSchema.name).filtered("name == 'John'")); - mutableSubs.remove(this.realm.objects(FlexiblePersonSchema.name).filtered("name BEGINSWITH 'A'")); + mutableSubs.remove(this.realm.objects(Person).filtered("name == 'John'")); + mutableSubs.remove(this.realm.objects(Person).filtered("name BEGINSWITH 'A'")); }); expect(subs).to.have.length(1); @@ -1483,7 +1462,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("returns true and removes the subscription if the subscription is found", async function (this: RealmContext) { - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10")); + addSubscription(this.realm, this.realm.objects(Person).filtered("age > 10")); const { subs, sub } = addSubscriptionForPerson(this.realm); expect(subs).to.have.length(2); @@ -1534,10 +1513,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("removes all subscriptions and returns the number of subscriptions removed", async function (this: RealmContext) { addSubscriptionForPerson(this.realm); - await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - ); + await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age > 10")); await this.realm.subscriptions.update((mutableSubs) => { expect(mutableSubs.removeAll()).to.equal(2); @@ -1551,11 +1527,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("removes all unnamed subscriptions and returns the number of subscriptions removed", async function (this: RealmContext) { // Add 1 named and 2 unnamed subscriptions. addSubscriptionForPerson(this.realm, { name: "test" }); - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("age < 5")); - await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - ); + addSubscription(this.realm, this.realm.objects(Person).filtered("age < 5")); + await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age > 10")); expect(this.realm.subscriptions).to.have.length(3); let numRemoved = 0; @@ -1568,11 +1541,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("does not remove subscription with empty name", async function (this: RealmContext) { - await addSubscriptionAndSync( - this.realm, - this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"), - { name: "" }, - ); + await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age > 10"), { name: "" }); expect(this.realm.subscriptions).to.have.length(1); let numRemoved = 0; @@ -1598,11 +1567,11 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("removes all subscriptions for the object type and returns the number of subscriptions removed", async function (this: RealmContext) { addSubscriptionForPerson(this.realm); - addSubscription(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10")); + addSubscription(this.realm, this.realm.objects(Person).filtered("age > 10")); const { subs } = addSubscription(this.realm, this.realm.objects(DogSchema.name)); await subs.update((mutableSubs) => { - expect(mutableSubs.removeByObjectType(FlexiblePersonSchema.name)).to.equal(2); + expect(mutableSubs.removeByObjectType(Person.schema.name)).to.equal(2); }); expect(subs).to.have.length(1); @@ -1628,7 +1597,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("waits for objects to sync the first time only", async function (this: RealmContext) { expect(this.realm.subscriptions).to.have.length(0); - const peopleOver10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + const peopleOver10 = this.realm.objects(Person).filtered("age > 10"); // Subscribing the first time should wait for synchronization. await peopleOver10.subscribe({ behavior: WaitForSync.FirstTime }); @@ -1644,7 +1613,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("waits for objects to sync the first time only by default", async function (this: RealmContext) { expect(this.realm.subscriptions).to.have.length(0); - const peopleOver10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + const peopleOver10 = this.realm.objects(Person).filtered("age > 10"); await peopleOver10.subscribe(); expect(this.realm.subscriptions.state).to.equal(SubscriptionSetState.Complete); @@ -1659,12 +1628,12 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { expect(this.realm.subscriptions).to.have.length(0); // Subscribe to a query on 'Results' instance 1. - let peopleOver10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + let peopleOver10 = this.realm.objects(Person).filtered("age > 10"); await peopleOver10.subscribe({ behavior: WaitForSync.FirstTime }); expect(this.realm.subscriptions.state).to.equal(SubscriptionSetState.Complete); // Subscribe to the same query on 'Results' instance 2 (overwrite previous 'peopleOver10' value). - peopleOver10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + peopleOver10 = this.realm.objects(Person).filtered("age > 10"); await peopleOver10.subscribe({ behavior: WaitForSync.FirstTime }); expect(this.realm.subscriptions.state).to.equal(SubscriptionSetState.Pending); @@ -1674,7 +1643,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("always waits for objects to sync", async function (this: RealmContext) { expect(this.realm.subscriptions).to.have.length(0); - const peopleOver10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + const peopleOver10 = this.realm.objects(Person).filtered("age > 10"); await peopleOver10.subscribe({ behavior: WaitForSync.Always }); expect(this.realm.subscriptions.state).to.equal(SubscriptionSetState.Complete); @@ -1688,7 +1657,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("never waits for objects to sync", async function (this: RealmContext) { expect(this.realm.subscriptions).to.have.length(0); - const peopleOver10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + const peopleOver10 = this.realm.objects(Person).filtered("age > 10"); await peopleOver10.subscribe({ behavior: WaitForSync.Never }); expect(this.realm.subscriptions.state).to.equal(SubscriptionSetState.Pending); @@ -1702,7 +1671,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("waits for objects to sync when timeout is longer", async function (this: RealmContext) { expect(this.realm.subscriptions).to.have.length(0); - const peopleOver10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + const peopleOver10 = this.realm.objects(Person).filtered("age > 10"); // `this.timeout()` is used so that it doesn't exceed the timeout that our tests // are configured to use (which could vary). await peopleOver10.subscribe({ behavior: WaitForSync.Always, timeout: this.timeout() }); @@ -1714,7 +1683,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("does not wait for objects to sync when timeout is shorter", async function (this: RealmContext) { expect(this.realm.subscriptions).to.have.length(0); - const peopleOver10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + const peopleOver10 = this.realm.objects(Person).filtered("age > 10"); await peopleOver10.subscribe({ behavior: WaitForSync.Always, timeout: 0 }); expect(this.realm.subscriptions.state).to.equal(SubscriptionSetState.Pending); @@ -1722,7 +1691,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("returns the same 'Results' instance", async function (this: RealmContext) { - const beforeSubscribe = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + const beforeSubscribe = this.realm.objects(Person).filtered("age > 10"); const afterSubscribe = await beforeSubscribe.subscribe(); expect(beforeSubscribe).to.equal(afterSubscribe); }); @@ -1730,7 +1699,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { describe("Results#unsubscribe", function () { it("unsubscribes from existing subscription", async function (this: RealmContext) { - const peopleOver10 = await this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10").subscribe(); + const peopleOver10 = await this.realm.objects(Person).filtered("age > 10").subscribe(); expect(this.realm.subscriptions).to.have.length(1); peopleOver10.unsubscribe(); @@ -1738,8 +1707,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("does not throw or unsubscribe when there is no matching subscription", function (this: RealmContext) { - const peopleUnder10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age < 10").subscribe(); - const peopleOver10 = this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10"); + const peopleUnder10 = this.realm.objects(Person).filtered("age < 10").subscribe(); + const peopleOver10 = this.realm.objects(Person).filtered("age > 10"); expect(this.realm.subscriptions).to.have.length(1); // Unsubscribe to the Results without a subscription. @@ -1748,8 +1717,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("does not unsubscribe multiple times", async function (this: RealmContext) { - await this.realm.objects(FlexiblePersonSchema.name).filtered("age < 10").subscribe(); - const peopleOver10 = await this.realm.objects(FlexiblePersonSchema.name).filtered("age > 10").subscribe(); + await this.realm.objects(Person).filtered("age < 10").subscribe(); + const peopleOver10 = await this.realm.objects(Person).filtered("age > 10").subscribe(); expect(this.realm.subscriptions).to.have.length(2); peopleOver10.unsubscribe(); @@ -1760,12 +1729,9 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("unsubscribes from subscription with matching name", async function (this: RealmContext) { // Create 3 subscriptions with the same query: 2 named, 1 unnamed. const queryString = "age > 10"; - await this.realm.objects(FlexiblePersonSchema.name).filtered(queryString).subscribe({ name: "name1" }); - await this.realm.objects(FlexiblePersonSchema.name).filtered(queryString).subscribe(); - const peopleOver10 = await this.realm - .objects(FlexiblePersonSchema.name) - .filtered(queryString) - .subscribe({ name: "name2" }); + await this.realm.objects(Person).filtered(queryString).subscribe({ name: "name1" }); + await this.realm.objects(Person).filtered(queryString).subscribe(); + const peopleOver10 = await this.realm.objects(Person).filtered(queryString).subscribe({ name: "name2" }); expect(this.realm.subscriptions).to.have.length(3); // Expect only the "name2" subscription to be gone. @@ -1782,13 +1748,13 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("unsubscribes from subscription with matching name when subscribing via `update()`", async function (this: RealmContext) { // Save a reference to a Results that is not yet subscribed to. const queryString = "age > 10"; - const peopleOver10 = await this.realm.objects(FlexiblePersonSchema.name).filtered(queryString); + const peopleOver10 = await this.realm.objects(Person).filtered(queryString); expect(this.realm.subscriptions).to.have.length(0); // Create 3 subscriptions via `update()` with the same query: 2 named, 1 unnamed. await this.realm.subscriptions.update((mutableSubs) => { - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered(queryString), { name: "name1" }); - mutableSubs.add(this.realm.objects(FlexiblePersonSchema.name).filtered(queryString)); + mutableSubs.add(this.realm.objects(Person).filtered(queryString), { name: "name1" }); + mutableSubs.add(this.realm.objects(Person).filtered(queryString)); // Pass the Results reference to subscribe to. mutableSubs.add(peopleOver10, { name: "name2" }); }); @@ -1807,8 +1773,8 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("unsubscribes from subscription with matching query", async function (this: RealmContext) { const queryString = "age > 10"; - const results1 = await this.realm.objects(FlexiblePersonSchema.name).filtered(queryString).subscribe(); - const results2 = await this.realm.objects(FlexiblePersonSchema.name).filtered(queryString); + const results1 = await this.realm.objects(Person).filtered(queryString).subscribe(); + const results2 = await this.realm.objects(Person).filtered(queryString); expect(this.realm.subscriptions).to.have.length(1); // Even though `subscribe()` was called on `results1`, `unsubscribe()` removes unnamed @@ -1843,9 +1809,9 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { * @param realm Realm instance * @returns Promise, resolving to an object containing the object and its id */ - async function addPersonAndWaitForUpload(realm: Realm): Promise<{ person: IPerson; id: BSON.ObjectId }> { + async function addPersonAndWaitForUpload(realm: Realm): Promise<{ person: Person; id: BSON.ObjectId }> { const person = realm.write(function () { - return realm.create(FlexiblePersonSchema.name, { _id: new BSON.ObjectId(), name: "Tom", age: 36 }); + return realm.create(Person, { _id: new BSON.ObjectId(), name: "Tom", age: 36 }); }); // Save the values we want to return, as this could be invalid after uploading, depending on the flexible sync criteria @@ -1884,7 +1850,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { await context.closeRealm({ reopen: true }); const { realm: newRealm } = context; - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.be.null; await newRealm.subscriptions.update((mutableSubs) => subsUpdateFn(mutableSubs, newRealm)); return { id, newRealm }; @@ -1892,70 +1858,70 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("syncs added items to a subscribed collection", async function (this: RealmContext) { const { id, newRealm } = await addPersonAndResyncWithSubscription(this, (mutableSubs, realm) => { - mutableSubs.add(realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(realm.objects(Person)); }); - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.not.be.null; - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.not.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.not.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.not.be.null; }); it("syncs added items to a subscribed collection with a filter", async function (this: RealmContext) { const { id, newRealm } = await addPersonAndResyncWithSubscription(this, (mutableSubs, realm) => { - mutableSubs.add(realm.objects(FlexiblePersonSchema.name).filtered("age > 30")); + mutableSubs.add(realm.objects(Person).filtered("age > 30")); }); - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.not.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.not.be.null; }); it("does not sync added items not matching the filter", async function (this: RealmContext) { const { id, newRealm } = await addPersonAndResyncWithSubscription(this, (mutableSubs, realm) => { - mutableSubs.add(realm.objects(FlexiblePersonSchema.name).filtered("age < 30")); + mutableSubs.add(realm.objects(Person).filtered("age < 30")); }); - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.be.null; }); // TODO: Probably remove this as it is testing old functionality it.skip("starts syncing items if a new subscription is added matching some items", async function (this: RealmContext) { const { id, newRealm } = await addPersonAndResyncWithSubscription(this, (mutableSubs, realm) => { - mutableSubs.add(realm.objects(FlexiblePersonSchema.name).filtered("age < 30")); + mutableSubs.add(realm.objects(Person).filtered("age < 30")); }); - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.be.null; const subs = newRealm.subscriptions; await subs.update((mutableSubs) => { - mutableSubs.add(newRealm.objects(FlexiblePersonSchema.name).filtered("age > 30")); + mutableSubs.add(newRealm.objects(Person).filtered("age > 30")); }); newRealm.addListener("change", () => { - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.not.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.not.be.null; }); }); // TODO: Probably remove this as it is testing old functionality it.skip("starts syncing items if the subscription is replaced to match some items", async function (this: RealmContext) { const { id, newRealm } = await addPersonAndResyncWithSubscription(this, (mutableSubs, realm) => { - mutableSubs.add(realm.objects(FlexiblePersonSchema.name).filtered("age < 30")); + mutableSubs.add(realm.objects(Person).filtered("age < 30")); }); - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.be.null; const subs = newRealm.subscriptions; await subs.update((mutableSubs) => { mutableSubs.removeAll(); - mutableSubs.add(newRealm.objects(FlexiblePersonSchema.name).filtered("age > 30")); + mutableSubs.add(newRealm.objects(Person).filtered("age > 30")); }); newRealm.addListener("change", () => { - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.not.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.not.be.null; }); }); it("stops syncing items when a subscription is removed (but other subscriptions still exist)", async function (this: RealmContext) { const { id, newRealm } = await addPersonAndResyncWithSubscription(this, (mutableSubs, realm) => { - mutableSubs.add(realm.objects(FlexiblePersonSchema.name).filtered("age < 40"), { name: "test" }); - mutableSubs.add(realm.objects(FlexiblePersonSchema.name).filtered("age > 50")); + mutableSubs.add(realm.objects(Person).filtered("age < 40"), { name: "test" }); + mutableSubs.add(realm.objects(Person).filtered("age > 50")); }); - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.not.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.not.be.null; const subs = newRealm.subscriptions; await subs.update((mutableSubs) => { @@ -1963,15 +1929,15 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); newRealm.addListener("change", () => { - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.be.null; }); }); it("stops syncing items when all subscriptions are removed", async function (this: RealmContext) { const { id, newRealm } = await addPersonAndResyncWithSubscription(this, (mutableSubs, realm) => { - mutableSubs.add(realm.objects(FlexiblePersonSchema.name)); + mutableSubs.add(realm.objects(Person)); }); - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.not.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.not.be.null; const subs = newRealm.subscriptions; await subs.update((mutableSubs) => { @@ -1979,23 +1945,23 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); newRealm.addListener("change", () => { - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.be.null; }); }); it("stops syncing items if the filter changes to not match some items", async function (this: RealmContext) { const { id, newRealm } = await addPersonAndResyncWithSubscription(this, (mutableSubs, realm) => { - mutableSubs.add(realm.objects(FlexiblePersonSchema.name).filtered("age > 30")); + mutableSubs.add(realm.objects(Person).filtered("age > 30")); }); - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.not.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.not.be.null; const subs = newRealm.subscriptions; await subs.update((mutableSubs) => { mutableSubs.removeAll(); - mutableSubs.add(newRealm.objects(FlexiblePersonSchema.name).filtered("age < 30")); + mutableSubs.add(newRealm.objects(Person).filtered("age < 30")); }); - expect(newRealm.objectForPrimaryKey(FlexiblePersonSchema.name, id)).to.be.null; + expect(newRealm.objectForPrimaryKey(Person, id)).to.be.null; }); // TODO test more complex integration scenarios, e.g. links, embedded objects, collections, complex queries @@ -2004,7 +1970,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("throw an exception if items are added without a subscription", function (this: RealmContext) { this.realm.write(() => { expect(() => { - this.realm.create(FlexiblePersonSchema.name, { + this.realm.create(Person, { _id: new BSON.ObjectId(), name: "Tom", age: 36, @@ -2014,10 +1980,10 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }); it("deletes the item if an item not matching the filter is created", async function (this: RealmContext) { - await addSubscriptionAndSync(this.realm, this.realm.objects(FlexiblePersonSchema.name).filtered("age < 30")); + await addSubscriptionAndSync(this.realm, this.realm.objects(Person).filtered("age < 30")); const tom = this.realm.write(() => - this.realm.create(FlexiblePersonSchema.name, { + this.realm.create(Person, { _id: new BSON.ObjectId(), name: "Tom Old", age: 99, @@ -2040,7 +2006,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { this.realm.write(() => { expect(() => { - this.realm.create(FlexiblePersonSchema.name, { + this.realm.create(Person, { _id: new BSON.ObjectId(), name: "Tom", age: 36, @@ -2053,10 +2019,10 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { const realm = this.realm; const action = async () => { - await addSubscriptionAndSync(realm, realm.objects(FlexiblePersonSchema.name).filtered("age < 40")); + await addSubscriptionAndSync(realm, realm.objects(Person).filtered("age < 40")); const person = realm.write(() => { - return realm.create(FlexiblePersonSchema.name, { + return realm.create(Person, { _id: new BSON.ObjectId(), name: "Tom", age: 36, @@ -2077,8 +2043,9 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("handles manual client resets with flexible sync enabled", async function (this: RealmContext) { await expectClientResetError( { - schema: [FlexiblePersonSchema, DogSchema], + schema: [Person, DogSchema], sync: { + //@ts-expect-error non-public internal configuration. _sessionStopPolicy: SessionStopPolicy.Immediately, flexible: true, user: this.user, @@ -2094,7 +2061,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { // @ts-ignore calling undocumented method _simulateError session._simulateError(211, "Simulate Client Reset", "realm::sync::ProtocolError", false); // 211 -> diverging histories }, - (error) => { + (error: Realm.SyncError) => { expect(error.name).to.equal("ClientReset"); expect(error.message).to.equal("Simulate Client Reset"); expect(error.code).to.equal(211); diff --git a/integration-tests/tests/src/tests/sync/mongo-db-client.ts b/integration-tests/tests/src/tests/sync/mongo-db-client.ts index 7aff0f6d79..dc47f5a45c 100644 --- a/integration-tests/tests/src/tests/sync/mongo-db-client.ts +++ b/integration-tests/tests/src/tests/sync/mongo-db-client.ts @@ -29,7 +29,7 @@ type ChangeEvent = Realm.Services.MongoDB.ChangeEvent; type InsertEvent = Realm.Services.MongoDB.InsertEvent; type TestDocument = { - _id: BSON.ObjectId; + _id: BSON.ObjectId | number; text?: string; isLast?: boolean; date?: Date; diff --git a/integration-tests/tests/src/tests/sync/open-behavior.ts b/integration-tests/tests/src/tests/sync/open-behavior.ts index 8e5b3612fe..2626dbc5c1 100644 --- a/integration-tests/tests/src/tests/sync/open-behavior.ts +++ b/integration-tests/tests/src/tests/sync/open-behavior.ts @@ -105,17 +105,16 @@ describe("OpenBehaviour", function () { }); realm.close(); - const config2: Realm.Configuration = { + const config2 = { schema: [DogForSyncSchema], sync: { - user, + user: user as Realm.User, partitionValue, - //@ts-expect-error const enum is removed at runtime, should either remove const or leave this as is. existingRealmFileBehavior: { type: "openImmediately" }, }, }; - realm = await Realm.open(config2); + realm = await Realm.open(config2 as Realm.Configuration); expect(realm.objects(DogForSyncSchema.name).length).equals(1); }); @@ -129,8 +128,8 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, + //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", - //@ts-expect-error const enum is removed at runtime, should either remove const or leave this as is. newRealmFileBehavior: { type: "downloadBeforeOpen" }, }, }; @@ -187,8 +186,8 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - _sessionStopPolicy: "immediately", //@ts-expect-error TYPEBUG: cannot access const enum at runtime + _sessionStopPolicy: "immediately", existingRealmFileBehavior: { type: "downloadBeforeOpen" }, }, }; @@ -207,12 +206,11 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, + //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", newRealmFileBehavior: { - //@ts-expect-error TYPEBUG: cannot access const enum at runtime type: "downloadBeforeOpen", timeOut: 0, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime timeOutBehavior: "throwException", }, }, @@ -252,12 +250,11 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, + //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", existingRealmFileBehavior: { - //@ts-expect-error TYPEBUG: cannot access const enum at runtime type: "downloadBeforeOpen", timeOut: 0, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime timeOutBehavior: "throwException", }, }, @@ -314,12 +311,11 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, + //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", newRealmFileBehavior: { - //@ts-expect-error TYPEBUG: cannot access const enum at runtime type: "downloadBeforeOpen", timeOut: 0, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime timeOutBehavior: "openLocalRealm", }, }, @@ -394,12 +390,11 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, + //@ts-expect-error TYPEBUG: cannot access const enum at runtime _sessionStopPolicy: "immediately", existingRealmFileBehavior: { - //@ts-expect-error TYPEBUG: cannot access const enum at runtime type: "downloadBeforeOpen", timeOut: 0, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime timeOutBehavior: "openLocalRealm", }, }, @@ -461,11 +456,9 @@ describe("OpenBehaviour", function () { user, partitionValue, existingRealmFileBehavior: { - //@ts-expect-error TYPEBUG: cannot access const enum at runtime - type: "downloadBeforeOpen", + type: OpenRealmBehaviorType.DownloadBeforeOpen, timeOut: 1000, - //@ts-expect-error TYPEBUG: cannot access const enum at runtime - timeOutBehavior: "openLocalRealm", + timeOutBehavior: OpenRealmTimeOutBehavior.OpenLocalRealm, }, }, }; @@ -487,8 +480,8 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - _sessionStopPolicy: "immediately", //@ts-expect-error TYPEBUG: cannot access const enum at runtime + _sessionStopPolicy: "immediately", newRealmFileBehavior: { type: "downloadBeforeOpen" }, }, }; @@ -521,8 +514,8 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - _sessionStopPolicy: "immediately", //@ts-expect-error TYPEBUG: cannot access const enum at runtime + _sessionStopPolicy: "immediately", newRealmFileBehavior: { type: "downloadBeforeOpen" }, }, }; @@ -543,8 +536,8 @@ describe("OpenBehaviour", function () { sync: { user, partitionValue, - _sessionStopPolicy: "immediately", //@ts-expect-error TYPEBUG: cannot access const enum at runtime + _sessionStopPolicy: "immediately", newRealmFileBehavior: { type: "downloadBeforeOpen" }, }, }; @@ -585,10 +578,9 @@ describe("OpenBehaviour", function () { user, partitionValue, _sessionStopPolicy: "immediately", - //@ts-expect-error testing invalid value for newRealmFileBehaviour newRealmFileBehavior: { type: "foo" }, }, - }), + } as unknown as Realm.Configuration), ).throws; await expect(() => @@ -598,10 +590,9 @@ describe("OpenBehaviour", function () { user, partitionValue, _sessionStopPolicy: "immediately", - //@ts-expect-error testing invalid value for newRealmFileBehaviour - newRealmFileBehavior: { type: "openLocalRealm", timeOutBehavior: "foo" }, + newRealmFileBehavior: { type: OpenRealmBehaviorType.OpenImmediately, timeOutBehavior: "foo" }, }, - }), + } as unknown as Realm.Configuration), ).throws; await expect(() => @@ -611,10 +602,9 @@ describe("OpenBehaviour", function () { user, partitionValue, _sessionStopPolicy: "immediately", - //@ts-expect-error testing invalid value for newRealmFileBehaviour - newRealmFileBehavior: { type: "openLocalRealm", timeOut: "bar" }, + newRealmFileBehavior: { type: OpenRealmBehaviorType.OpenImmediately, timeOut: "bar" }, }, - }), + } as unknown as Realm.Configuration), ).throws; }); }); diff --git a/integration-tests/tests/src/tests/sync/realm-conversions.ts b/integration-tests/tests/src/tests/sync/realm-conversions.ts index b7cdb9ae2b..a928354192 100644 --- a/integration-tests/tests/src/tests/sync/realm-conversions.ts +++ b/integration-tests/tests/src/tests/sync/realm-conversions.ts @@ -22,7 +22,7 @@ import { importAppBefore } from "../../hooks"; import { getRegisteredEmailPassCredentials } from "../../utils/credentials"; import { buildAppConfig } from "../../utils/build-app-config"; -const DogForSyncSchema = { +const DogForSyncSchema: Realm.ObjectSchema = { name: "Dog", primaryKey: "_id", properties: { @@ -33,7 +33,7 @@ const DogForSyncSchema = { }, }; -const PersonForSyncSchema = { +const PersonForSyncSchema: Realm.ObjectSchema = { name: "Person", primaryKey: "_id", properties: { diff --git a/integration-tests/tests/src/tests/sync/realm.ts b/integration-tests/tests/src/tests/sync/realm.ts index dc18ec11cf..2c32551250 100644 --- a/integration-tests/tests/src/tests/sync/realm.ts +++ b/integration-tests/tests/src/tests/sync/realm.ts @@ -24,7 +24,7 @@ import { expectArraysEqual, expectDecimalEqual } from "../../utils/comparisons"; import { sleep } from "../../utils/sleep"; import { buildAppConfig } from "../../utils/build-app-config"; -const CarSchema = { +const CarSchema: Realm.ObjectSchema = { name: "Car", properties: { make: "string", @@ -33,14 +33,14 @@ const CarSchema = { }, }; -const TestObjectSchema = { +const TestObjectSchema: Realm.ObjectSchema = { name: "TestObject", properties: { doubleCol: "double", }, }; -const AllTypesSchema = { +const AllTypesSchema: Realm.ObjectSchema = { name: "AllTypesObject", properties: { boolCol: "bool", @@ -81,21 +81,21 @@ const AllTypesSchema = { }, }; -const LinkToAllTypesObjectSchema = { +const LinkToAllTypesObjectSchema: Realm.ObjectSchema = { name: "LinkToAllTypesObject", properties: { allTypesCol: "AllTypesObject", }, }; -const IntOnlySchema = { +const IntOnlySchema: Realm.ObjectSchema = { name: "IntOnlyObject", properties: { intCol: "int", }, }; -const IntPrimarySchema = { +const IntPrimarySchema: Realm.ObjectSchema = { name: "IntPrimaryObject", primaryKey: "primaryCol", properties: { @@ -104,7 +104,7 @@ const IntPrimarySchema = { }, }; -const AllPrimaryTypesSchema = { +const AllPrimaryTypesSchema: Realm.ObjectSchema = { name: "AllPrimaryTypesObject", primaryKey: "primaryCol", properties: { @@ -121,7 +121,7 @@ const AllPrimaryTypesSchema = { }, }; -const StringPrimarySchema = { +const StringPrimarySchema: Realm.ObjectSchema = { name: "StringPrimaryObject", primaryKey: "primaryCol", properties: { @@ -130,7 +130,7 @@ const StringPrimarySchema = { }, }; -const OptionalStringSchema = { +const OptionalStringSchema: Realm.ObjectSchema = { name: "OptionalString", properties: { name: "string", @@ -138,7 +138,7 @@ const OptionalStringSchema = { }, }; -const IndexedTypesSchema = { +const IndexedTypesSchema: Realm.ObjectSchema = { name: "IndexedTypesObject", properties: { boolCol: { type: "bool", indexed: true }, @@ -194,7 +194,7 @@ const LinkingObjectsObjectSchema: Realm.ObjectSchema = { }, }; -const DateObjectSchema = { +const DateObjectSchema: Realm.ObjectSchema = { name: "Date", properties: { currentDate: "date", @@ -202,14 +202,14 @@ const DateObjectSchema = { }, }; -const StringOnlySchema = { +const StringOnlySchema: Realm.ObjectSchema = { name: "StringOnlyObject", properties: { stringCol: "string", }, }; -const TestObjectWithPkSchema = { +const TestObjectWithPkSchema: Realm.ObjectSchema = { name: "TestObject", primaryKey: "_id", properties: { @@ -218,7 +218,7 @@ const TestObjectWithPkSchema = { }, }; -const ObjectWithoutPropertiesSchema = { +const ObjectWithoutPropertiesSchema: Realm.ObjectSchema = { name: "ObjectWithoutProperties", properties: {}, }; @@ -265,7 +265,7 @@ const EmbeddedObjectSchemas: Realm.ObjectSchema[] = [ }, ]; -const PersonSchema = { +const PersonSchema: Realm.ObjectSchema = { name: "Person", primaryKey: "name", properties: { @@ -275,7 +275,7 @@ const PersonSchema = { }, }; -const DogSchema = { +const DogSchema: Realm.ObjectSchema = { name: "Dog", properties: { age: "int", @@ -383,7 +383,7 @@ interface IDateObject { nullDate: Date | undefined; } -class TestObject extends Realm.Object { +class TestObject extends Realm.Object { doubleCol!: number; static schema: Realm.ObjectSchema = { name: "TestObject", @@ -393,7 +393,7 @@ class TestObject extends Realm.Object { }; } -class PersonObject extends Realm.Object { +class PersonObject extends Realm.Object { name!: string; age!: number; married!: boolean; @@ -1057,16 +1057,26 @@ describe("Realmtest", () => { const obj = this.realm.create(DefaultValuesSchema.name, {}); const properties = DefaultValuesSchema.properties; + //@ts-expect-error it's currently not typed for access expect(obj.boolCol).equals(properties.boolCol.default); + //@ts-expect-error it's currently not typed for access expect(obj.intCol).equals(properties.intCol.default); + //@ts-expect-error it's currently not typed for access expectDecimalEqual(obj.floatCol, properties.floatCol.default); + //@ts-expect-error it's currently not typed for access expectDecimalEqual(obj.doubleCol, properties.doubleCol.default); + //@ts-expect-error it's currently not typed for access expect(obj.stringCol).equals(properties.stringCol.default); + //@ts-expect-error it's currently not typed for access expect(obj.dateCol.getTime()).equals(properties.dateCol.default.getTime()); + //@ts-expect-error it's currently not typed for access expect(obj.dataCol.byteLength).equals(properties.dataCol.default.byteLength); + //@ts-expect-error it's currently not typed for access expect(obj.objectCol.doubleCol).equals(properties.objectCol.default.doubleCol); expect(obj.nullObjectCol).equals(null); + //@ts-expect-error it's currently not typed for access expect(obj.arrayCol.length).equals(properties.arrayCol.default.length); + //@ts-expect-error it's currently not typed for access expect(obj.arrayCol[0].doubleCol).equals(properties.arrayCol.default[0].doubleCol); }; @@ -1161,7 +1171,6 @@ describe("Realmtest", () => { //@ts-expect-error Invalid object is not a proper schema realm = new Realm({ schema: [CustomObject, InvalidObject] }); - const obj = realm.objects("CustomObject")[0]; expect(realm.objects("CustomObject")[0]).instanceof(CustomObject); expect(realm.objects(CustomObject).length > 0).to.be.true; realm.close(); diff --git a/integration-tests/tests/src/tests/sync/sync-session.ts b/integration-tests/tests/src/tests/sync/sync-session.ts index 88a15bc3bc..7b2abf929d 100644 --- a/integration-tests/tests/src/tests/sync/sync-session.ts +++ b/integration-tests/tests/src/tests/sync/sync-session.ts @@ -26,7 +26,7 @@ import { importApp } from "../../utils/import-app"; import { sleep, throwAfterTimeout } from "../../utils/sleep"; import { buildAppConfig } from "../../utils/build-app-config"; -const DogForSyncSchema = { +const DogForSyncSchema: Realm.ObjectSchema = { name: "Dog", primaryKey: "_id", properties: { @@ -37,7 +37,7 @@ const DogForSyncSchema = { }, }; -const PersonForSyncSchema = { +const PersonForSyncSchema: Realm.ObjectSchema = { name: "Person", primaryKey: "_id", properties: { @@ -611,6 +611,7 @@ describe("SessionTest", () => { describe("hasExistingSessions", () => { afterEach(() => Realm.clearTestState()); it("starting and stopping syncsessions propagates to hasExistingSessions", async function (this: AppContext) { + //@ts-expect-error internal method expect(Realm.App.Sync._hasExistingSessions(this.app)).to.be.false; const credentials = Realm.Credentials.anonymous(); @@ -618,12 +619,14 @@ describe("SessionTest", () => { return this.app.logIn(credentials).then((user) => { const config = getSyncConfiguration(user, partition); const realm = new Realm(config); + //@ts-expect-error internal method expect(Realm.App.Sync._hasExistingSessions(this.app)).to.be.true; realm.close(); // Wait for the session to finish return async () => { for (let i = 50; i >= 0; i--) { + //@ts-expect-error internal method if (!Realm.App.Sync._hasExistingSessions(this.app)) { return; } @@ -717,11 +720,14 @@ describe("SessionTest", () => { config.sync._sessionStopPolicy = "immediately"; { + //@ts-expect-error internal method expect(Realm.App.Sync._hasExistingSessions(this.app)).to.be.false; const realm = new Realm(config); + //@ts-expect-error internal method expect(Realm.App.Sync._hasExistingSessions(this.app)).to.be.true; realm.close(); } + //@ts-expect-error internal method expect(Realm.App.Sync._hasExistingSessions(this.app)).to.be.false; }); }); @@ -1045,7 +1051,6 @@ describe("SessionTest", () => { //@ts-expect-error internal field _sessionStopPolicy: "immediately", // Make it safe to delete files after realm.close() clientReset: { - //@ts-expect-error TYPEBUG: enum not exposed in realm namespace mode: "manual", onManual: (...args) => console.log("error", args), }, diff --git a/integration-tests/tests/src/tests/sync/user.ts b/integration-tests/tests/src/tests/sync/user.ts index 1b3405a532..73268f90c3 100644 --- a/integration-tests/tests/src/tests/sync/user.ts +++ b/integration-tests/tests/src/tests/sync/user.ts @@ -79,6 +79,7 @@ describe.skipIf(environment.missingServer, "User", () => { removeExistingUsers(); it("login without username throws", async function (this: AppContext & RealmContext) { + //@ts-expect-error email cannot be undefined. expect(() => Realm.Credentials.emailPassword({ email: undefined, password: "password" })).throws( "Expected 'email' to be a string, got undefined", ); @@ -86,6 +87,7 @@ describe.skipIf(environment.missingServer, "User", () => { it("login without password throws", async function (this: AppContext & RealmContext) { const username = new Realm.BSON.UUID().toHexString(); + //@ts-expect-error password cannot be undefined. expect(() => Realm.Credentials.emailPassword({ email: username, password: undefined })).throws( "Expected 'password' to be a string, got undefined", ); diff --git a/integration-tests/tests/src/typings.d.ts b/integration-tests/tests/src/typings.d.ts index aef8b05e3f..9d6c5ea921 100644 --- a/integration-tests/tests/src/typings.d.ts +++ b/integration-tests/tests/src/typings.d.ts @@ -191,6 +191,9 @@ declare namespace Chai { /** Calls the callback on the next tick of the event loop */ declare function setImmediate(cb: () => void): void; +/** Rough typing of setTimeout to avoid type errors */ +declare function setTimeout(cb: (args: any[]) => void, timeout: number): any; + interface Console { error(message?: unknown, ...optionalParams: unknown[]): void; log(message?: unknown, ...optionalParams: unknown[]): void; diff --git a/integration-tests/tests/src/utils/ExtendedAppConfigBuilder.ts b/integration-tests/tests/src/utils/ExtendedAppConfigBuilder.ts index 3a9ae412ad..bfa9b28ca5 100644 --- a/integration-tests/tests/src/utils/ExtendedAppConfigBuilder.ts +++ b/integration-tests/tests/src/utils/ExtendedAppConfigBuilder.ts @@ -20,9 +20,12 @@ import { PartitionConfig, CustomTokenAuthMetadataField, EmailPasswordAuthConfig, + FlexibleSyncConfig, + PartitionSyncConfig, } from "@realm/app-importer"; import { randomDatabaseName } from "./generators"; +import { DisabledConfig } from "@realm/app-importer/src/AppConfigBuilder"; // Setting the mongodbClusterName on the Mocha Remote context will default the service type of mongodb services to "mongodb-atlas" // This makes sense because there's no reason to provide the cluster name if we're not on Atlas. @@ -183,7 +186,7 @@ export class ExtendedAppConfigBuilder extends AppConfigBuilder { exports = async function (appId, userId) { return (await deleteClientFile("__realm_sync_" + appId, userId)) || (await deleteClientFile("__realm_sync", userId)); }; - + async function deleteClientFile(db, userId) { const mongodb = context.services.get("mongodb"); return (await mongodb.db(db).collection("clientfiles").deleteMany({ ownerId: userId })).deletedCount > 0; @@ -210,7 +213,9 @@ export function buildMongoDBConfig(config: MongoServiceSyncConfig) { } } -function buildMongoDBSyncConfig(config: MongoServiceSyncConfig) { +function buildMongoDBSyncConfig( + config: MongoServiceSyncConfig, +): DisabledConfig | FlexibleSyncConfig | PartitionSyncConfig { if (config.kind === "disabled") { return {}; } else if (config.kind === "flexible") { diff --git a/integration-tests/tests/src/utils/credentials.ts b/integration-tests/tests/src/utils/credentials.ts index 8b633080b9..502e11c25d 100644 --- a/integration-tests/tests/src/utils/credentials.ts +++ b/integration-tests/tests/src/utils/credentials.ts @@ -16,10 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { App, Credentials } from "realm"; +import { Credentials } from "realm"; import { randomVerifiableEmail } from "./generators"; -export async function getRegisteredEmailPassCredentials(app: App): Promise { +export async function getRegisteredEmailPassCredentials(app: Realm.App): Promise { if (!app) { throw new Error("No app supplied to 'getRegisteredEmailPassCredentials'"); } diff --git a/integration-tests/tests/src/utils/open-realm.ts b/integration-tests/tests/src/utils/open-realm.ts index 105e68c231..8b653dc9f8 100644 --- a/integration-tests/tests/src/utils/open-realm.ts +++ b/integration-tests/tests/src/utils/open-realm.ts @@ -47,7 +47,7 @@ export type OpenRealmConfiguration = ConfigurationWithoutSync | ConfigurationWit */ export async function openRealm( partialConfig: LocalConfiguration | Partial = {}, - user: User, + user: Realm.User, ): Promise<{ config: Configuration; realm: Realm }> { if (!partialConfig.sync) { const config = createLocalConfig(partialConfig as LocalConfiguration); @@ -80,7 +80,7 @@ export async function openRealm( return { config, realm }; } -export function createSyncConfig(partialConfig: SyncedConfiguration = {}, user: User): Configuration { +export function createSyncConfig(partialConfig: SyncedConfiguration = {}, user: Realm.User): Configuration { const { path, nonce } = getRandomPathAndNonce(); return { diff --git a/packages/realm-app-importer/src/AppConfigBuilder.ts b/packages/realm-app-importer/src/AppConfigBuilder.ts index bb45761d64..a8792f2a3b 100644 --- a/packages/realm-app-importer/src/AppConfigBuilder.ts +++ b/packages/realm-app-importer/src/AppConfigBuilder.ts @@ -37,11 +37,24 @@ export type SyncConfig = { export type ServiceConfig = { name: string; type: string; - config: DisabledConfig | PartitionSyncConfig | FlexibleSyncConfig; + config: + | DisabledConfig + | PartitionSyncConfig + | FlexibleSyncConfig + | (PartitionConfig & WithAtlas) + | (FlexibleSyncConfig & WithAtlas) + | WithAtlas; + secret_config: Record; version?: number; }; +export type WithAtlas = { + clusterName: string; + readPreference: string; + wireProtocolEnabled: boolean; +}; + export type ServiceRule = { roles: Array<{ name: string; diff --git a/packages/realm/src/OrderedCollection.ts b/packages/realm/src/OrderedCollection.ts index b998343a5a..a723127202 100644 --- a/packages/realm/src/OrderedCollection.ts +++ b/packages/realm/src/OrderedCollection.ts @@ -260,7 +260,7 @@ export abstract class OrderedCollection = MongoDBCollection; type MongoDBDatabaseType = MongoDBDatabase; type NewDocumentType = NewDocument; type OperationTypeType = OperationType; +type OrderedCollectionType = OrderedCollection; type RenameEventType = RenameEvent; type ReplaceEventType = ReplaceEvent; type UpdateType = Update; @@ -1465,6 +1468,7 @@ export declare namespace Realm { OpenRealmBehaviorConfiguration, OpenRealmBehaviorTypeType as OpenRealmBehaviorType, OpenRealmTimeOutBehaviorType as OpenRealmTimeOutBehavior, + OrderedCollectionType as OrderedCollection, PartitionSyncConfiguration, PrimaryKey, PrimitivePropertyTypeName, diff --git a/packages/realm/src/app-services/BaseSubscriptionSet.ts b/packages/realm/src/app-services/BaseSubscriptionSet.ts index 3f5da5dd2a..c7c1607863 100644 --- a/packages/realm/src/app-services/BaseSubscriptionSet.ts +++ b/packages/realm/src/app-services/BaseSubscriptionSet.ts @@ -217,7 +217,7 @@ export abstract class BaseSubscriptionSet { * e.g. `Realm.objects("Cat").filtered("age > 10")`. * @returns The subscription with the specified query, or `null` if the subscription is not found. */ - findByQuery(query: Results): Subscription | null { + findByQuery(query: Results>): Subscription | null { assert.instanceOf(query, Results, "query"); const subscription = this.internal.findByQuery(query.internal.query); From d61921a9bba5bf326776db42249f73a111a11b86 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Fri, 11 Aug 2023 14:52:12 +0200 Subject: [PATCH 13/15] fix types errors in tests (#6060) Co-authored-by: Andrew Meyer --- integration-tests/tests/src/tests/results.ts | 2 +- .../tests/src/tests/sync/flexible.ts | 32 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/integration-tests/tests/src/tests/results.ts b/integration-tests/tests/src/tests/results.ts index fe027232e9..8f37f66de9 100644 --- a/integration-tests/tests/src/tests/results.ts +++ b/integration-tests/tests/src/tests/results.ts @@ -451,7 +451,7 @@ describe("Results", () => { }); it("implements sorted", () => { - const realm = new Realm({ schema: [IntPrimarySchema] }); + const realm = new Realm({ schema: [IntPrimaryObject] }); let objects = realm.objects(IntPrimaryObject); realm.write(function () { diff --git a/integration-tests/tests/src/tests/sync/flexible.ts b/integration-tests/tests/src/tests/sync/flexible.ts index c6a749710c..9707ee98c0 100644 --- a/integration-tests/tests/src/tests/sync/flexible.ts +++ b/integration-tests/tests/src/tests/sync/flexible.ts @@ -272,7 +272,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { initialSubscriptions: Realm.FlexibleSyncConfiguration["initialSubscriptions"], ): Realm.Configuration { return { - schema: [Person, DogSchema], + schema: [Person, Dog], sync: { // @ts-expect-error Using an internal API _sessionStopPolicy: SessionStopPolicy.Immediately, @@ -471,9 +471,9 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { expect((compensatingWrites[1].primaryKey as BSON.ObjectId).equals(person2Id)).to.be.true; expect((compensatingWrites[2].primaryKey as BSON.ObjectId).equals(dogId)).to.be.true; - expect(compensatingWrites[0].objectName).to.equal(Person); - expect(compensatingWrites[1].objectName).to.equal(Person); - expect(compensatingWrites[2].objectName).to.equal(DogSchema.name); + expect(compensatingWrites[0].objectName).to.equal(Person.name); + expect(compensatingWrites[1].objectName).to.equal(Person.name); + expect(compensatingWrites[2].objectName).to.equal(Dog.name); expect(compensatingWrites[0].reason).to.contain("object is outside of the current query view"); expect(compensatingWrites[1].reason).to.contain("object is outside of the current query view"); @@ -483,7 +483,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { }; const realm = await Realm.open({ - schema: [Person, DogSchema], + schema: [Person, Dog], sync: { flexible: true, user: this.user, @@ -493,7 +493,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { await realm.subscriptions.update((mutableSubs) => { mutableSubs.add(realm.objects(Person).filtered("age < 30")); - mutableSubs.add(realm.objects(DogSchema.name).filtered("age > 5")); + mutableSubs.add(realm.objects(Dog).filtered("age > 5")); }); realm.write(() => { @@ -523,7 +523,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { describe("with realm opened before", function () { openRealmBeforeEach({ - schema: [Person, DogSchema], + schema: [Person, Dog], sync: { flexible: true, //@ts-expect-error Using an internal API @@ -593,7 +593,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("has an objectType", function (this: RealmContext) { const { sub } = addSubscriptionForPerson(this.realm); - expect(sub.objectType).to.equal(Person); + expect(sub.objectType).to.equal(Person.name); }); it("has a default queryString", function (this: RealmContext) { @@ -1154,13 +1154,13 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { const subsCopy = [...subs]; expect(subsCopy[0].queryString).to.equal("age < 10"); - expect(subsCopy[0].objectType).to.equal(Person); + expect(subsCopy[0].objectType).to.equal(Person.name); expect(subsCopy[1].queryString).to.equal("age > 20"); - expect(subsCopy[1].objectType).to.equal(Person); + expect(subsCopy[1].objectType).to.equal(Person.name); expect(subsCopy[2].queryString).to.equal("age > 30"); - expect(subsCopy[2].objectType).to.equal(DogSchema.name); + expect(subsCopy[2].objectType).to.equal(Dog.name); }); it("handles multiple updates in multiple batches", async function (this: RealmContext) { @@ -1173,20 +1173,20 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { await subs.update((mutableSubs) => { mutableSubs.add(this.realm.objects(Person).filtered("age > 20")); - mutableSubs.add(this.realm.objects(DogSchema.name).filtered("age > 30")); + mutableSubs.add(this.realm.objects(Dog).filtered("age > 30")); }); expect(subs).to.have.length(3); const subsCopy = [...subs]; expect(subsCopy[0].queryString).to.equal("age < 10"); - expect(subsCopy[0].objectType).to.equal(Person); + expect(subsCopy[0].objectType).to.equal(Person.name); expect(subsCopy[1].queryString).to.equal("age > 20"); - expect(subsCopy[1].objectType).to.equal(Person); + expect(subsCopy[1].objectType).to.equal(Person.name); expect(subsCopy[2].queryString).to.equal("age > 30"); - expect(subsCopy[2].objectType).to.equal(DogSchema.name); + expect(subsCopy[2].objectType).to.equal(Dog.name); }); // TODO: Enable test when we can find another way of triggering a `SubscriptionSetState.Error`. @@ -2043,7 +2043,7 @@ describe.skipIf(environment.missingServer, "Flexible sync", function () { it("handles manual client resets with flexible sync enabled", async function (this: RealmContext) { await expectClientResetError( { - schema: [Person, DogSchema], + schema: [Person, Dog], sync: { //@ts-expect-error non-public internal configuration. _sessionStopPolicy: SessionStopPolicy.Immediately, From 480ecbe32588e0eb5b7f2b1777264dfc76328d3d Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Fri, 11 Aug 2023 14:58:27 +0200 Subject: [PATCH 14/15] Update changelog and add to lint command for tests --- CHANGELOG.md | 1 + integration-tests/tests/package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edadc40628..83df7984e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * File format: generates Realms with format v23 (reads and upgrades file format v5 or later for non-synced Realm, upgrades file format v10 or later for synced Realms). ### Internal +* Fix types in integration tests and added type checking to the lint command. diff --git a/integration-tests/tests/package.json b/integration-tests/tests/package.json index 727cb28445..8e26a89e49 100644 --- a/integration-tests/tests/package.json +++ b/integration-tests/tests/package.json @@ -12,7 +12,7 @@ "build": "wireit", "start": "wireit", "test": "wireit", - "lint": "eslint --ext .js,.ts .", + "lint": "eslint --ext .js,.ts . && tsc --noEmit", "coverage": "wireit", "ci:coverage": "wireit" }, From c135e92ad22a1ae89d4778ba7c698fa53a638ca2 Mon Sep 17 00:00:00 2001 From: Andrew Meyer Date: Fri, 11 Aug 2023 16:27:59 +0200 Subject: [PATCH 15/15] Fix lint command in integration tests --- integration-tests/tests/package.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/integration-tests/tests/package.json b/integration-tests/tests/package.json index 8e26a89e49..331217422d 100644 --- a/integration-tests/tests/package.json +++ b/integration-tests/tests/package.json @@ -12,11 +12,19 @@ "build": "wireit", "start": "wireit", "test": "wireit", - "lint": "eslint --ext .js,.ts . && tsc --noEmit", + "lint": "wireit", "coverage": "wireit", "ci:coverage": "wireit" }, "wireit": { + "lint": { + "command": "eslint --ext .js,.ts . && tsc --noEmit", + "dependencies": [ + "../../packages/realm-network-transport:bundle", + "../../packages/realm:bundle", + "build-dependencies" + ] + }, "build": { "command": "tsc", "dependencies": [