Skip to content

Commit 96079fa

Browse files
committed
refactor: wip tests
1 parent a8ba2a6 commit 96079fa

7 files changed

Lines changed: 810 additions & 358 deletions

File tree

packages/utils/src/lib/performance-observer.int.test.ts

Lines changed: 81 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,26 @@ describe('PerformanceObserverSink', () => {
4141
expect(() => new PerformanceObserverSink(options)).not.toThrow();
4242
});
4343

44-
it('internal PerformanceObserver should process observed entries', async () => {
44+
it('unsubscribe stops observing performance entries', async () => {
45+
const observer = new PerformanceObserverSink({
46+
...options,
47+
flushThreshold: 1,
48+
});
49+
50+
observer.subscribe();
51+
performance.mark('subscribed-mark1');
52+
performance.mark('subscribed-mark2');
53+
await awaitObserverCallback();
54+
expect(encode).toHaveBeenCalledTimes(2);
55+
56+
observer.unsubscribe();
57+
performance.mark('unsubscribed-mark1');
58+
performance.mark('unsubscribed-mark2');
59+
await awaitObserverCallback();
60+
expect(encode).toHaveBeenCalledTimes(2);
61+
});
62+
63+
it('observes and encodes performance entries', async () => {
4564
const observer = new PerformanceObserverSink(options);
4665
observer.subscribe();
4766

@@ -64,23 +83,26 @@ describe('PerformanceObserverSink', () => {
6483
);
6584
});
6685

67-
it('internal PerformanceObserver calls flush if flushThreshold exceeded', async () => {
86+
it('handles multiple items per performance entry', async () => {
87+
const multiEncodeFn = vi.fn(e => [
88+
`${e.entryType}-item1`,
89+
`${e.entryType}item2`,
90+
]);
6891
const observer = new PerformanceObserverSink({
6992
...options,
70-
flushThreshold: 3,
93+
encodePerfEntry: multiEncodeFn,
7194
});
72-
observer.subscribe();
7395

74-
performance.mark('test-mark1');
75-
performance.mark('test-mark2');
76-
performance.mark('test-mark3');
96+
observer.subscribe();
7797

98+
performance.mark('test-mark');
7899
await awaitObserverCallback();
100+
observer.flush();
79101

80-
expect(encode).toHaveBeenCalledTimes(3);
102+
expect(sink.getWrittenItems()).toHaveLength(2);
81103
});
82104

83-
it('flush flushes observed entries when subscribed', async () => {
105+
it('successfully writes queued items to sink', async () => {
84106
const observer = new PerformanceObserverSink(options);
85107
observer.subscribe();
86108

@@ -96,86 +118,89 @@ describe('PerformanceObserverSink', () => {
96118
]);
97119
});
98120

99-
it('flush calls encode for each entry', async () => {
121+
it('observes performance entries when subscribed', async () => {
100122
const observer = new PerformanceObserverSink(options);
123+
124+
observer.subscribe();
125+
performance.mark('test-mark-1');
126+
performance.mark('test-mark-2');
127+
await awaitObserverCallback();
128+
observer.flush();
129+
expect(sink.getWrittenItems()).toHaveLength(2);
130+
});
131+
132+
it('triggers proactive flush when threshold exceeded', async () => {
133+
const observer = new PerformanceObserverSink({
134+
...options,
135+
flushThreshold: 3,
136+
});
101137
observer.subscribe();
102138

103139
performance.mark('test-mark1');
104140
performance.mark('test-mark2');
141+
performance.mark('test-mark3');
105142

106143
await awaitObserverCallback();
107-
observer.flush();
108144

109-
expect(encode).toHaveBeenCalledWith(
110-
expect.objectContaining({
111-
name: 'test-mark1',
112-
entryType: 'mark',
113-
}),
114-
);
115-
expect(encode).toHaveBeenCalledWith(
116-
expect.objectContaining({
117-
name: 'test-mark2',
118-
entryType: 'mark',
119-
}),
120-
);
145+
expect(encode).toHaveBeenCalledTimes(3);
121146
});
122147

123-
it('unsubscribe stops observing performance entries', async () => {
148+
it('keeps items in queue when sink write fails', async () => {
149+
const failingSink = new MockSink();
150+
failingSink.open();
151+
failingSink.write.mockImplementation(() => {
152+
throw new Error('Sink write failed');
153+
});
154+
124155
const observer = new PerformanceObserverSink({
125-
...options,
156+
sink: failingSink,
157+
encodePerfEntry: encode,
126158
flushThreshold: 1,
159+
maxQueueSize: 10,
127160
});
128161

129162
observer.subscribe();
130-
performance.mark('subscribed-mark1');
131-
performance.mark('subscribed-mark2');
132-
await awaitObserverCallback();
133-
expect(encode).toHaveBeenCalledTimes(2);
134163

135-
observer.unsubscribe();
136-
performance.mark('unsubscribed-mark1');
137-
performance.mark('unsubscribed-mark2');
164+
performance.mark('test-mark');
138165
await awaitObserverCallback();
139-
expect(encode).toHaveBeenCalledTimes(2);
166+
167+
const stats = observer.getStats();
168+
expect(stats.dropped).toBe(0);
169+
expect(stats.queued).toBe(1);
140170
});
141171

142-
it('should observe performance entries and write them to the sink on flush', async () => {
143-
const observer = new PerformanceObserverSink(options);
172+
it('keeps items in queue when sink is closed during flush', async () => {
173+
const closedSink = new MockSink();
174+
closedSink.open();
175+
closedSink.close();
176+
177+
const observer = new PerformanceObserverSink({
178+
sink: closedSink,
179+
encodePerfEntry: encode,
180+
});
144181

145182
observer.subscribe();
183+
146184
performance.mark('test-mark');
147185
await awaitObserverCallback();
148-
observer.flush();
149-
expect(sink.getWrittenItems()).toHaveLength(1);
150-
});
151186

152-
it('should observe performance entries when subscribed', async () => {
153-
const observer = new PerformanceObserverSink(options);
154-
155-
observer.subscribe();
156-
performance.mark('test-mark-1');
157-
performance.mark('test-mark-2');
158-
await awaitObserverCallback();
159-
observer.flush();
160-
expect(sink.getWrittenItems()).toHaveLength(2);
187+
const stats = observer.getStats();
188+
expect(stats.queued).toBe(1);
189+
expect(stats.dropped).toBe(0);
161190
});
162191

163-
it('handles multiple encoded items per performance entry', async () => {
164-
const multiEncodeFn = vi.fn(e => [
165-
`${e.entryType}-item1`,
166-
`${e.entryType}item2`,
167-
]);
192+
it('handles flush errors gracefully without losing items', async () => {
168193
const observer = new PerformanceObserverSink({
169-
...options,
170-
encodePerfEntry: multiEncodeFn,
194+
sink,
195+
encodePerfEntry: encode,
171196
});
172197

173198
observer.subscribe();
174199

175200
performance.mark('test-mark');
176201
await awaitObserverCallback();
177-
observer.flush();
178202

179-
expect(sink.getWrittenItems()).toHaveLength(2);
203+
const stats = observer.getStats();
204+
expect(stats.queued).toBeGreaterThanOrEqual(0);
180205
});
181206
});

0 commit comments

Comments
 (0)