@fluidframework/telemetry-utils 2.0.0-internal.4.2.1 → 2.0.0-internal.4.4.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 +4 -0
- package/dist/mockLogger.d.ts +10 -7
- package/dist/mockLogger.d.ts.map +1 -1
- package/dist/mockLogger.js +45 -19
- package/dist/mockLogger.js.map +1 -1
- package/lib/mockLogger.d.ts +10 -7
- package/lib/mockLogger.d.ts.map +1 -1
- package/lib/mockLogger.js +45 -19
- package/lib/mockLogger.js.map +1 -1
- package/package.json +3 -4
- package/src/mockLogger.ts +73 -18
- package/dist/packageVersion.d.ts +0 -9
- package/dist/packageVersion.d.ts.map +0 -1
- package/dist/packageVersion.js +0 -12
- package/dist/packageVersion.js.map +0 -1
- package/lib/packageVersion.d.ts +0 -9
- package/lib/packageVersion.d.ts.map +0 -1
- package/lib/packageVersion.js +0 -9
- package/lib/packageVersion.js.map +0 -1
- package/src/packageVersion.ts +0 -9
package/CHANGELOG.md
CHANGED
package/dist/mockLogger.d.ts
CHANGED
|
@@ -17,35 +17,38 @@ export declare class MockLogger extends TelemetryLogger implements ITelemetryLog
|
|
|
17
17
|
* Search events logged since the last time matchEvents was called, looking for the given expected
|
|
18
18
|
* events in order.
|
|
19
19
|
* @param expectedEvents - events in order that are expected to appear in the recorded log.
|
|
20
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
20
21
|
* These event objects may be subsets of the logged events.
|
|
21
22
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
22
23
|
*/
|
|
23
|
-
matchEvents(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): boolean;
|
|
24
|
+
matchEvents(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], inlineDetailsProp?: boolean): boolean;
|
|
24
25
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
25
|
-
assertMatch(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string): void;
|
|
26
|
+
assertMatch(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
|
|
26
27
|
/**
|
|
27
28
|
* Search events logged since the last time matchEvents was called, looking for any of the given
|
|
28
29
|
* expected events.
|
|
29
30
|
* @param expectedEvents - events that are expected to appear in the recorded log.
|
|
31
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
30
32
|
* These event objects may be subsets of the logged events.
|
|
31
33
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
32
34
|
* @returns if any of the expected events is found.
|
|
33
35
|
*/
|
|
34
|
-
matchAnyEvent(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): boolean;
|
|
36
|
+
matchAnyEvent(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], inlineDetailsProp?: boolean): boolean;
|
|
35
37
|
/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */
|
|
36
|
-
assertMatchAny(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string): void;
|
|
38
|
+
assertMatchAny(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
|
|
37
39
|
/**
|
|
38
40
|
* Search events logged since the last time matchEvents was called, looking only for the given expected
|
|
39
41
|
* events in order.
|
|
40
42
|
* @param expectedEvents - events in order that are expected to be the only events in the recorded log.
|
|
43
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
41
44
|
* These event objects may be subsets of the logged events.
|
|
42
45
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
43
46
|
*/
|
|
44
|
-
matchEventStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): boolean;
|
|
47
|
+
matchEventStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], inlineDetailsProp?: boolean): boolean;
|
|
45
48
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
46
|
-
assertMatchStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string): void;
|
|
49
|
+
assertMatchStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
|
|
47
50
|
/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */
|
|
48
|
-
assertMatchNone(disallowedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string): void;
|
|
51
|
+
assertMatchNone(disallowedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
|
|
49
52
|
private getMatchedEventsCount;
|
|
50
53
|
/**
|
|
51
54
|
* Ensure the expected event is a strict subset of the actual event
|
package/dist/mockLogger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockLogger.d.ts","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"mockLogger.d.ts","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAE3F,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;;GAGG;AACH,qBAAa,UAAW,SAAQ,eAAgB,YAAW,gBAAgB;IAC1E,MAAM,EAAE,mBAAmB,EAAE,CAAM;;IAMnC,KAAK;IAIL,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAItC;;;;;;;OAOG;IACH,WAAW,CACV,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAUV,qFAAqF;IACrF,WAAW,CACV,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC;;;;;;;;OAQG;IACH,aAAa,CACZ,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAQV,uFAAuF;IACvF,cAAc,CACb,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC;;;;;;;OAOG;IACH,gBAAgB,CACf,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAOV,qFAAqF;IACrF,iBAAiB,CAChB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC,6GAA6G;IAC7G,eAAe,CACd,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACzD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC,OAAO,CAAC,qBAAqB;IAsB7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;CAqB1B"}
|
package/dist/mockLogger.js
CHANGED
|
@@ -3,8 +3,20 @@
|
|
|
3
3
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
7
|
+
var t = {};
|
|
8
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
9
|
+
t[p] = s[p];
|
|
10
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
11
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
12
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
13
|
+
t[p[i]] = s[p[i]];
|
|
14
|
+
}
|
|
15
|
+
return t;
|
|
16
|
+
};
|
|
6
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
18
|
exports.MockLogger = void 0;
|
|
19
|
+
const common_utils_1 = require("@fluidframework/common-utils");
|
|
8
20
|
const logger_1 = require("./logger");
|
|
9
21
|
/**
|
|
10
22
|
* The MockLogger records events sent to it, and then can walk back over those events
|
|
@@ -25,19 +37,20 @@ class MockLogger extends logger_1.TelemetryLogger {
|
|
|
25
37
|
* Search events logged since the last time matchEvents was called, looking for the given expected
|
|
26
38
|
* events in order.
|
|
27
39
|
* @param expectedEvents - events in order that are expected to appear in the recorded log.
|
|
40
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
28
41
|
* These event objects may be subsets of the logged events.
|
|
29
42
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
30
43
|
*/
|
|
31
|
-
matchEvents(expectedEvents) {
|
|
32
|
-
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);
|
|
44
|
+
matchEvents(expectedEvents, inlineDetailsProp = false) {
|
|
45
|
+
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents, inlineDetailsProp);
|
|
33
46
|
// How many expected events were left over? Hopefully none.
|
|
34
47
|
const unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;
|
|
35
48
|
return unmatchedExpectedEventCount === 0;
|
|
36
49
|
}
|
|
37
50
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
38
|
-
assertMatch(expectedEvents, message) {
|
|
51
|
+
assertMatch(expectedEvents, message, inlineDetailsProp = false) {
|
|
39
52
|
const actualEvents = this.events;
|
|
40
|
-
if (!this.matchEvents(expectedEvents)) {
|
|
53
|
+
if (!this.matchEvents(expectedEvents, inlineDetailsProp)) {
|
|
41
54
|
throw new Error(`${message}
|
|
42
55
|
expected:
|
|
43
56
|
${JSON.stringify(expectedEvents)}
|
|
@@ -50,18 +63,19 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
50
63
|
* Search events logged since the last time matchEvents was called, looking for any of the given
|
|
51
64
|
* expected events.
|
|
52
65
|
* @param expectedEvents - events that are expected to appear in the recorded log.
|
|
66
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
53
67
|
* These event objects may be subsets of the logged events.
|
|
54
68
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
55
69
|
* @returns if any of the expected events is found.
|
|
56
70
|
*/
|
|
57
|
-
matchAnyEvent(expectedEvents) {
|
|
58
|
-
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);
|
|
71
|
+
matchAnyEvent(expectedEvents, inlineDetailsProp = false) {
|
|
72
|
+
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents, inlineDetailsProp);
|
|
59
73
|
return matchedExpectedEventCount > 0;
|
|
60
74
|
}
|
|
61
75
|
/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */
|
|
62
|
-
assertMatchAny(expectedEvents, message) {
|
|
76
|
+
assertMatchAny(expectedEvents, message, inlineDetailsProp = false) {
|
|
63
77
|
const actualEvents = this.events;
|
|
64
|
-
if (!this.matchAnyEvent(expectedEvents)) {
|
|
78
|
+
if (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {
|
|
65
79
|
throw new Error(`${message}
|
|
66
80
|
expected:
|
|
67
81
|
${JSON.stringify(expectedEvents)}
|
|
@@ -74,16 +88,18 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
74
88
|
* Search events logged since the last time matchEvents was called, looking only for the given expected
|
|
75
89
|
* events in order.
|
|
76
90
|
* @param expectedEvents - events in order that are expected to be the only events in the recorded log.
|
|
91
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
77
92
|
* These event objects may be subsets of the logged events.
|
|
78
93
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
79
94
|
*/
|
|
80
|
-
matchEventStrict(expectedEvents) {
|
|
81
|
-
return expectedEvents.length === this.events.length &&
|
|
95
|
+
matchEventStrict(expectedEvents, inlineDetailsProp = false) {
|
|
96
|
+
return (expectedEvents.length === this.events.length &&
|
|
97
|
+
this.matchEvents(expectedEvents, inlineDetailsProp));
|
|
82
98
|
}
|
|
83
99
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
84
|
-
assertMatchStrict(expectedEvents, message) {
|
|
100
|
+
assertMatchStrict(expectedEvents, message, inlineDetailsProp = false) {
|
|
85
101
|
const actualEvents = this.events;
|
|
86
|
-
if (!this.matchEventStrict(expectedEvents)) {
|
|
102
|
+
if (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {
|
|
87
103
|
throw new Error(`${message}
|
|
88
104
|
expected:
|
|
89
105
|
${JSON.stringify(expectedEvents)}
|
|
@@ -93,9 +109,9 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
93
109
|
}
|
|
94
110
|
}
|
|
95
111
|
/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */
|
|
96
|
-
assertMatchNone(disallowedEvents, message) {
|
|
112
|
+
assertMatchNone(disallowedEvents, message, inlineDetailsProp = false) {
|
|
97
113
|
const actualEvents = this.events;
|
|
98
|
-
if (this.matchAnyEvent(disallowedEvents)) {
|
|
114
|
+
if (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {
|
|
99
115
|
throw new Error(`${message}
|
|
100
116
|
disallowed events:
|
|
101
117
|
${JSON.stringify(disallowedEvents)}
|
|
@@ -104,11 +120,11 @@ actual:
|
|
|
104
120
|
${JSON.stringify(actualEvents)}`);
|
|
105
121
|
}
|
|
106
122
|
}
|
|
107
|
-
getMatchedEventsCount(expectedEvents) {
|
|
123
|
+
getMatchedEventsCount(expectedEvents, inlineDetailsProp) {
|
|
108
124
|
let iExpectedEvent = 0;
|
|
109
125
|
this.events.forEach((event) => {
|
|
110
126
|
if (iExpectedEvent < expectedEvents.length &&
|
|
111
|
-
MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent])) {
|
|
127
|
+
MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)) {
|
|
112
128
|
// We found the next expected event; increment
|
|
113
129
|
++iExpectedEvent;
|
|
114
130
|
}
|
|
@@ -121,9 +137,19 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
121
137
|
/**
|
|
122
138
|
* Ensure the expected event is a strict subset of the actual event
|
|
123
139
|
*/
|
|
124
|
-
static eventsMatch(actual, expected) {
|
|
125
|
-
const
|
|
126
|
-
|
|
140
|
+
static eventsMatch(actual, expected, inlineDetailsProp) {
|
|
141
|
+
const { details } = actual, actualForMatching = __rest(actual, ["details"]);
|
|
142
|
+
let detailsExpanded = { details };
|
|
143
|
+
// "details" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.
|
|
144
|
+
// Some of the properties in the expected event may be inside "details". So, if inlineDetailsProp is true,
|
|
145
|
+
// extract the properties from "details" in the actual event and inline them in the actual event.
|
|
146
|
+
if (inlineDetailsProp && details !== undefined) {
|
|
147
|
+
(0, common_utils_1.assert)(typeof details === "string", 0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */);
|
|
148
|
+
detailsExpanded = JSON.parse(details);
|
|
149
|
+
}
|
|
150
|
+
const actualExpanded = Object.assign(Object.assign({}, actualForMatching), detailsExpanded);
|
|
151
|
+
const masked = Object.assign(Object.assign({}, actualExpanded), expected);
|
|
152
|
+
return JSON.stringify(masked) === JSON.stringify(actualExpanded);
|
|
127
153
|
}
|
|
128
154
|
}
|
|
129
155
|
exports.MockLogger = MockLogger;
|
package/dist/mockLogger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockLogger.js","sourceRoot":"","sources":["../src/mockLogger.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\nimport { ITelemetryLogger, ITelemetryBaseEvent } from \"@fluidframework/common-definitions\";\nimport { TelemetryLogger } from \"./logger\";\n\n/**\n * The MockLogger records events sent to it, and then can walk back over those events\n * searching for a set of expected events to match against the logged events.\n */\nexport class MockLogger extends TelemetryLogger implements ITelemetryLogger {\n\tevents: ITelemetryBaseEvent[] = [];\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tclear() {\n\t\tthis.events = [];\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tthis.events.push(event);\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to appear in the recorded log.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEvents(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[]): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);\n\t\t// How many expected events were left over? Hopefully none.\n\t\tconst unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;\n\t\treturn unmatchedExpectedEventCount === 0;\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatch(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[], message?: string) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEvents(expectedEvents)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for any of the given\n\t * expected events.\n\t * @param expectedEvents - events that are expected to appear in the recorded log.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t * @returns if any of the expected events is found.\n\t */\n\tmatchAnyEvent(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[]): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */\n\tassertMatchAny(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[], message?: string) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchAnyEvent(expectedEvents)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking only for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to be the only events in the recorded log.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEventStrict(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[]): boolean {\n\t\treturn expectedEvents.length === this.events.length && this.matchEvents(expectedEvents);\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatchStrict(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[], message?: string) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEventStrict(expectedEvents)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */\n\tassertMatchNone(disallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[], message?: string) {\n\t\tconst actualEvents = this.events;\n\t\tif (this.matchAnyEvent(disallowedEvents)) {\n\t\t\tthrow new Error(`${message}\ndisallowed events:\n${JSON.stringify(disallowedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\tprivate getMatchedEventsCount(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[]): number {\n\t\tlet iExpectedEvent = 0;\n\t\tthis.events.forEach((event) => {\n\t\t\tif (\n\t\t\t\tiExpectedEvent < expectedEvents.length &&\n\t\t\t\tMockLogger.eventsMatch(event, expectedEvents[iExpectedEvent])\n\t\t\t) {\n\t\t\t\t// We found the next expected event; increment\n\t\t\t\t++iExpectedEvent;\n\t\t\t}\n\t\t});\n\n\t\t// Remove the events so far; next call will just compare subsequent events from here\n\t\tthis.events = [];\n\n\t\t// Return the count of matched events.\n\t\treturn iExpectedEvent;\n\t}\n\n\t/**\n\t * Ensure the expected event is a strict subset of the actual event\n\t */\n\tprivate static eventsMatch(\n\t\tactual: ITelemetryBaseEvent,\n\t\texpected: Omit<ITelemetryBaseEvent, \"category\">,\n\t): boolean {\n\t\tconst masked = { ...actual, ...expected };\n\t\treturn JSON.stringify(masked) === JSON.stringify(actual);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mockLogger.js","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;AAGH,+DAAsD;AACtD,qCAA2C;AAE3C;;;GAGG;AACH,MAAa,UAAW,SAAQ,wBAAe;IAG9C;QACC,KAAK,EAAE,CAAC;QAHT,WAAM,GAA0B,EAAE,CAAC;IAInC,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,KAA0B;QAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CACV,cAAuD,EACvD,oBAA6B,KAAK;QAElC,MAAM,yBAAyB,GAAG,IAAI,CAAC,qBAAqB,CAC3D,cAAc,EACd,iBAAiB,CACjB,CAAC;QACF,2DAA2D;QAC3D,MAAM,2BAA2B,GAAG,cAAc,CAAC,MAAM,GAAG,yBAAyB,CAAC;QACtF,OAAO,2BAA2B,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,qFAAqF;IACrF,WAAW,CACV,cAAuD,EACvD,OAAgB,EAChB,oBAA6B,KAAK;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE;YACzD,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO;;EAE3B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;EAG9B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SAC/B;IACF,CAAC;IAED;;;;;;;;OAQG;IACH,aAAa,CACZ,cAAuD,EACvD,oBAA6B,KAAK;QAElC,MAAM,yBAAyB,GAAG,IAAI,CAAC,qBAAqB,CAC3D,cAAc,EACd,iBAAiB,CACjB,CAAC;QACF,OAAO,yBAAyB,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,uFAAuF;IACvF,cAAc,CACb,cAAuD,EACvD,OAAgB,EAChB,oBAA6B,KAAK;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE;YAC3D,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO;;EAE3B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;EAG9B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SAC/B;IACF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CACf,cAAuD,EACvD,oBAA6B,KAAK;QAElC,OAAO,CACN,cAAc,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM;YAC5C,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,iBAAiB,CAAC,CACnD,CAAC;IACH,CAAC;IAED,qFAAqF;IACrF,iBAAiB,CAChB,cAAuD,EACvD,OAAgB,EAChB,oBAA6B,KAAK;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE;YAC9D,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO;;EAE3B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;EAG9B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SAC/B;IACF,CAAC;IAED,6GAA6G;IAC7G,eAAe,CACd,gBAAyD,EACzD,OAAgB,EAChB,oBAA6B,KAAK;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,EAAE;YAC5D,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO;;EAE3B,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;;;EAGhC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SAC/B;IACF,CAAC;IAEO,qBAAqB,CAC5B,cAAuD,EACvD,iBAA0B;QAE1B,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC7B,IACC,cAAc,GAAG,cAAc,CAAC,MAAM;gBACtC,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,EAAE,iBAAiB,CAAC,EAC/E;gBACD,8CAA8C;gBAC9C,EAAE,cAAc,CAAC;aACjB;QACF,CAAC,CAAC,CAAC;QAEH,oFAAoF;QACpF,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QAEjB,sCAAsC;QACtC,OAAO,cAAc,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,WAAW,CACzB,MAA2B,EAC3B,QAA+C,EAC/C,iBAA0B;QAE1B,MAAM,EAAE,OAAO,KAA2B,MAAM,EAA5B,iBAAiB,UAAK,MAAM,EAA1C,WAAiC,CAAS,CAAC;QACjD,IAAI,eAAe,GAAG,EAAE,OAAO,EAAE,CAAC;QAClC,2GAA2G;QAC3G,0GAA0G;QAC1G,iGAAiG;QACjG,IAAI,iBAAiB,IAAI,OAAO,KAAK,SAAS,EAAE;YAC/C,IAAA,qBAAM,EACL,OAAO,OAAO,KAAK,QAAQ,EAC3B,KAAK,CAAC,2EAA2E,CACjF,CAAC;YACF,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;SACtC;QACD,MAAM,cAAc,mCAA6B,iBAAiB,GAAK,eAAe,CAAE,CAAC;QACzF,MAAM,MAAM,mCAAQ,cAAc,GAAK,QAAQ,CAAE,CAAC;QAClD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAClE,CAAC;CACD;AA5LD,gCA4LC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger, ITelemetryBaseEvent } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { TelemetryLogger } from \"./logger\";\n\n/**\n * The MockLogger records events sent to it, and then can walk back over those events\n * searching for a set of expected events to match against the logged events.\n */\nexport class MockLogger extends TelemetryLogger implements ITelemetryLogger {\n\tevents: ITelemetryBaseEvent[] = [];\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tclear() {\n\t\tthis.events = [];\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tthis.events.push(event);\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEvents(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\t// How many expected events were left over? Hopefully none.\n\t\tconst unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;\n\t\treturn unmatchedExpectedEventCount === 0;\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatch(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEvents(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for any of the given\n\t * expected events.\n\t * @param expectedEvents - events that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t * @returns if any of the expected events is found.\n\t */\n\tmatchAnyEvent(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */\n\tassertMatchAny(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking only for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to be the only events in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEventStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\treturn (\n\t\t\texpectedEvents.length === this.events.length &&\n\t\t\tthis.matchEvents(expectedEvents, inlineDetailsProp)\n\t\t);\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatchStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */\n\tassertMatchNone(\n\t\tdisallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\ndisallowed events:\n${JSON.stringify(disallowedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\tprivate getMatchedEventsCount(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean,\n\t): number {\n\t\tlet iExpectedEvent = 0;\n\t\tthis.events.forEach((event) => {\n\t\t\tif (\n\t\t\t\tiExpectedEvent < expectedEvents.length &&\n\t\t\t\tMockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)\n\t\t\t) {\n\t\t\t\t// We found the next expected event; increment\n\t\t\t\t++iExpectedEvent;\n\t\t\t}\n\t\t});\n\n\t\t// Remove the events so far; next call will just compare subsequent events from here\n\t\tthis.events = [];\n\n\t\t// Return the count of matched events.\n\t\treturn iExpectedEvent;\n\t}\n\n\t/**\n\t * Ensure the expected event is a strict subset of the actual event\n\t */\n\tprivate static eventsMatch(\n\t\tactual: ITelemetryBaseEvent,\n\t\texpected: Omit<ITelemetryBaseEvent, \"category\">,\n\t\tinlineDetailsProp: boolean,\n\t): boolean {\n\t\tconst { details, ...actualForMatching } = actual;\n\t\tlet detailsExpanded = { details };\n\t\t// \"details\" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.\n\t\t// Some of the properties in the expected event may be inside \"details\". So, if inlineDetailsProp is true,\n\t\t// extract the properties from \"details\" in the actual event and inline them in the actual event.\n\t\tif (inlineDetailsProp && details !== undefined) {\n\t\t\tassert(\n\t\t\t\ttypeof details === \"string\",\n\t\t\t\t0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */,\n\t\t\t);\n\t\t\tdetailsExpanded = JSON.parse(details);\n\t\t}\n\t\tconst actualExpanded: ITelemetryBaseEvent = { ...actualForMatching, ...detailsExpanded };\n\t\tconst masked = { ...actualExpanded, ...expected };\n\t\treturn JSON.stringify(masked) === JSON.stringify(actualExpanded);\n\t}\n}\n"]}
|
package/lib/mockLogger.d.ts
CHANGED
|
@@ -17,35 +17,38 @@ export declare class MockLogger extends TelemetryLogger implements ITelemetryLog
|
|
|
17
17
|
* Search events logged since the last time matchEvents was called, looking for the given expected
|
|
18
18
|
* events in order.
|
|
19
19
|
* @param expectedEvents - events in order that are expected to appear in the recorded log.
|
|
20
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
20
21
|
* These event objects may be subsets of the logged events.
|
|
21
22
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
22
23
|
*/
|
|
23
|
-
matchEvents(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): boolean;
|
|
24
|
+
matchEvents(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], inlineDetailsProp?: boolean): boolean;
|
|
24
25
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
25
|
-
assertMatch(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string): void;
|
|
26
|
+
assertMatch(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
|
|
26
27
|
/**
|
|
27
28
|
* Search events logged since the last time matchEvents was called, looking for any of the given
|
|
28
29
|
* expected events.
|
|
29
30
|
* @param expectedEvents - events that are expected to appear in the recorded log.
|
|
31
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
30
32
|
* These event objects may be subsets of the logged events.
|
|
31
33
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
32
34
|
* @returns if any of the expected events is found.
|
|
33
35
|
*/
|
|
34
|
-
matchAnyEvent(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): boolean;
|
|
36
|
+
matchAnyEvent(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], inlineDetailsProp?: boolean): boolean;
|
|
35
37
|
/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */
|
|
36
|
-
assertMatchAny(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string): void;
|
|
38
|
+
assertMatchAny(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
|
|
37
39
|
/**
|
|
38
40
|
* Search events logged since the last time matchEvents was called, looking only for the given expected
|
|
39
41
|
* events in order.
|
|
40
42
|
* @param expectedEvents - events in order that are expected to be the only events in the recorded log.
|
|
43
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
41
44
|
* These event objects may be subsets of the logged events.
|
|
42
45
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
43
46
|
*/
|
|
44
|
-
matchEventStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[]): boolean;
|
|
47
|
+
matchEventStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], inlineDetailsProp?: boolean): boolean;
|
|
45
48
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
46
|
-
assertMatchStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string): void;
|
|
49
|
+
assertMatchStrict(expectedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
|
|
47
50
|
/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */
|
|
48
|
-
assertMatchNone(disallowedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string): void;
|
|
51
|
+
assertMatchNone(disallowedEvents: Omit<ITelemetryBaseEvent, "category">[], message?: string, inlineDetailsProp?: boolean): void;
|
|
49
52
|
private getMatchedEventsCount;
|
|
50
53
|
/**
|
|
51
54
|
* Ensure the expected event is a strict subset of the actual event
|
package/lib/mockLogger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockLogger.d.ts","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"mockLogger.d.ts","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAE3F,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C;;;GAGG;AACH,qBAAa,UAAW,SAAQ,eAAgB,YAAW,gBAAgB;IAC1E,MAAM,EAAE,mBAAmB,EAAE,CAAM;;IAMnC,KAAK;IAIL,IAAI,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAItC;;;;;;;OAOG;IACH,WAAW,CACV,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAUV,qFAAqF;IACrF,WAAW,CACV,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC;;;;;;;;OAQG;IACH,aAAa,CACZ,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAQV,uFAAuF;IACvF,cAAc,CACb,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC;;;;;;;OAOG;IACH,gBAAgB,CACf,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,iBAAiB,GAAE,OAAe,GAChC,OAAO;IAOV,qFAAqF;IACrF,iBAAiB,CAChB,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACvD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC,6GAA6G;IAC7G,eAAe,CACd,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAAE,EACzD,OAAO,CAAC,EAAE,MAAM,EAChB,iBAAiB,GAAE,OAAe;IAanC,OAAO,CAAC,qBAAqB;IAsB7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;CAqB1B"}
|
package/lib/mockLogger.js
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
6
|
+
var t = {};
|
|
7
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
8
|
+
t[p] = s[p];
|
|
9
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
10
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
11
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
12
|
+
t[p[i]] = s[p[i]];
|
|
13
|
+
}
|
|
14
|
+
return t;
|
|
15
|
+
};
|
|
16
|
+
import { assert } from "@fluidframework/common-utils";
|
|
5
17
|
import { TelemetryLogger } from "./logger";
|
|
6
18
|
/**
|
|
7
19
|
* The MockLogger records events sent to it, and then can walk back over those events
|
|
@@ -22,19 +34,20 @@ export class MockLogger extends TelemetryLogger {
|
|
|
22
34
|
* Search events logged since the last time matchEvents was called, looking for the given expected
|
|
23
35
|
* events in order.
|
|
24
36
|
* @param expectedEvents - events in order that are expected to appear in the recorded log.
|
|
37
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
25
38
|
* These event objects may be subsets of the logged events.
|
|
26
39
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
27
40
|
*/
|
|
28
|
-
matchEvents(expectedEvents) {
|
|
29
|
-
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);
|
|
41
|
+
matchEvents(expectedEvents, inlineDetailsProp = false) {
|
|
42
|
+
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents, inlineDetailsProp);
|
|
30
43
|
// How many expected events were left over? Hopefully none.
|
|
31
44
|
const unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;
|
|
32
45
|
return unmatchedExpectedEventCount === 0;
|
|
33
46
|
}
|
|
34
47
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
35
|
-
assertMatch(expectedEvents, message) {
|
|
48
|
+
assertMatch(expectedEvents, message, inlineDetailsProp = false) {
|
|
36
49
|
const actualEvents = this.events;
|
|
37
|
-
if (!this.matchEvents(expectedEvents)) {
|
|
50
|
+
if (!this.matchEvents(expectedEvents, inlineDetailsProp)) {
|
|
38
51
|
throw new Error(`${message}
|
|
39
52
|
expected:
|
|
40
53
|
${JSON.stringify(expectedEvents)}
|
|
@@ -47,18 +60,19 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
47
60
|
* Search events logged since the last time matchEvents was called, looking for any of the given
|
|
48
61
|
* expected events.
|
|
49
62
|
* @param expectedEvents - events that are expected to appear in the recorded log.
|
|
63
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
50
64
|
* These event objects may be subsets of the logged events.
|
|
51
65
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
52
66
|
* @returns if any of the expected events is found.
|
|
53
67
|
*/
|
|
54
|
-
matchAnyEvent(expectedEvents) {
|
|
55
|
-
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);
|
|
68
|
+
matchAnyEvent(expectedEvents, inlineDetailsProp = false) {
|
|
69
|
+
const matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents, inlineDetailsProp);
|
|
56
70
|
return matchedExpectedEventCount > 0;
|
|
57
71
|
}
|
|
58
72
|
/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */
|
|
59
|
-
assertMatchAny(expectedEvents, message) {
|
|
73
|
+
assertMatchAny(expectedEvents, message, inlineDetailsProp = false) {
|
|
60
74
|
const actualEvents = this.events;
|
|
61
|
-
if (!this.matchAnyEvent(expectedEvents)) {
|
|
75
|
+
if (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {
|
|
62
76
|
throw new Error(`${message}
|
|
63
77
|
expected:
|
|
64
78
|
${JSON.stringify(expectedEvents)}
|
|
@@ -71,16 +85,18 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
71
85
|
* Search events logged since the last time matchEvents was called, looking only for the given expected
|
|
72
86
|
* events in order.
|
|
73
87
|
* @param expectedEvents - events in order that are expected to be the only events in the recorded log.
|
|
88
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
74
89
|
* These event objects may be subsets of the logged events.
|
|
75
90
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
76
91
|
*/
|
|
77
|
-
matchEventStrict(expectedEvents) {
|
|
78
|
-
return expectedEvents.length === this.events.length &&
|
|
92
|
+
matchEventStrict(expectedEvents, inlineDetailsProp = false) {
|
|
93
|
+
return (expectedEvents.length === this.events.length &&
|
|
94
|
+
this.matchEvents(expectedEvents, inlineDetailsProp));
|
|
79
95
|
}
|
|
80
96
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
81
|
-
assertMatchStrict(expectedEvents, message) {
|
|
97
|
+
assertMatchStrict(expectedEvents, message, inlineDetailsProp = false) {
|
|
82
98
|
const actualEvents = this.events;
|
|
83
|
-
if (!this.matchEventStrict(expectedEvents)) {
|
|
99
|
+
if (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {
|
|
84
100
|
throw new Error(`${message}
|
|
85
101
|
expected:
|
|
86
102
|
${JSON.stringify(expectedEvents)}
|
|
@@ -90,9 +106,9 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
90
106
|
}
|
|
91
107
|
}
|
|
92
108
|
/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */
|
|
93
|
-
assertMatchNone(disallowedEvents, message) {
|
|
109
|
+
assertMatchNone(disallowedEvents, message, inlineDetailsProp = false) {
|
|
94
110
|
const actualEvents = this.events;
|
|
95
|
-
if (this.matchAnyEvent(disallowedEvents)) {
|
|
111
|
+
if (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {
|
|
96
112
|
throw new Error(`${message}
|
|
97
113
|
disallowed events:
|
|
98
114
|
${JSON.stringify(disallowedEvents)}
|
|
@@ -101,11 +117,11 @@ actual:
|
|
|
101
117
|
${JSON.stringify(actualEvents)}`);
|
|
102
118
|
}
|
|
103
119
|
}
|
|
104
|
-
getMatchedEventsCount(expectedEvents) {
|
|
120
|
+
getMatchedEventsCount(expectedEvents, inlineDetailsProp) {
|
|
105
121
|
let iExpectedEvent = 0;
|
|
106
122
|
this.events.forEach((event) => {
|
|
107
123
|
if (iExpectedEvent < expectedEvents.length &&
|
|
108
|
-
MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent])) {
|
|
124
|
+
MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)) {
|
|
109
125
|
// We found the next expected event; increment
|
|
110
126
|
++iExpectedEvent;
|
|
111
127
|
}
|
|
@@ -118,9 +134,19 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
118
134
|
/**
|
|
119
135
|
* Ensure the expected event is a strict subset of the actual event
|
|
120
136
|
*/
|
|
121
|
-
static eventsMatch(actual, expected) {
|
|
122
|
-
const
|
|
123
|
-
|
|
137
|
+
static eventsMatch(actual, expected, inlineDetailsProp) {
|
|
138
|
+
const { details } = actual, actualForMatching = __rest(actual, ["details"]);
|
|
139
|
+
let detailsExpanded = { details };
|
|
140
|
+
// "details" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.
|
|
141
|
+
// Some of the properties in the expected event may be inside "details". So, if inlineDetailsProp is true,
|
|
142
|
+
// extract the properties from "details" in the actual event and inline them in the actual event.
|
|
143
|
+
if (inlineDetailsProp && details !== undefined) {
|
|
144
|
+
assert(typeof details === "string", 0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */);
|
|
145
|
+
detailsExpanded = JSON.parse(details);
|
|
146
|
+
}
|
|
147
|
+
const actualExpanded = Object.assign(Object.assign({}, actualForMatching), detailsExpanded);
|
|
148
|
+
const masked = Object.assign(Object.assign({}, actualExpanded), expected);
|
|
149
|
+
return JSON.stringify(masked) === JSON.stringify(actualExpanded);
|
|
124
150
|
}
|
|
125
151
|
}
|
|
126
152
|
//# sourceMappingURL=mockLogger.js.map
|
package/lib/mockLogger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockLogger.js","sourceRoot":"","sources":["../src/mockLogger.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\nimport { ITelemetryLogger, ITelemetryBaseEvent } from \"@fluidframework/common-definitions\";\nimport { TelemetryLogger } from \"./logger\";\n\n/**\n * The MockLogger records events sent to it, and then can walk back over those events\n * searching for a set of expected events to match against the logged events.\n */\nexport class MockLogger extends TelemetryLogger implements ITelemetryLogger {\n\tevents: ITelemetryBaseEvent[] = [];\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tclear() {\n\t\tthis.events = [];\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tthis.events.push(event);\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to appear in the recorded log.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEvents(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[]): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);\n\t\t// How many expected events were left over? Hopefully none.\n\t\tconst unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;\n\t\treturn unmatchedExpectedEventCount === 0;\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatch(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[], message?: string) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEvents(expectedEvents)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for any of the given\n\t * expected events.\n\t * @param expectedEvents - events that are expected to appear in the recorded log.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t * @returns if any of the expected events is found.\n\t */\n\tmatchAnyEvent(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[]): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(expectedEvents);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */\n\tassertMatchAny(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[], message?: string) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchAnyEvent(expectedEvents)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking only for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to be the only events in the recorded log.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEventStrict(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[]): boolean {\n\t\treturn expectedEvents.length === this.events.length && this.matchEvents(expectedEvents);\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatchStrict(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[], message?: string) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEventStrict(expectedEvents)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */\n\tassertMatchNone(disallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[], message?: string) {\n\t\tconst actualEvents = this.events;\n\t\tif (this.matchAnyEvent(disallowedEvents)) {\n\t\t\tthrow new Error(`${message}\ndisallowed events:\n${JSON.stringify(disallowedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\tprivate getMatchedEventsCount(expectedEvents: Omit<ITelemetryBaseEvent, \"category\">[]): number {\n\t\tlet iExpectedEvent = 0;\n\t\tthis.events.forEach((event) => {\n\t\t\tif (\n\t\t\t\tiExpectedEvent < expectedEvents.length &&\n\t\t\t\tMockLogger.eventsMatch(event, expectedEvents[iExpectedEvent])\n\t\t\t) {\n\t\t\t\t// We found the next expected event; increment\n\t\t\t\t++iExpectedEvent;\n\t\t\t}\n\t\t});\n\n\t\t// Remove the events so far; next call will just compare subsequent events from here\n\t\tthis.events = [];\n\n\t\t// Return the count of matched events.\n\t\treturn iExpectedEvent;\n\t}\n\n\t/**\n\t * Ensure the expected event is a strict subset of the actual event\n\t */\n\tprivate static eventsMatch(\n\t\tactual: ITelemetryBaseEvent,\n\t\texpected: Omit<ITelemetryBaseEvent, \"category\">,\n\t): boolean {\n\t\tconst masked = { ...actual, ...expected };\n\t\treturn JSON.stringify(masked) === JSON.stringify(actual);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mockLogger.js","sourceRoot":"","sources":["../src/mockLogger.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\nimport { ITelemetryLogger, ITelemetryBaseEvent } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { TelemetryLogger } from \"./logger\";\n\n/**\n * The MockLogger records events sent to it, and then can walk back over those events\n * searching for a set of expected events to match against the logged events.\n */\nexport class MockLogger extends TelemetryLogger implements ITelemetryLogger {\n\tevents: ITelemetryBaseEvent[] = [];\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tclear() {\n\t\tthis.events = [];\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tthis.events.push(event);\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEvents(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\t// How many expected events were left over? Hopefully none.\n\t\tconst unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;\n\t\treturn unmatchedExpectedEventCount === 0;\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatch(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEvents(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for any of the given\n\t * expected events.\n\t * @param expectedEvents - events that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t * @returns if any of the expected events is found.\n\t */\n\tmatchAnyEvent(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */\n\tassertMatchAny(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking only for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to be the only events in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEventStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\treturn (\n\t\t\texpectedEvents.length === this.events.length &&\n\t\t\tthis.matchEvents(expectedEvents, inlineDetailsProp)\n\t\t);\n\t}\n\n\t/** Asserts that matchEvents is true, and prints the actual/expected output if not */\n\tassertMatchStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */\n\tassertMatchNone(\n\t\tdisallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t) {\n\t\tconst actualEvents = this.events;\n\t\tif (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\ndisallowed events:\n${JSON.stringify(disallowedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\tprivate getMatchedEventsCount(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean,\n\t): number {\n\t\tlet iExpectedEvent = 0;\n\t\tthis.events.forEach((event) => {\n\t\t\tif (\n\t\t\t\tiExpectedEvent < expectedEvents.length &&\n\t\t\t\tMockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)\n\t\t\t) {\n\t\t\t\t// We found the next expected event; increment\n\t\t\t\t++iExpectedEvent;\n\t\t\t}\n\t\t});\n\n\t\t// Remove the events so far; next call will just compare subsequent events from here\n\t\tthis.events = [];\n\n\t\t// Return the count of matched events.\n\t\treturn iExpectedEvent;\n\t}\n\n\t/**\n\t * Ensure the expected event is a strict subset of the actual event\n\t */\n\tprivate static eventsMatch(\n\t\tactual: ITelemetryBaseEvent,\n\t\texpected: Omit<ITelemetryBaseEvent, \"category\">,\n\t\tinlineDetailsProp: boolean,\n\t): boolean {\n\t\tconst { details, ...actualForMatching } = actual;\n\t\tlet detailsExpanded = { details };\n\t\t// \"details\" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.\n\t\t// Some of the properties in the expected event may be inside \"details\". So, if inlineDetailsProp is true,\n\t\t// extract the properties from \"details\" in the actual event and inline them in the actual event.\n\t\tif (inlineDetailsProp && details !== undefined) {\n\t\t\tassert(\n\t\t\t\ttypeof details === \"string\",\n\t\t\t\t0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */,\n\t\t\t);\n\t\t\tdetailsExpanded = JSON.parse(details);\n\t\t}\n\t\tconst actualExpanded: ITelemetryBaseEvent = { ...actualForMatching, ...detailsExpanded };\n\t\tconst masked = { ...actualExpanded, ...expected };\n\t\treturn JSON.stringify(masked) === JSON.stringify(actualExpanded);\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/telemetry-utils",
|
|
3
|
-
"version": "2.0.0-internal.4.
|
|
3
|
+
"version": "2.0.0-internal.4.4.0",
|
|
4
4
|
"description": "Collection of telemetry relates utilities for Fluid",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@fluidframework/build-common": "^1.1.0",
|
|
51
51
|
"@fluidframework/build-tools": "^0.17.0",
|
|
52
52
|
"@fluidframework/eslint-config-fluid": "^2.0.0",
|
|
53
|
-
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.4.
|
|
53
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.4.4.0 <2.0.0-internal.4.5.0",
|
|
54
54
|
"@fluidframework/telemetry-utils-previous": "npm:@fluidframework/telemetry-utils@2.0.0-internal.4.1.0",
|
|
55
55
|
"@microsoft/api-extractor": "^7.34.4",
|
|
56
56
|
"@types/debug": "^4.1.5",
|
|
@@ -76,14 +76,13 @@
|
|
|
76
76
|
"broken": {}
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|
|
79
|
-
"build": "
|
|
79
|
+
"build": "concurrently npm:build:compile npm:lint && npm run build:docs",
|
|
80
80
|
"build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
|
|
81
81
|
"build:compile": "concurrently npm:build:commonjs npm:build:esnext",
|
|
82
82
|
"build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
|
|
83
83
|
"build:esnext": "tsc --project ./tsconfig.esnext.json",
|
|
84
84
|
"build:full": "npm run build",
|
|
85
85
|
"build:full:compile": "npm run build:compile",
|
|
86
|
-
"build:genver": "gen-version",
|
|
87
86
|
"build:test": "tsc --project ./src/test/tsconfig.json",
|
|
88
87
|
"bump-version": "npm version minor --no-push --no-git-tag-version && npm run build:genver",
|
|
89
88
|
"ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
|
package/src/mockLogger.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { ITelemetryLogger, ITelemetryBaseEvent } from "@fluidframework/common-definitions";
|
|
7
|
+
import { assert } from "@fluidframework/common-utils";
|
|
7
8
|
import { TelemetryLogger } from "./logger";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -29,20 +30,31 @@ export class MockLogger extends TelemetryLogger implements ITelemetryLogger {
|
|
|
29
30
|
* Search events logged since the last time matchEvents was called, looking for the given expected
|
|
30
31
|
* events in order.
|
|
31
32
|
* @param expectedEvents - events in order that are expected to appear in the recorded log.
|
|
33
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
32
34
|
* These event objects may be subsets of the logged events.
|
|
33
35
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
34
36
|
*/
|
|
35
|
-
matchEvents(
|
|
36
|
-
|
|
37
|
+
matchEvents(
|
|
38
|
+
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
39
|
+
inlineDetailsProp: boolean = false,
|
|
40
|
+
): boolean {
|
|
41
|
+
const matchedExpectedEventCount = this.getMatchedEventsCount(
|
|
42
|
+
expectedEvents,
|
|
43
|
+
inlineDetailsProp,
|
|
44
|
+
);
|
|
37
45
|
// How many expected events were left over? Hopefully none.
|
|
38
46
|
const unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;
|
|
39
47
|
return unmatchedExpectedEventCount === 0;
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
43
|
-
assertMatch(
|
|
51
|
+
assertMatch(
|
|
52
|
+
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
53
|
+
message?: string,
|
|
54
|
+
inlineDetailsProp: boolean = false,
|
|
55
|
+
) {
|
|
44
56
|
const actualEvents = this.events;
|
|
45
|
-
if (!this.matchEvents(expectedEvents)) {
|
|
57
|
+
if (!this.matchEvents(expectedEvents, inlineDetailsProp)) {
|
|
46
58
|
throw new Error(`${message}
|
|
47
59
|
expected:
|
|
48
60
|
${JSON.stringify(expectedEvents)}
|
|
@@ -56,19 +68,30 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
56
68
|
* Search events logged since the last time matchEvents was called, looking for any of the given
|
|
57
69
|
* expected events.
|
|
58
70
|
* @param expectedEvents - events that are expected to appear in the recorded log.
|
|
71
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
59
72
|
* These event objects may be subsets of the logged events.
|
|
60
73
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
61
74
|
* @returns if any of the expected events is found.
|
|
62
75
|
*/
|
|
63
|
-
matchAnyEvent(
|
|
64
|
-
|
|
76
|
+
matchAnyEvent(
|
|
77
|
+
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
78
|
+
inlineDetailsProp: boolean = false,
|
|
79
|
+
): boolean {
|
|
80
|
+
const matchedExpectedEventCount = this.getMatchedEventsCount(
|
|
81
|
+
expectedEvents,
|
|
82
|
+
inlineDetailsProp,
|
|
83
|
+
);
|
|
65
84
|
return matchedExpectedEventCount > 0;
|
|
66
85
|
}
|
|
67
86
|
|
|
68
87
|
/** Asserts that matchAnyEvent is true, and prints the actual/expected output if not */
|
|
69
|
-
assertMatchAny(
|
|
88
|
+
assertMatchAny(
|
|
89
|
+
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
90
|
+
message?: string,
|
|
91
|
+
inlineDetailsProp: boolean = false,
|
|
92
|
+
) {
|
|
70
93
|
const actualEvents = this.events;
|
|
71
|
-
if (!this.matchAnyEvent(expectedEvents)) {
|
|
94
|
+
if (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {
|
|
72
95
|
throw new Error(`${message}
|
|
73
96
|
expected:
|
|
74
97
|
${JSON.stringify(expectedEvents)}
|
|
@@ -82,17 +105,28 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
82
105
|
* Search events logged since the last time matchEvents was called, looking only for the given expected
|
|
83
106
|
* events in order.
|
|
84
107
|
* @param expectedEvents - events in order that are expected to be the only events in the recorded log.
|
|
108
|
+
* @param inlineDetailsProp - true if the "details" property in the actual event should be extracted and inlined.
|
|
85
109
|
* These event objects may be subsets of the logged events.
|
|
86
110
|
* Note: category is omitted from the type because it's usually uninteresting and tedious to type.
|
|
87
111
|
*/
|
|
88
|
-
matchEventStrict(
|
|
89
|
-
|
|
112
|
+
matchEventStrict(
|
|
113
|
+
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
114
|
+
inlineDetailsProp: boolean = false,
|
|
115
|
+
): boolean {
|
|
116
|
+
return (
|
|
117
|
+
expectedEvents.length === this.events.length &&
|
|
118
|
+
this.matchEvents(expectedEvents, inlineDetailsProp)
|
|
119
|
+
);
|
|
90
120
|
}
|
|
91
121
|
|
|
92
122
|
/** Asserts that matchEvents is true, and prints the actual/expected output if not */
|
|
93
|
-
assertMatchStrict(
|
|
123
|
+
assertMatchStrict(
|
|
124
|
+
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
125
|
+
message?: string,
|
|
126
|
+
inlineDetailsProp: boolean = false,
|
|
127
|
+
) {
|
|
94
128
|
const actualEvents = this.events;
|
|
95
|
-
if (!this.matchEventStrict(expectedEvents)) {
|
|
129
|
+
if (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {
|
|
96
130
|
throw new Error(`${message}
|
|
97
131
|
expected:
|
|
98
132
|
${JSON.stringify(expectedEvents)}
|
|
@@ -103,9 +137,13 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
103
137
|
}
|
|
104
138
|
|
|
105
139
|
/** Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not */
|
|
106
|
-
assertMatchNone(
|
|
140
|
+
assertMatchNone(
|
|
141
|
+
disallowedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
142
|
+
message?: string,
|
|
143
|
+
inlineDetailsProp: boolean = false,
|
|
144
|
+
) {
|
|
107
145
|
const actualEvents = this.events;
|
|
108
|
-
if (this.matchAnyEvent(disallowedEvents)) {
|
|
146
|
+
if (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {
|
|
109
147
|
throw new Error(`${message}
|
|
110
148
|
disallowed events:
|
|
111
149
|
${JSON.stringify(disallowedEvents)}
|
|
@@ -115,12 +153,15 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
115
153
|
}
|
|
116
154
|
}
|
|
117
155
|
|
|
118
|
-
private getMatchedEventsCount(
|
|
156
|
+
private getMatchedEventsCount(
|
|
157
|
+
expectedEvents: Omit<ITelemetryBaseEvent, "category">[],
|
|
158
|
+
inlineDetailsProp: boolean,
|
|
159
|
+
): number {
|
|
119
160
|
let iExpectedEvent = 0;
|
|
120
161
|
this.events.forEach((event) => {
|
|
121
162
|
if (
|
|
122
163
|
iExpectedEvent < expectedEvents.length &&
|
|
123
|
-
MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent])
|
|
164
|
+
MockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)
|
|
124
165
|
) {
|
|
125
166
|
// We found the next expected event; increment
|
|
126
167
|
++iExpectedEvent;
|
|
@@ -140,8 +181,22 @@ ${JSON.stringify(actualEvents)}`);
|
|
|
140
181
|
private static eventsMatch(
|
|
141
182
|
actual: ITelemetryBaseEvent,
|
|
142
183
|
expected: Omit<ITelemetryBaseEvent, "category">,
|
|
184
|
+
inlineDetailsProp: boolean,
|
|
143
185
|
): boolean {
|
|
144
|
-
const
|
|
145
|
-
|
|
186
|
+
const { details, ...actualForMatching } = actual;
|
|
187
|
+
let detailsExpanded = { details };
|
|
188
|
+
// "details" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.
|
|
189
|
+
// Some of the properties in the expected event may be inside "details". So, if inlineDetailsProp is true,
|
|
190
|
+
// extract the properties from "details" in the actual event and inline them in the actual event.
|
|
191
|
+
if (inlineDetailsProp && details !== undefined) {
|
|
192
|
+
assert(
|
|
193
|
+
typeof details === "string",
|
|
194
|
+
0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */,
|
|
195
|
+
);
|
|
196
|
+
detailsExpanded = JSON.parse(details);
|
|
197
|
+
}
|
|
198
|
+
const actualExpanded: ITelemetryBaseEvent = { ...actualForMatching, ...detailsExpanded };
|
|
199
|
+
const masked = { ...actualExpanded, ...expected };
|
|
200
|
+
return JSON.stringify(masked) === JSON.stringify(actualExpanded);
|
|
146
201
|
}
|
|
147
202
|
}
|
package/dist/packageVersion.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*
|
|
5
|
-
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
|
-
*/
|
|
7
|
-
export declare const pkgName = "@fluidframework/telemetry-utils";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-internal.4.2.1";
|
|
9
|
-
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,oCAAoC,CAAC;AACzD,eAAO,MAAM,UAAU,yBAAyB,CAAC"}
|
package/dist/packageVersion.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*!
|
|
3
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
-
* Licensed under the MIT License.
|
|
5
|
-
*
|
|
6
|
-
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.pkgVersion = exports.pkgName = void 0;
|
|
10
|
-
exports.pkgName = "@fluidframework/telemetry-utils";
|
|
11
|
-
exports.pkgVersion = "2.0.0-internal.4.2.1";
|
|
12
|
-
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,iCAAiC,CAAC;AAC5C,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/telemetry-utils\";\nexport const pkgVersion = \"2.0.0-internal.4.2.1\";\n"]}
|
package/lib/packageVersion.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*
|
|
5
|
-
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
|
-
*/
|
|
7
|
-
export declare const pkgName = "@fluidframework/telemetry-utils";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-internal.4.2.1";
|
|
9
|
-
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,oCAAoC,CAAC;AACzD,eAAO,MAAM,UAAU,yBAAyB,CAAC"}
|
package/lib/packageVersion.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*
|
|
5
|
-
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
|
-
*/
|
|
7
|
-
export const pkgName = "@fluidframework/telemetry-utils";
|
|
8
|
-
export const pkgVersion = "2.0.0-internal.4.2.1";
|
|
9
|
-
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,iCAAiC,CAAC;AACzD,MAAM,CAAC,MAAM,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/telemetry-utils\";\nexport const pkgVersion = \"2.0.0-internal.4.2.1\";\n"]}
|
package/src/packageVersion.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*
|
|
5
|
-
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export const pkgName = "@fluidframework/telemetry-utils";
|
|
9
|
-
export const pkgVersion = "2.0.0-internal.4.2.1";
|