diff --git a/examples/data-objects/inventory-app/package.json b/examples/data-objects/inventory-app/package.json index 0daa98f7e3d1..6dd12e8d06ad 100644 --- a/examples/data-objects/inventory-app/package.json +++ b/examples/data-objects/inventory-app/package.json @@ -16,6 +16,7 @@ "build": "fluid-build . --task build", "build:compile": "fluid-build . --task compile", "build:esnext": "tsc --project ./tsconfig.json", + "build:genver": "gen-version", "check:biome": "biome check .", "check:format": "npm run check:biome", "clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" nyc", diff --git a/examples/data-objects/inventory-app/src/packageVersion.ts b/examples/data-objects/inventory-app/src/packageVersion.ts new file mode 100644 index 000000000000..4ec546bdf395 --- /dev/null +++ b/examples/data-objects/inventory-app/src/packageVersion.ts @@ -0,0 +1,9 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + * + * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY + */ + +export const pkgName = "@fluid-example/inventory-app"; +export const pkgVersion = "2.73.0"; diff --git a/examples/data-objects/inventory-app/tests/schemaCompatibility.test.ts b/examples/data-objects/inventory-app/tests/schemaCompatibility.test.ts new file mode 100644 index 000000000000..0af50b9f3a41 --- /dev/null +++ b/examples/data-objects/inventory-app/tests/schemaCompatibility.test.ts @@ -0,0 +1,66 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import type { TreeViewConfiguration } from "fluid-framework"; +import { + checkCompatibility, + exportCompatibilitySchemaSnapshot, + importCompatibilitySchemaSnapshot, + type JsonCompatibleReadOnly, +} from "@fluidframework/tree/alpha"; +import path from "node:path"; +import fs from "node:fs"; +import { treeConfiguration } from "../src/schema.js"; +import { pkgVersion } from "../src/packageVersion.js"; + +// Store compatibility snapshots with source code. Unlike the snapshots that snapshotTools.ts manages, these snapshots should not be +// be regenerated automatically, as they are used to verify compatibility over time. +const snapshotDirectory = path.join(__dirname, "./snapshots"); + +function writeSchemaSnapshot(filename: string, viewSchema: TreeViewConfiguration): void { + const snapshot = exportCompatibilitySchemaSnapshot(viewSchema); + const fullPath = path.join(snapshotDirectory, filename); + fs.mkdirSync(snapshotDirectory); + fs.writeFileSync(fullPath, JSON.stringify(snapshot), "utf8"); +} + +function readSchemaSnapshot(filename: string): TreeViewConfiguration { + const fullPath = path.join(snapshotDirectory, filename); + const snapshot = JSON.parse(fs.readFileSync(fullPath, "utf8")) as JsonCompatibleReadOnly; + return importCompatibilitySchemaSnapshot(snapshot); +} + +function readAllSchemaSnapshots(): TreeViewConfiguration[] { + const files = fs.readdirSync(snapshotDirectory); + const snapshots: TreeViewConfiguration[] = []; + for (const file of files) { + if (file.endsWith(".json")) { + snapshots.push(readSchemaSnapshot(file)); + } + } + return snapshots; +} + +describe("inventory app schema compatibility", () => { + it.only("write current view schema snapshot", () => { + writeSchemaSnapshot(`inventoryAppViewSchema_${pkgVersion}.json`, treeConfiguration); + }); + + it("current view schema can read content written by historical persisted schemas", () => { + const currentViewSchema = treeConfiguration; + const previousViewSchemas = readAllSchemaSnapshots(); + for (const previousViewSchema of previousViewSchemas) { + checkCompatibility(previousViewSchema, currentViewSchema); + } + }); + + it("current persisted schema can read content written by historical view schemas", () => { + const currentPersistedSchema = treeConfiguration; + const previousViewSchemas = readAllSchemaSnapshots(); + for (const previousViewSchema of previousViewSchemas) { + checkCompatibility(currentPersistedSchema, previousViewSchema); + } + }); +}); diff --git a/examples/data-objects/inventory-app/tsconfig.json b/examples/data-objects/inventory-app/tsconfig.json index 2800c2a58044..33be248c15aa 100644 --- a/examples/data-objects/inventory-app/tsconfig.json +++ b/examples/data-objects/inventory-app/tsconfig.json @@ -13,5 +13,5 @@ ], "exactOptionalPropertyTypes": false, }, - "include": ["src/**/*"], + "include": ["src/**/*", "tests/**/*"], }