@fluid-experimental/attributor 2.0.0-rc.2.0.2 → 2.0.0-rc.3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/api-report/attributor.api.md +3 -3
- package/dist/attributor.d.ts +6 -2
- package/dist/attributor.d.ts.map +1 -1
- package/dist/attributor.js +6 -6
- package/dist/attributor.js.map +1 -1
- package/dist/encoders.d.ts +5 -1
- package/dist/encoders.d.ts.map +1 -1
- package/dist/encoders.js +5 -5
- package/dist/encoders.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lz4Encoder.d.ts +5 -1
- package/dist/lz4Encoder.d.ts.map +1 -1
- package/dist/lz4Encoder.js +3 -3
- package/dist/lz4Encoder.js.map +1 -1
- package/dist/mixinAttributor.d.ts +6 -2
- package/dist/mixinAttributor.d.ts.map +1 -1
- package/dist/mixinAttributor.js +21 -17
- package/dist/mixinAttributor.js.map +1 -1
- package/dist/stringInterner.js +2 -2
- package/dist/stringInterner.js.map +1 -1
- package/lib/attributor.d.ts +6 -2
- package/lib/attributor.d.ts.map +1 -1
- package/lib/attributor.js +2 -2
- package/lib/attributor.js.map +1 -1
- package/lib/encoders.d.ts +5 -1
- package/lib/encoders.d.ts.map +1 -1
- package/lib/encoders.js +1 -1
- package/lib/encoders.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/lz4Encoder.d.ts +5 -1
- package/lib/lz4Encoder.d.ts.map +1 -1
- package/lib/lz4Encoder.js +1 -1
- package/lib/lz4Encoder.js.map +1 -1
- package/lib/mixinAttributor.d.ts +6 -2
- package/lib/mixinAttributor.d.ts.map +1 -1
- package/lib/mixinAttributor.js +8 -4
- package/lib/mixinAttributor.js.map +1 -1
- package/lib/stringInterner.js +1 -1
- package/lib/stringInterner.js.map +1 -1
- package/package.json +31 -65
- package/src/attributor.ts +5 -4
- package/src/encoders.ts +4 -2
- package/src/index.ts +1 -0
- package/src/lz4Encoder.ts +4 -2
- package/src/mixinAttributor.ts +22 -18
- package/src/stringInterner.ts +1 -1
- package/api-extractor-cjs.json +0 -8
- package/dist/attributor-alpha.d.ts +0 -27
- package/dist/attributor-beta.d.ts +0 -31
- package/dist/attributor-public.d.ts +0 -31
- package/dist/attributor-untrimmed.d.ts +0 -127
- package/lib/attributor-alpha.d.ts +0 -27
- package/lib/attributor-beta.d.ts +0 -31
- package/lib/attributor-public.d.ts +0 -31
- package/lib/attributor-untrimmed.d.ts +0 -127
- package/lib/test/attribution/dirname.cjs +0 -16
- package/lib/test/attribution/dirname.cjs.map +0 -1
- package/lib/test/attribution/sharedString.attribution.spec.js +0 -398
- package/lib/test/attribution/sharedString.attribution.spec.js.map +0 -1
- package/lib/test/attributor.spec.js +0 -32
- package/lib/test/attributor.spec.js.map +0 -1
- package/lib/test/attributorSerializer.spec.js +0 -123
- package/lib/test/attributorSerializer.spec.js.map +0 -1
- package/lib/test/deltaEncoder.spec.js +0 -36
- package/lib/test/deltaEncoder.spec.js.map +0 -1
- package/lib/test/lz4Encoder.spec.js +0 -27
- package/lib/test/lz4Encoder.spec.js.map +0 -1
- package/lib/test/mixinAttributor.spec.js +0 -219
- package/lib/test/mixinAttributor.spec.js.map +0 -1
- package/lib/test/opStreamAttributor.spec.js +0 -43
- package/lib/test/opStreamAttributor.spec.js.map +0 -1
- package/lib/test/stringInterner.spec.js +0 -71
- package/lib/test/stringInterner.spec.js.map +0 -1
- package/lib/test/utils.js +0 -32
- package/lib/test/utils.js.map +0 -1
- /package/{dist → lib}/tsdoc-metadata.json +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attributorSerializer.spec.js","sourceRoot":"","sources":["../../src/test/attributorSerializer.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { strict as assert } from \"node:assert\";\nimport { type AttributionInfo } from \"@fluidframework/runtime-definitions\";\n\nimport { Attributor, type IAttributor } from \"../attributor.js\";\nimport {\n\tAttributorSerializer,\n\tchain,\n\ttype Encoder,\n\ttype SerializedAttributor,\n} from \"../encoders.js\";\nimport { type InternedStringId } from \"../stringInterner.js\";\n\nfunction makeNoopEncoder<T>(): Encoder<T, T> {\n\treturn {\n\t\tencode: (x) => x,\n\t\tdecode: (x) => x,\n\t};\n}\n\ndescribe(\"AttributorSerializer\", () => {\n\tit(\"uses its timestamp encoder\", () => {\n\t\tit(\"on encode\", () => {\n\t\t\tconst attributor = new Attributor([\n\t\t\t\t[1, { user: { id: \"a\" }, timestamp: 500 }],\n\t\t\t\t[2, { user: { id: \"a\" }, timestamp: 6001 }],\n\t\t\t]);\n\t\t\tconst calls: unknown[] = [];\n\t\t\tconst serializer = new AttributorSerializer((entries) => new Attributor(entries), {\n\t\t\t\tencode: (x): number[] => {\n\t\t\t\t\tcalls.push(x);\n\t\t\t\t\treturn x;\n\t\t\t\t},\n\t\t\t\tdecode: (x): number[] => x,\n\t\t\t});\n\t\t\tassert.equal(calls.length, 0);\n\t\t\tserializer.encode(attributor);\n\t\t\tassert.equal(calls.length, 1);\n\t\t\tassert.deepEqual(calls[0], [500, 6001]);\n\t\t});\n\n\t\tit(\"on decode\", () => {\n\t\t\tconst calls: unknown[] = [];\n\t\t\tconst serializer = new AttributorSerializer((entries) => new Attributor(entries), {\n\t\t\t\tencode: (x): number[] => x,\n\t\t\t\tdecode: (x): number[] => {\n\t\t\t\t\tcalls.push(x);\n\t\t\t\t\treturn x;\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst encoded: SerializedAttributor = {\n\t\t\t\tinterner: [\"a\"],\n\t\t\t\tseqs: [1, 2],\n\t\t\t\ttimestamps: [501, 604],\n\t\t\t\tattributionRefs: [0 as InternedStringId, 0 as InternedStringId],\n\t\t\t};\n\n\t\t\tassert.equal(calls.length, 0);\n\t\t\tserializer.decode(encoded);\n\t\t\tassert.equal(calls.length, 1);\n\t\t\tassert.deepEqual(calls[0], [501, 604]);\n\t\t});\n\t});\n\n\tdescribe(\"correctly round-trips\", () => {\n\t\tconst testCases: { name: string; entries: Iterable<[number, AttributionInfo]> }[] = [\n\t\t\t{\n\t\t\t\tname: \"empty attribution information\",\n\t\t\t\tentries: [],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"one attribution\",\n\t\t\t\tentries: [[5, { user: { id: \"only user\" }, timestamp: 6000 }]],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"multiple keys associated with the same user\",\n\t\t\t\tentries: [\n\t\t\t\t\t[1, { user: { id: \"user foo\" }, timestamp: 500 }],\n\t\t\t\t\t[2, { user: { id: \"user foo\" }, timestamp: 7000 }],\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"multiple keys associated with different users\",\n\t\t\t\tentries: [\n\t\t\t\t\t[1, { user: { id: \"user foo\" }, timestamp: 500 }],\n\t\t\t\t\t[2, { user: { id: \"user bar\" }, timestamp: 7000 }],\n\t\t\t\t],\n\t\t\t},\n\t\t];\n\n\t\tfor (const { name, entries } of testCases) {\n\t\t\tit(name, () => {\n\t\t\t\tconst calls: unknown[] = [];\n\t\t\t\tlet retVal: IAttributor | undefined;\n\t\t\t\tconst serializer = new AttributorSerializer((providedEntries) => {\n\t\t\t\t\tcalls.push(providedEntries);\n\t\t\t\t\tretVal = new Attributor(providedEntries);\n\t\t\t\t\treturn retVal;\n\t\t\t\t}, makeNoopEncoder());\n\t\t\t\tconst attributor = new Attributor(entries);\n\t\t\t\tconst roundTrippedAttributor = serializer.decode(serializer.encode(attributor));\n\t\t\t\tassert.equal(calls.length, 1);\n\t\t\t\tassert.deepEqual(calls[0], entries);\n\t\t\t\tassert.equal(retVal, roundTrippedAttributor);\n\t\t\t});\n\t\t}\n\t});\n});\n\ndescribe(\"chain\", () => {\n\tit(\"correctly chains encoders\", () => {\n\t\tconst encodeCalls: string[] = [];\n\t\tconst decodeCalls: string[] = [];\n\t\tconst makeLoggingChain = <T>(tag: string): Encoder<T, T> => ({\n\t\t\tencode: (s: T): T => {\n\t\t\t\tencodeCalls.push(tag);\n\t\t\t\treturn s;\n\t\t\t},\n\t\t\tdecode: (s: T): T => {\n\t\t\t\tdecodeCalls.push(tag);\n\t\t\t\treturn s;\n\t\t\t},\n\t\t});\n\t\tconst encoder = chain(makeLoggingChain(\"A\"), makeLoggingChain(\"B\"));\n\t\tassert.deepEqual(encodeCalls, []);\n\t\tassert.deepEqual(decodeCalls, []);\n\t\tassert.equal(encoder.encode(\"foo\"), \"foo\");\n\t\tassert.deepEqual(encodeCalls, [\"A\", \"B\"]);\n\t\tassert.deepEqual(decodeCalls, []);\n\t\tassert.equal(encoder.decode(\"bar\"), \"bar\");\n\t\tassert.deepEqual(encodeCalls, [\"A\", \"B\"]);\n\t\tassert.deepEqual(decodeCalls, [\"B\", \"A\"]);\n\t});\n});\n"]}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { strict as assert } from "node:assert";
|
|
6
|
-
import { deltaEncoder } from "../encoders.js";
|
|
7
|
-
describe("deltaEncoder", () => {
|
|
8
|
-
const cases = [
|
|
9
|
-
{ name: "empty lists", data: [], expected: [] },
|
|
10
|
-
{ name: "lists of size 1", data: [5], expected: [5] },
|
|
11
|
-
{ name: "increasing numbers", data: [7, 19], expected: [7, 12] },
|
|
12
|
-
{ name: "decreasing number", data: [19, 17], expected: [19, -2] },
|
|
13
|
-
{
|
|
14
|
-
name: "longer lists",
|
|
15
|
-
data: Array.from({ length: 10 }, (_, i) => 5 * i),
|
|
16
|
-
expected: [0, ...Array.from({ length: 9 }, () => 5)],
|
|
17
|
-
},
|
|
18
|
-
];
|
|
19
|
-
describe("correctly encodes", () => {
|
|
20
|
-
for (const { name, data, expected } of cases) {
|
|
21
|
-
it(name, () => {
|
|
22
|
-
const actual = deltaEncoder.encode(data);
|
|
23
|
-
assert.deepEqual(actual, expected);
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
describe("correctly round-trips", () => {
|
|
28
|
-
for (const { name, data } of cases) {
|
|
29
|
-
it(name, () => {
|
|
30
|
-
const actual = deltaEncoder.decode(deltaEncoder.encode(data));
|
|
31
|
-
assert.deepEqual(actual, data);
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
//# sourceMappingURL=deltaEncoder.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deltaEncoder.spec.js","sourceRoot":"","sources":["../../src/test/deltaEncoder.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC7B,MAAM,KAAK,GAA2D;QACrE,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC/C,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;QACrD,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;QAChE,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE;QACjE;YACC,IAAI,EAAE,cAAc;YACpB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;YACjD,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;SACpD;KACD,CAAC;IAEF,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAClC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,KAAK,EAAE;YAC7C,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE;gBACb,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;SACH;IACF,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACtC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE;YACnC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE;gBACb,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC9D,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;SACH;IACF,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { strict as assert } from \"node:assert\";\nimport { deltaEncoder } from \"../encoders.js\";\n\ndescribe(\"deltaEncoder\", () => {\n\tconst cases: { name: string; data: number[]; expected: number[] }[] = [\n\t\t{ name: \"empty lists\", data: [], expected: [] },\n\t\t{ name: \"lists of size 1\", data: [5], expected: [5] },\n\t\t{ name: \"increasing numbers\", data: [7, 19], expected: [7, 12] },\n\t\t{ name: \"decreasing number\", data: [19, 17], expected: [19, -2] },\n\t\t{\n\t\t\tname: \"longer lists\",\n\t\t\tdata: Array.from({ length: 10 }, (_, i) => 5 * i),\n\t\t\texpected: [0, ...Array.from({ length: 9 }, () => 5)],\n\t\t},\n\t];\n\n\tdescribe(\"correctly encodes\", () => {\n\t\tfor (const { name, data, expected } of cases) {\n\t\t\tit(name, () => {\n\t\t\t\tconst actual = deltaEncoder.encode(data);\n\t\t\t\tassert.deepEqual(actual, expected);\n\t\t\t});\n\t\t}\n\t});\n\n\tdescribe(\"correctly round-trips\", () => {\n\t\tfor (const { name, data } of cases) {\n\t\t\tit(name, () => {\n\t\t\t\tconst actual = deltaEncoder.decode(deltaEncoder.encode(data));\n\t\t\t\tassert.deepEqual(actual, data);\n\t\t\t});\n\t\t}\n\t});\n});\n"]}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { strict as assert } from "node:assert";
|
|
6
|
-
import { makeLZ4Encoder } from "../lz4Encoder.js";
|
|
7
|
-
describe("lz4Encoder", () => {
|
|
8
|
-
const cases = [
|
|
9
|
-
{ name: "empty string", data: "" },
|
|
10
|
-
{ name: "numbers", data: 0 },
|
|
11
|
-
{ name: "objects", data: {} },
|
|
12
|
-
{ name: "empty lists", data: [] },
|
|
13
|
-
// eslint-disable-next-line unicorn/no-null
|
|
14
|
-
{ name: "null properties", data: { foo: null } },
|
|
15
|
-
{ name: "more complex objects", data: { foo: { bar: [1, 2] }, baz: 3, bat: "hello" } },
|
|
16
|
-
];
|
|
17
|
-
describe("correctly round-trips", () => {
|
|
18
|
-
for (const { name, data } of cases) {
|
|
19
|
-
it(name, () => {
|
|
20
|
-
const encoder = makeLZ4Encoder();
|
|
21
|
-
const actual = encoder.decode(encoder.encode(data));
|
|
22
|
-
assert.deepEqual(actual, data);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
//# sourceMappingURL=lz4Encoder.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lz4Encoder.spec.js","sourceRoot":"","sources":["../../src/test/lz4Encoder.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC3B,MAAM,KAAK,GAAsC;QAChD,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,EAAE;QAClC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE;QAC5B,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;QAC7B,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,2CAA2C;QAC3C,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAChD,EAAE,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;KACtF,CAAC;IAEF,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACtC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE;YACnC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE;gBACb,MAAM,OAAO,GAAG,cAAc,EAAW,CAAC;gBAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAA+B,CAAC,CAAC,CAAC;gBAC/E,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAChC,CAAC,CAAC,CAAC;SACH;IACF,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { strict as assert } from \"node:assert\";\nimport { type JsonableTypeWith } from \"@fluidframework/datastore-definitions\";\n\nimport { makeLZ4Encoder } from \"../lz4Encoder.js\";\n\ndescribe(\"lz4Encoder\", () => {\n\tconst cases: { name: string; data: unknown }[] = [\n\t\t{ name: \"empty string\", data: \"\" },\n\t\t{ name: \"numbers\", data: 0 },\n\t\t{ name: \"objects\", data: {} },\n\t\t{ name: \"empty lists\", data: [] },\n\t\t// eslint-disable-next-line unicorn/no-null\n\t\t{ name: \"null properties\", data: { foo: null } },\n\t\t{ name: \"more complex objects\", data: { foo: { bar: [1, 2] }, baz: 3, bat: \"hello\" } },\n\t];\n\n\tdescribe(\"correctly round-trips\", () => {\n\t\tfor (const { name, data } of cases) {\n\t\t\tit(name, () => {\n\t\t\t\tconst encoder = makeLZ4Encoder<unknown>();\n\t\t\t\tconst actual = encoder.decode(encoder.encode(data as JsonableTypeWith<never>));\n\t\t\t\tassert.deepEqual(actual, data);\n\t\t\t});\n\t\t}\n\t});\n});\n"]}
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
6
|
-
import { strict as assert } from "node:assert";
|
|
7
|
-
import { AttachState, } from "@fluidframework/container-definitions";
|
|
8
|
-
import { MockLogger, sessionStorageConfigProvider } from "@fluidframework/telemetry-utils";
|
|
9
|
-
import { MockDeltaManager, MockQuorumClients } from "@fluidframework/test-runtime-utils";
|
|
10
|
-
import { SummaryType, } from "@fluidframework/protocol-definitions";
|
|
11
|
-
import { createRuntimeAttributor, enableOnNewFileKey, mixinAttributor, } from "../mixinAttributor.js";
|
|
12
|
-
import { Attributor } from "../attributor.js";
|
|
13
|
-
import { makeLZ4Encoder } from "../lz4Encoder.js";
|
|
14
|
-
import { AttributorSerializer, chain, deltaEncoder } from "../encoders.js";
|
|
15
|
-
import { makeMockAudience } from "./utils.js";
|
|
16
|
-
describe("mixinAttributor", () => {
|
|
17
|
-
const clientId = "mock client id";
|
|
18
|
-
const getMockContext = () => {
|
|
19
|
-
return {
|
|
20
|
-
audience: makeMockAudience([clientId]),
|
|
21
|
-
attachState: AttachState.Attached,
|
|
22
|
-
deltaManager: new MockDeltaManager(),
|
|
23
|
-
quorum: new MockQuorumClients(),
|
|
24
|
-
taggedLogger: new MockLogger(),
|
|
25
|
-
clientDetails: { capabilities: { interactive: true } },
|
|
26
|
-
closeFn: (error) => {
|
|
27
|
-
if (error) {
|
|
28
|
-
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
29
|
-
throw error;
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
options: {},
|
|
33
|
-
updateDirtyContainerState: (_dirty) => { },
|
|
34
|
-
getLoadedFromVersion: () => undefined,
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
const getScope = () => ({
|
|
38
|
-
IRuntimeAttributor: createRuntimeAttributor(),
|
|
39
|
-
});
|
|
40
|
-
const oldRawConfig = sessionStorageConfigProvider.value.getRawConfig;
|
|
41
|
-
let injectedSettings = {};
|
|
42
|
-
before(() => {
|
|
43
|
-
sessionStorageConfigProvider.value.getRawConfig = (name) => injectedSettings[name];
|
|
44
|
-
});
|
|
45
|
-
afterEach(() => {
|
|
46
|
-
injectedSettings = {};
|
|
47
|
-
});
|
|
48
|
-
after(() => {
|
|
49
|
-
sessionStorageConfigProvider.value.getRawConfig = oldRawConfig;
|
|
50
|
-
});
|
|
51
|
-
const setEnableOnNew = (val) => {
|
|
52
|
-
injectedSettings[enableOnNewFileKey] = val;
|
|
53
|
-
};
|
|
54
|
-
const AttributingContainerRuntime = mixinAttributor();
|
|
55
|
-
it("Attributes ops", async () => {
|
|
56
|
-
setEnableOnNew(true);
|
|
57
|
-
const context = getMockContext();
|
|
58
|
-
const containerRuntime = await AttributingContainerRuntime.loadRuntime({
|
|
59
|
-
context,
|
|
60
|
-
registryEntries: [],
|
|
61
|
-
containerScope: getScope(),
|
|
62
|
-
provideEntryPoint: async () => ({}),
|
|
63
|
-
existing: false,
|
|
64
|
-
});
|
|
65
|
-
const maybeProvidesAttributor = containerRuntime.scope;
|
|
66
|
-
assert(maybeProvidesAttributor.IRuntimeAttributor !== undefined);
|
|
67
|
-
const runtimeAttribution = maybeProvidesAttributor.IRuntimeAttributor;
|
|
68
|
-
const op = {
|
|
69
|
-
type: "op",
|
|
70
|
-
sequenceNumber: 7,
|
|
71
|
-
clientId,
|
|
72
|
-
timestamp: 1006,
|
|
73
|
-
};
|
|
74
|
-
context.deltaManager.emit("op", op);
|
|
75
|
-
assert.deepEqual(runtimeAttribution.get({ type: "op", seq: op.sequenceNumber }), {
|
|
76
|
-
timestamp: op.timestamp,
|
|
77
|
-
user: context.audience?.getMember(op.clientId)?.user,
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
it("includes attribution association data in the summary tree", async () => {
|
|
81
|
-
setEnableOnNew(true);
|
|
82
|
-
const context = getMockContext();
|
|
83
|
-
const containerRuntime = await AttributingContainerRuntime.loadRuntime({
|
|
84
|
-
context,
|
|
85
|
-
registryEntries: [],
|
|
86
|
-
containerScope: getScope(),
|
|
87
|
-
provideEntryPoint: async () => ({}),
|
|
88
|
-
existing: false,
|
|
89
|
-
});
|
|
90
|
-
const op = {
|
|
91
|
-
type: "op",
|
|
92
|
-
sequenceNumber: 7,
|
|
93
|
-
clientId,
|
|
94
|
-
timestamp: 1006,
|
|
95
|
-
};
|
|
96
|
-
context.deltaManager.emit("op", op);
|
|
97
|
-
const { summary } = await containerRuntime.summarize({
|
|
98
|
-
fullTree: true,
|
|
99
|
-
trackState: false,
|
|
100
|
-
runGC: false,
|
|
101
|
-
});
|
|
102
|
-
const { ".attributor": attributor } = summary.tree;
|
|
103
|
-
assert(attributor !== undefined && attributor.type === SummaryType.Tree, "summary should contain attributor data");
|
|
104
|
-
const opAttributorBlob = attributor.tree.op;
|
|
105
|
-
assert(opAttributorBlob.type === SummaryType.Blob &&
|
|
106
|
-
typeof opAttributorBlob.content === "string");
|
|
107
|
-
const decoder = chain(new AttributorSerializer((entries) => new Attributor(entries), deltaEncoder), makeLZ4Encoder());
|
|
108
|
-
const decoded = decoder.decode(opAttributorBlob.content);
|
|
109
|
-
assert.deepEqual(decoded.getAttributionInfo(op.sequenceNumber), {
|
|
110
|
-
timestamp: op.timestamp,
|
|
111
|
-
user: context.audience?.getMember(op.clientId)?.user,
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
it("repopulates attribution association data using the summary tree", async () => {
|
|
115
|
-
const op = {
|
|
116
|
-
sequenceNumber: 7,
|
|
117
|
-
clientId,
|
|
118
|
-
timestamp: 1006,
|
|
119
|
-
};
|
|
120
|
-
const encoder = chain(new AttributorSerializer((entries) => new Attributor(entries), deltaEncoder), makeLZ4Encoder());
|
|
121
|
-
const context = getMockContext();
|
|
122
|
-
const sampleAttributor = new Attributor([
|
|
123
|
-
[
|
|
124
|
-
op.sequenceNumber,
|
|
125
|
-
{ timestamp: op.timestamp, user: context.audience.getMember(op.clientId).user },
|
|
126
|
-
],
|
|
127
|
-
]);
|
|
128
|
-
const opAttributorBlobId = "mock attributor blob id";
|
|
129
|
-
const mockStorage = {
|
|
130
|
-
readBlob: async (blobId) => {
|
|
131
|
-
assert(blobId === opAttributorBlobId);
|
|
132
|
-
return encoder.encode(sampleAttributor);
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
const snapshot = {
|
|
136
|
-
blobs: {},
|
|
137
|
-
trees: {
|
|
138
|
-
".attributor": {
|
|
139
|
-
blobs: { op: opAttributorBlobId },
|
|
140
|
-
trees: {},
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
};
|
|
144
|
-
context.baseSnapshot = snapshot;
|
|
145
|
-
context.storage = mockStorage;
|
|
146
|
-
const containerRuntime = await AttributingContainerRuntime.loadRuntime({
|
|
147
|
-
context,
|
|
148
|
-
registryEntries: [],
|
|
149
|
-
containerScope: getScope(),
|
|
150
|
-
provideEntryPoint: async () => ({}),
|
|
151
|
-
existing: false,
|
|
152
|
-
});
|
|
153
|
-
const maybeProvidesAttributor = containerRuntime.scope;
|
|
154
|
-
assert(maybeProvidesAttributor.IRuntimeAttributor !== undefined);
|
|
155
|
-
const runtimeAttribution = maybeProvidesAttributor.IRuntimeAttributor;
|
|
156
|
-
assert.deepEqual(runtimeAttribution.get({ type: "op", seq: op.sequenceNumber }), {
|
|
157
|
-
timestamp: op.timestamp,
|
|
158
|
-
user: context.audience?.getMember(op.clientId)?.user,
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
describe("Doesn't summarize attributor", () => {
|
|
162
|
-
const testCases = [
|
|
163
|
-
{
|
|
164
|
-
testName: "for existing documents that had no attributor",
|
|
165
|
-
getContext: () => {
|
|
166
|
-
setEnableOnNew(true);
|
|
167
|
-
const context = getMockContext();
|
|
168
|
-
const snapshot = {
|
|
169
|
-
blobs: {},
|
|
170
|
-
trees: {},
|
|
171
|
-
};
|
|
172
|
-
context.baseSnapshot = snapshot;
|
|
173
|
-
return context;
|
|
174
|
-
},
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
testName: `for new documents with ${enableOnNewFileKey} unset`,
|
|
178
|
-
getContext: () => {
|
|
179
|
-
return getMockContext();
|
|
180
|
-
},
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
testName: `for new documents with ${enableOnNewFileKey} set to false`,
|
|
184
|
-
getContext: () => {
|
|
185
|
-
setEnableOnNew(false);
|
|
186
|
-
const context = getMockContext();
|
|
187
|
-
const snapshot = {
|
|
188
|
-
blobs: {},
|
|
189
|
-
trees: {},
|
|
190
|
-
};
|
|
191
|
-
context.baseSnapshot = snapshot;
|
|
192
|
-
return context;
|
|
193
|
-
},
|
|
194
|
-
},
|
|
195
|
-
];
|
|
196
|
-
for (const { getContext, testName } of testCases) {
|
|
197
|
-
it(testName, async () => {
|
|
198
|
-
const context = getContext();
|
|
199
|
-
const containerRuntime = await AttributingContainerRuntime.loadRuntime({
|
|
200
|
-
context,
|
|
201
|
-
registryEntries: [],
|
|
202
|
-
containerScope: getScope(),
|
|
203
|
-
provideEntryPoint: async () => ({}),
|
|
204
|
-
existing: false,
|
|
205
|
-
});
|
|
206
|
-
const maybeProvidesAttributor = containerRuntime.scope;
|
|
207
|
-
assert(maybeProvidesAttributor.IRuntimeAttributor !== undefined);
|
|
208
|
-
const { summary } = await containerRuntime.summarize({
|
|
209
|
-
fullTree: true,
|
|
210
|
-
trackState: false,
|
|
211
|
-
runGC: false,
|
|
212
|
-
});
|
|
213
|
-
assert(summary.tree[".attributor"] === undefined);
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
/* eslint-enable @typescript-eslint/no-non-null-assertion */
|
|
219
|
-
//# sourceMappingURL=mixinAttributor.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mixinAttributor.spec.js","sourceRoot":"","sources":["../../src/test/mixinAttributor.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport { strict as assert } from \"node:assert\";\nimport {\n\tAttachState,\n\ttype IContainerContext,\n\ttype ICriticalContainerError,\n} from \"@fluidframework/container-definitions\";\nimport { MockLogger, sessionStorageConfigProvider } from \"@fluidframework/telemetry-utils\";\nimport { type IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { MockDeltaManager, MockQuorumClients } from \"@fluidframework/test-runtime-utils\";\nimport { type ConfigTypes, type FluidObject } from \"@fluidframework/core-interfaces\";\nimport {\n\ttype ISequencedDocumentMessage,\n\ttype ISnapshotTree,\n\tSummaryType,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n\tcreateRuntimeAttributor,\n\tenableOnNewFileKey,\n\ttype IProvideRuntimeAttributor,\n\tmixinAttributor,\n} from \"../mixinAttributor.js\";\nimport { Attributor } from \"../attributor.js\";\nimport { makeLZ4Encoder } from \"../lz4Encoder.js\";\nimport { AttributorSerializer, chain, deltaEncoder } from \"../encoders.js\";\nimport { makeMockAudience } from \"./utils.js\";\n\ntype Mutable<T> = {\n\t-readonly [P in keyof T]: T[P];\n};\n\ndescribe(\"mixinAttributor\", () => {\n\tconst clientId = \"mock client id\";\n\tconst getMockContext = (): Partial<IContainerContext> => {\n\t\treturn {\n\t\t\taudience: makeMockAudience([clientId]),\n\t\t\tattachState: AttachState.Attached,\n\t\t\tdeltaManager: new MockDeltaManager(),\n\t\t\tquorum: new MockQuorumClients(),\n\t\t\ttaggedLogger: new MockLogger(),\n\t\t\tclientDetails: { capabilities: { interactive: true } },\n\t\t\tcloseFn: (error?: ICriticalContainerError): void => {\n\t\t\t\tif (error) {\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-throw-literal\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t},\n\t\t\toptions: {},\n\t\t\tupdateDirtyContainerState: (_dirty: boolean): void => {},\n\t\t\tgetLoadedFromVersion: () => undefined,\n\t\t};\n\t};\n\n\tconst getScope = (): FluidObject<IProvideRuntimeAttributor> => ({\n\t\tIRuntimeAttributor: createRuntimeAttributor(),\n\t});\n\n\tconst oldRawConfig = sessionStorageConfigProvider.value.getRawConfig;\n\tlet injectedSettings: Record<string, ConfigTypes> = {};\n\n\tbefore(() => {\n\t\tsessionStorageConfigProvider.value.getRawConfig = (name): ConfigTypes =>\n\t\t\tinjectedSettings[name];\n\t});\n\n\tafterEach(() => {\n\t\tinjectedSettings = {};\n\t});\n\n\tafter(() => {\n\t\tsessionStorageConfigProvider.value.getRawConfig = oldRawConfig;\n\t});\n\n\tconst setEnableOnNew = (val: boolean): void => {\n\t\tinjectedSettings[enableOnNewFileKey] = val;\n\t};\n\n\tconst AttributingContainerRuntime = mixinAttributor();\n\n\tit(\"Attributes ops\", async () => {\n\t\tsetEnableOnNew(true);\n\t\tconst context = getMockContext() as IContainerContext;\n\t\tconst containerRuntime = await AttributingContainerRuntime.loadRuntime({\n\t\t\tcontext,\n\t\t\tregistryEntries: [],\n\t\t\tcontainerScope: getScope(),\n\t\t\tprovideEntryPoint: async () => ({}),\n\t\t\texisting: false,\n\t\t});\n\n\t\tconst maybeProvidesAttributor: FluidObject<IProvideRuntimeAttributor> =\n\t\t\tcontainerRuntime.scope;\n\t\tassert(maybeProvidesAttributor.IRuntimeAttributor !== undefined);\n\t\tconst runtimeAttribution = maybeProvidesAttributor.IRuntimeAttributor;\n\n\t\tconst op: Partial<ISequencedDocumentMessage> = {\n\t\t\ttype: \"op\",\n\t\t\tsequenceNumber: 7,\n\t\t\tclientId,\n\t\t\ttimestamp: 1006,\n\t\t};\n\n\t\t(context.deltaManager as MockDeltaManager).emit(\"op\", op);\n\n\t\tassert.deepEqual(runtimeAttribution.get({ type: \"op\", seq: op.sequenceNumber! }), {\n\t\t\ttimestamp: op.timestamp,\n\t\t\tuser: context.audience?.getMember(op.clientId!)?.user,\n\t\t});\n\t});\n\n\tit(\"includes attribution association data in the summary tree\", async () => {\n\t\tsetEnableOnNew(true);\n\t\tconst context = getMockContext() as IContainerContext;\n\t\tconst containerRuntime = await AttributingContainerRuntime.loadRuntime({\n\t\t\tcontext,\n\t\t\tregistryEntries: [],\n\t\t\tcontainerScope: getScope(),\n\t\t\tprovideEntryPoint: async () => ({}),\n\t\t\texisting: false,\n\t\t});\n\n\t\tconst op: Partial<ISequencedDocumentMessage> = {\n\t\t\ttype: \"op\",\n\t\t\tsequenceNumber: 7,\n\t\t\tclientId,\n\t\t\ttimestamp: 1006,\n\t\t};\n\n\t\t(context.deltaManager as MockDeltaManager).emit(\"op\", op);\n\t\tconst { summary } = await containerRuntime.summarize({\n\t\t\tfullTree: true,\n\t\t\ttrackState: false,\n\t\t\trunGC: false,\n\t\t});\n\n\t\tconst { \".attributor\": attributor } = summary.tree;\n\t\tassert(\n\t\t\tattributor !== undefined && attributor.type === SummaryType.Tree,\n\t\t\t\"summary should contain attributor data\",\n\t\t);\n\t\tconst opAttributorBlob = attributor.tree.op;\n\t\tassert(\n\t\t\topAttributorBlob.type === SummaryType.Blob &&\n\t\t\t\ttypeof opAttributorBlob.content === \"string\",\n\t\t);\n\t\tconst decoder = chain(\n\t\t\tnew AttributorSerializer((entries) => new Attributor(entries), deltaEncoder),\n\t\t\tmakeLZ4Encoder(),\n\t\t);\n\t\tconst decoded = decoder.decode(opAttributorBlob.content);\n\t\tassert.deepEqual(decoded.getAttributionInfo(op.sequenceNumber!), {\n\t\t\ttimestamp: op.timestamp,\n\t\t\tuser: context.audience?.getMember(op.clientId!)?.user,\n\t\t});\n\t});\n\n\tit(\"repopulates attribution association data using the summary tree\", async () => {\n\t\tconst op: Partial<ISequencedDocumentMessage> = {\n\t\t\tsequenceNumber: 7,\n\t\t\tclientId,\n\t\t\ttimestamp: 1006,\n\t\t};\n\n\t\tconst encoder = chain(\n\t\t\tnew AttributorSerializer((entries) => new Attributor(entries), deltaEncoder),\n\t\t\tmakeLZ4Encoder(),\n\t\t);\n\t\tconst context = getMockContext() as Mutable<IContainerContext>;\n\t\tconst sampleAttributor = new Attributor([\n\t\t\t[\n\t\t\t\top.sequenceNumber!,\n\t\t\t\t{ timestamp: op.timestamp!, user: context.audience!.getMember(op.clientId!)!.user },\n\t\t\t],\n\t\t]);\n\n\t\tconst opAttributorBlobId = \"mock attributor blob id\";\n\t\tconst mockStorage: IDocumentStorageService = {\n\t\t\treadBlob: async (blobId: string) => {\n\t\t\t\tassert(blobId === opAttributorBlobId);\n\t\t\t\treturn encoder.encode(sampleAttributor);\n\t\t\t},\n\t\t} as unknown as IDocumentStorageService;\n\t\tconst snapshot: ISnapshotTree = {\n\t\t\tblobs: {},\n\t\t\ttrees: {\n\t\t\t\t\".attributor\": {\n\t\t\t\t\tblobs: { op: opAttributorBlobId },\n\t\t\t\t\ttrees: {},\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t\tcontext.baseSnapshot = snapshot;\n\t\tcontext.storage = mockStorage;\n\t\tconst containerRuntime = await AttributingContainerRuntime.loadRuntime({\n\t\t\tcontext,\n\t\t\tregistryEntries: [],\n\t\t\tcontainerScope: getScope(),\n\t\t\tprovideEntryPoint: async () => ({}),\n\t\t\texisting: false,\n\t\t});\n\n\t\tconst maybeProvidesAttributor: FluidObject<IProvideRuntimeAttributor> =\n\t\t\tcontainerRuntime.scope;\n\t\tassert(maybeProvidesAttributor.IRuntimeAttributor !== undefined);\n\t\tconst runtimeAttribution = maybeProvidesAttributor.IRuntimeAttributor;\n\n\t\tassert.deepEqual(runtimeAttribution.get({ type: \"op\", seq: op.sequenceNumber! }), {\n\t\t\ttimestamp: op.timestamp,\n\t\t\tuser: context.audience?.getMember(op.clientId!)?.user,\n\t\t});\n\t});\n\n\tdescribe(\"Doesn't summarize attributor\", () => {\n\t\tconst testCases: { getContext: () => IContainerContext; testName: string }[] = [\n\t\t\t{\n\t\t\t\ttestName: \"for existing documents that had no attributor\",\n\t\t\t\tgetContext: (): IContainerContext => {\n\t\t\t\t\tsetEnableOnNew(true);\n\t\t\t\t\tconst context = getMockContext() as Mutable<IContainerContext>;\n\t\t\t\t\tconst snapshot: ISnapshotTree = {\n\t\t\t\t\t\tblobs: {},\n\t\t\t\t\t\ttrees: {},\n\t\t\t\t\t};\n\t\t\t\t\tcontext.baseSnapshot = snapshot;\n\t\t\t\t\treturn context;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttestName: `for new documents with ${enableOnNewFileKey} unset`,\n\t\t\t\tgetContext: (): IContainerContext => {\n\t\t\t\t\treturn getMockContext() as IContainerContext;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttestName: `for new documents with ${enableOnNewFileKey} set to false`,\n\t\t\t\tgetContext: (): IContainerContext => {\n\t\t\t\t\tsetEnableOnNew(false);\n\t\t\t\t\tconst context = getMockContext() as Mutable<IContainerContext>;\n\t\t\t\t\tconst snapshot: ISnapshotTree = {\n\t\t\t\t\t\tblobs: {},\n\t\t\t\t\t\ttrees: {},\n\t\t\t\t\t};\n\t\t\t\t\tcontext.baseSnapshot = snapshot;\n\t\t\t\t\treturn context;\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\tfor (const { getContext, testName } of testCases) {\n\t\t\tit(testName, async () => {\n\t\t\t\tconst context = getContext();\n\t\t\t\tconst containerRuntime = await AttributingContainerRuntime.loadRuntime({\n\t\t\t\t\tcontext,\n\t\t\t\t\tregistryEntries: [],\n\t\t\t\t\tcontainerScope: getScope(),\n\t\t\t\t\tprovideEntryPoint: async () => ({}),\n\t\t\t\t\texisting: false,\n\t\t\t\t});\n\n\t\t\t\tconst maybeProvidesAttributor: FluidObject<IProvideRuntimeAttributor> =\n\t\t\t\t\tcontainerRuntime.scope;\n\t\t\t\tassert(maybeProvidesAttributor.IRuntimeAttributor !== undefined);\n\n\t\t\t\tconst { summary } = await containerRuntime.summarize({\n\t\t\t\t\tfullTree: true,\n\t\t\t\t\ttrackState: false,\n\t\t\t\t\trunGC: false,\n\t\t\t\t});\n\t\t\t\tassert(summary.tree[\".attributor\"] === undefined);\n\t\t\t});\n\t\t}\n\t});\n});\n\n/* eslint-enable @typescript-eslint/no-non-null-assertion */\n"]}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { strict as assert } from "node:assert";
|
|
6
|
-
import { MockDeltaManager } from "@fluidframework/test-runtime-utils";
|
|
7
|
-
import { OpStreamAttributor } from "../attributor.js";
|
|
8
|
-
import { makeMockAudience } from "./utils.js";
|
|
9
|
-
const clientIds = ["A", "B", "C"];
|
|
10
|
-
const defaultAudience = makeMockAudience(clientIds);
|
|
11
|
-
class OpFactory {
|
|
12
|
-
constructor() {
|
|
13
|
-
this.seq = 0;
|
|
14
|
-
}
|
|
15
|
-
makeOp({ timestamp, clientId, }) {
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
17
|
-
return {
|
|
18
|
-
type: "op",
|
|
19
|
-
timestamp,
|
|
20
|
-
clientId,
|
|
21
|
-
sequenceNumber: this.seq++,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
describe("OpStreamAttributor", () => {
|
|
26
|
-
let opFactory;
|
|
27
|
-
beforeEach(() => {
|
|
28
|
-
opFactory = new OpFactory();
|
|
29
|
-
});
|
|
30
|
-
it("can retrieve user information from ops submitted during the current session", () => {
|
|
31
|
-
const deltaManager = new MockDeltaManager();
|
|
32
|
-
const attributor = new OpStreamAttributor(deltaManager, defaultAudience);
|
|
33
|
-
const clientId = clientIds[1];
|
|
34
|
-
const timestamp = 50;
|
|
35
|
-
const op = opFactory.makeOp({ timestamp, clientId });
|
|
36
|
-
deltaManager.emit("op", op);
|
|
37
|
-
assert.deepEqual(attributor.getAttributionInfo(op.sequenceNumber), {
|
|
38
|
-
user: defaultAudience.getMember(clientId)?.user,
|
|
39
|
-
timestamp,
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
//# sourceMappingURL=opStreamAttributor.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"opStreamAttributor.spec.js","sourceRoot":"","sources":["../../src/test/opStreamAttributor.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAClC,MAAM,eAAe,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAEpD,MAAM,SAAS;IAAf;QACS,QAAG,GAAG,CAAC,CAAC;IAiBjB,CAAC;IAfO,MAAM,CAAC,EACb,SAAS,EACT,QAAQ,GAIR;QACA,yEAAyE;QACzE,OAAO;YACN,IAAI,EAAE,IAAI;YACV,SAAS;YACT,QAAQ;YACR,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE;SACG,CAAC;IAChC,CAAC;CACD;AAED,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IACnC,IAAI,SAAoB,CAAC;IACzB,UAAU,CAAC,GAAG,EAAE;QACf,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACtF,MAAM,YAAY,GAAG,IAAI,gBAAgB,EAAE,CAAC;QAC5C,MAAM,UAAU,GAAG,IAAI,kBAAkB,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,EAAE,CAAC;QACrB,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5B,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC,cAAc,CAAC,EAAE;YAClE,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI;YAC/C,SAAS;SACT,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { strict as assert } from \"node:assert\";\nimport { type ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { MockDeltaManager } from \"@fluidframework/test-runtime-utils\";\nimport { OpStreamAttributor } from \"../attributor.js\";\nimport { makeMockAudience } from \"./utils.js\";\n\nconst clientIds = [\"A\", \"B\", \"C\"];\nconst defaultAudience = makeMockAudience(clientIds);\n\nclass OpFactory {\n\tprivate seq = 0;\n\n\tpublic makeOp({\n\t\ttimestamp,\n\t\tclientId,\n\t}: {\n\t\ttimestamp: number;\n\t\tclientId: string;\n\t}): ISequencedDocumentMessage {\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\t\treturn {\n\t\t\ttype: \"op\",\n\t\t\ttimestamp,\n\t\t\tclientId,\n\t\t\tsequenceNumber: this.seq++,\n\t\t} as ISequencedDocumentMessage;\n\t}\n}\n\ndescribe(\"OpStreamAttributor\", () => {\n\tlet opFactory: OpFactory;\n\tbeforeEach(() => {\n\t\topFactory = new OpFactory();\n\t});\n\n\tit(\"can retrieve user information from ops submitted during the current session\", () => {\n\t\tconst deltaManager = new MockDeltaManager();\n\t\tconst attributor = new OpStreamAttributor(deltaManager, defaultAudience);\n\t\tconst clientId = clientIds[1];\n\t\tconst timestamp = 50;\n\t\tconst op = opFactory.makeOp({ timestamp, clientId });\n\t\tdeltaManager.emit(\"op\", op);\n\t\tassert.deepEqual(attributor.getAttributionInfo(op.sequenceNumber), {\n\t\t\tuser: defaultAudience.getMember(clientId)?.user,\n\t\t\ttimestamp,\n\t\t});\n\t});\n});\n"]}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { strict as assert } from "node:assert";
|
|
6
|
-
import { MutableStringInterner } from "../stringInterner.js";
|
|
7
|
-
describe("MutableStringInterner", () => {
|
|
8
|
-
const inputStrings = ["test", "test2", "test3", "test4"];
|
|
9
|
-
it("can associate a string with an intern ID", () => {
|
|
10
|
-
const interner = new MutableStringInterner();
|
|
11
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);
|
|
12
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);
|
|
13
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);
|
|
14
|
-
});
|
|
15
|
-
it("can handle empty strings", () => {
|
|
16
|
-
const interner = new MutableStringInterner();
|
|
17
|
-
assert.equal(interner.getOrCreateInternedId(""), 0);
|
|
18
|
-
});
|
|
19
|
-
it("getInternedId returns undefined for un-created ids", () => {
|
|
20
|
-
const interner = new MutableStringInterner();
|
|
21
|
-
assert.equal(interner.getInternedId(inputStrings[0]), undefined);
|
|
22
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);
|
|
23
|
-
assert.equal(interner.getInternedId(inputStrings[0]), 0);
|
|
24
|
-
assert.equal(interner.getInternedId(inputStrings[1]), undefined);
|
|
25
|
-
});
|
|
26
|
-
it("can retrieve the intern ID associated with a string", () => {
|
|
27
|
-
const interner = new MutableStringInterner();
|
|
28
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);
|
|
29
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);
|
|
30
|
-
assert.equal(interner.getInternedId(inputStrings[0]), 0);
|
|
31
|
-
assert.equal(interner.getInternedId(inputStrings[1]), 1);
|
|
32
|
-
assert.equal(interner.getString(0), inputStrings[0]);
|
|
33
|
-
assert.equal(interner.getString(1), inputStrings[1]);
|
|
34
|
-
});
|
|
35
|
-
it("throws an error when trying to retrieve a string that hasn't been encountered", () => {
|
|
36
|
-
const interner = new MutableStringInterner();
|
|
37
|
-
assert.throws(() => interner.getString(0), /No string associated with 0\./, "error should be thrown");
|
|
38
|
-
});
|
|
39
|
-
it("can return a serializable representation of its state", () => {
|
|
40
|
-
const interner = new MutableStringInterner();
|
|
41
|
-
for (const value of inputStrings) {
|
|
42
|
-
interner.getOrCreateInternedId(value);
|
|
43
|
-
}
|
|
44
|
-
assert.deepEqual(interner.getSerializable(), inputStrings);
|
|
45
|
-
});
|
|
46
|
-
it("can be initialized with a list of input strings", () => {
|
|
47
|
-
const interner = new MutableStringInterner(inputStrings);
|
|
48
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[3]), 3);
|
|
49
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[2]), 2);
|
|
50
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);
|
|
51
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);
|
|
52
|
-
});
|
|
53
|
-
it("can be initialized with a list of input strings that include duplicate IDs", () => {
|
|
54
|
-
const interner = new MutableStringInterner([...inputStrings, ...inputStrings]);
|
|
55
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[3]), 3);
|
|
56
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[2]), 2);
|
|
57
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);
|
|
58
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);
|
|
59
|
-
});
|
|
60
|
-
it("doesn't change a string's intern ID when retrieving it multiple times", () => {
|
|
61
|
-
const interner = new MutableStringInterner();
|
|
62
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);
|
|
63
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);
|
|
64
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);
|
|
65
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);
|
|
66
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);
|
|
67
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);
|
|
68
|
-
assert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
//# sourceMappingURL=stringInterner.spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stringInterner.spec.js","sourceRoot":"","sources":["../../src/test/stringInterner.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACtC,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEzD,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QACnD,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACnC,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC7D,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC9D,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEzD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACxF,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;QAE7C,MAAM,CAAC,MAAM,CACZ,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAC3B,+BAA+B,EAC/B,wBAAwB,CACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAChE,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;QAE7C,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE;YACjC,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;SACtC;QAED,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,EAAE,YAAY,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QAC1D,MAAM,QAAQ,GAAG,IAAI,qBAAqB,CAAC,YAAY,CAAC,CAAC;QAEzD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QACrF,MAAM,QAAQ,GAAG,IAAI,qBAAqB,CAAC,CAAC,GAAG,YAAY,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;QAE/E,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAChF,MAAM,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;QAE7C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport { MutableStringInterner } from \"../stringInterner.js\";\n\ndescribe(\"MutableStringInterner\", () => {\n\tconst inputStrings = [\"test\", \"test2\", \"test3\", \"test4\"];\n\n\tit(\"can associate a string with an intern ID\", () => {\n\t\tconst interner = new MutableStringInterner();\n\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);\n\t});\n\n\tit(\"can handle empty strings\", () => {\n\t\tconst interner = new MutableStringInterner();\n\n\t\tassert.equal(interner.getOrCreateInternedId(\"\"), 0);\n\t});\n\n\tit(\"getInternedId returns undefined for un-created ids\", () => {\n\t\tconst interner = new MutableStringInterner();\n\n\t\tassert.equal(interner.getInternedId(inputStrings[0]), undefined);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);\n\t\tassert.equal(interner.getInternedId(inputStrings[0]), 0);\n\t\tassert.equal(interner.getInternedId(inputStrings[1]), undefined);\n\t});\n\n\tit(\"can retrieve the intern ID associated with a string\", () => {\n\t\tconst interner = new MutableStringInterner();\n\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);\n\t\tassert.equal(interner.getInternedId(inputStrings[0]), 0);\n\t\tassert.equal(interner.getInternedId(inputStrings[1]), 1);\n\n\t\tassert.equal(interner.getString(0), inputStrings[0]);\n\t\tassert.equal(interner.getString(1), inputStrings[1]);\n\t});\n\n\tit(\"throws an error when trying to retrieve a string that hasn't been encountered\", () => {\n\t\tconst interner = new MutableStringInterner();\n\n\t\tassert.throws(\n\t\t\t() => interner.getString(0),\n\t\t\t/No string associated with 0\\./,\n\t\t\t\"error should be thrown\",\n\t\t);\n\t});\n\n\tit(\"can return a serializable representation of its state\", () => {\n\t\tconst interner = new MutableStringInterner();\n\n\t\tfor (const value of inputStrings) {\n\t\t\tinterner.getOrCreateInternedId(value);\n\t\t}\n\n\t\tassert.deepEqual(interner.getSerializable(), inputStrings);\n\t});\n\n\tit(\"can be initialized with a list of input strings\", () => {\n\t\tconst interner = new MutableStringInterner(inputStrings);\n\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[3]), 3);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[2]), 2);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);\n\t});\n\n\tit(\"can be initialized with a list of input strings that include duplicate IDs\", () => {\n\t\tconst interner = new MutableStringInterner([...inputStrings, ...inputStrings]);\n\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[3]), 3);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[2]), 2);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);\n\t});\n\n\tit(\"doesn't change a string's intern ID when retrieving it multiple times\", () => {\n\t\tconst interner = new MutableStringInterner();\n\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[0]), 0);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);\n\t\tassert.equal(interner.getOrCreateInternedId(inputStrings[1]), 1);\n\t});\n});\n"]}
|
package/lib/test/utils.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates a mock {@link @fluidframework/container-definitions#IAudience} for testing.
|
|
3
|
-
*/
|
|
4
|
-
export function makeMockAudience(clientIds) {
|
|
5
|
-
const clients = new Map();
|
|
6
|
-
for (const [index, clientId] of clientIds.entries()) {
|
|
7
|
-
// eslint-disable-next-line unicorn/prefer-code-point
|
|
8
|
-
const stringId = String.fromCharCode(index + 65);
|
|
9
|
-
const name = stringId.repeat(10);
|
|
10
|
-
const userId = `${name}@microsoft.com`;
|
|
11
|
-
const email = userId;
|
|
12
|
-
const user = {
|
|
13
|
-
id: userId,
|
|
14
|
-
name,
|
|
15
|
-
email,
|
|
16
|
-
};
|
|
17
|
-
clients.set(clientId, {
|
|
18
|
-
mode: "write",
|
|
19
|
-
details: { capabilities: { interactive: true } },
|
|
20
|
-
permission: [],
|
|
21
|
-
user,
|
|
22
|
-
scopes: [],
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
26
|
-
return {
|
|
27
|
-
getMember: (clientId) => {
|
|
28
|
-
return clients.get(clientId);
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
//# sourceMappingURL=utils.js.map
|
package/lib/test/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAmB;IACnD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC3C,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE;QACpD,qDAAqD;QACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,GAAG,IAAI,gBAAgB,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC;QACrB,MAAM,IAAI,GAAG;YACZ,EAAE,EAAE,MAAM;YACV,IAAI;YACJ,KAAK;SACL,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE;YACrB,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,EAAE,YAAY,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;YAChD,UAAU,EAAE,EAAE;YACd,IAAI;YACJ,MAAM,EAAE,EAAE;SACV,CAAC,CAAC;KACH;IACD,yEAAyE;IACzE,OAAO;QACN,SAAS,EAAE,CAAC,QAAgB,EAAuB,EAAE;YACpD,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;KACY,CAAC;AAChB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { type IClient } from \"@fluidframework/protocol-definitions\";\nimport { type IAudience } from \"@fluidframework/container-definitions\";\n\n/**\n * Creates a mock {@link @fluidframework/container-definitions#IAudience} for testing.\n */\nexport function makeMockAudience(clientIds: string[]): IAudience {\n\tconst clients = new Map<string, IClient>();\n\tfor (const [index, clientId] of clientIds.entries()) {\n\t\t// eslint-disable-next-line unicorn/prefer-code-point\n\t\tconst stringId = String.fromCharCode(index + 65);\n\t\tconst name = stringId.repeat(10);\n\t\tconst userId = `${name}@microsoft.com`;\n\t\tconst email = userId;\n\t\tconst user = {\n\t\t\tid: userId,\n\t\t\tname,\n\t\t\temail,\n\t\t};\n\t\tclients.set(clientId, {\n\t\t\tmode: \"write\",\n\t\t\tdetails: { capabilities: { interactive: true } },\n\t\t\tpermission: [],\n\t\t\tuser,\n\t\t\tscopes: [],\n\t\t});\n\t}\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\treturn {\n\t\tgetMember: (clientId: string): IClient | undefined => {\n\t\t\treturn clients.get(clientId);\n\t\t},\n\t} as IAudience;\n}\n"]}
|
|
File without changes
|