Skip to content

Commit d7d67e1

Browse files
committed
Use snapshots and work with arrays
1 parent 044e3df commit d7d67e1

File tree

3 files changed

+596
-115
lines changed

3 files changed

+596
-115
lines changed

src/PatchResolver.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
import { parseMultipartHttp } from './parseMultipartHttp';
22

3+
function insertPatch(obj, path, data) {
4+
if (Array.isArray(obj) && typeof path === 'number') {
5+
return [].concat(obj.slice(0, path), [data], obj.slice(path + 1));
6+
} else {
7+
return {
8+
...obj,
9+
[path]: data,
10+
};
11+
}
12+
}
13+
314
// recursive function to apply the patch to the previous response
415
function applyPatch(previousResponse, patchPath, patchData) {
516
const [nextPath, ...rest] = patchPath;
617
if (rest.length === 0) {
7-
return {
8-
...previousResponse,
9-
[nextPath]: patchData,
10-
};
18+
return insertPatch(previousResponse, nextPath, patchData);
1119
}
12-
return {
13-
...previousResponse,
14-
[nextPath]: applyPatch(previousResponse[nextPath], rest, patchData),
15-
};
20+
return insertPatch(
21+
previousResponse,
22+
nextPath,
23+
applyPatch(previousResponse[nextPath], rest, patchData)
24+
);
1625
}
1726

1827
function mergeErrors(previousErrors, patchErrors) {

src/__test__/PatchResolver.spec.js

Lines changed: 33 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ const chunk1 = [
88
'',
99
'---',
1010
'Content-Type: application/json',
11-
'Content-Length: 64',
11+
'Content-Length: 142',
1212
'',
13-
'{"data":{"viewer":{"currencies":null,"user":{"profile":null}}}}\n',
13+
'{"data":{"viewer":{"currencies":null,"user":{"profile":null,"items":{"edges":[{"node":{"isFavorite":null}},{"node":{"isFavorite":null}}]}}}}}\n',
1414
].join('\r\n');
1515

1616
const chunk1error = [
@@ -47,6 +47,15 @@ const chunk3 = [
4747
'Content-Length: 76',
4848
'',
4949
'{"path":["viewer","user","profile"],"data":{"displayName":"Steven Seagal"}}\n',
50+
].join('\r\n');
51+
52+
const chunk4 = [
53+
'',
54+
'---',
55+
'Content-Type: application/json',
56+
'Content-Length: 78',
57+
'',
58+
'{"data":false,"path":["viewer","user","items","edges",1,"node","isFavorite"]}\n',
5059
'',
5160
'-----\r\n',
5261
].join('\r\n');
@@ -59,29 +68,19 @@ describe('PathResolver', function() {
5968
});
6069

6170
resolver.handleChunk(chunk1);
62-
expect(onResponse).toHaveBeenCalledWith({
63-
data: { viewer: { currencies: null, user: { profile: null } } },
64-
});
71+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
72+
6573
onResponse.mockClear();
6674
resolver.handleChunk(chunk2);
67-
expect(onResponse).toHaveBeenCalledWith({
68-
data: {
69-
viewer: {
70-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
71-
user: { profile: null },
72-
},
73-
},
74-
});
75+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
76+
7577
onResponse.mockClear();
7678
resolver.handleChunk(chunk3);
77-
expect(onResponse).toHaveBeenCalledWith({
78-
data: {
79-
viewer: {
80-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
81-
user: { profile: { displayName: 'Steven Seagal' } },
82-
},
83-
},
84-
});
79+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
80+
81+
onResponse.mockClear();
82+
resolver.handleChunk(chunk4);
83+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
8584
});
8685

8786
it('should work when chunks are split', function() {
@@ -90,8 +89,6 @@ describe('PathResolver', function() {
9089
onResponse,
9190
});
9291

93-
console.log('chunk1.length', chunk1.length);
94-
9592
const chunk1a = chunk1.substr(0, 35);
9693
const chunk1b = chunk1.substr(35, 80);
9794
const chunk1c = chunk1.substr(35 + 80);
@@ -101,9 +98,7 @@ describe('PathResolver', function() {
10198
resolver.handleChunk(chunk1b);
10299
expect(onResponse).not.toHaveBeenCalled();
103100
resolver.handleChunk(chunk1c);
104-
expect(onResponse).toHaveBeenCalledWith({
105-
data: { viewer: { currencies: null, user: { profile: null } } },
106-
});
101+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
107102
onResponse.mockClear();
108103

109104
const chunk2a = chunk2.substr(0, 35);
@@ -112,14 +107,7 @@ describe('PathResolver', function() {
112107
resolver.handleChunk(chunk2a);
113108
expect(onResponse).not.toHaveBeenCalled();
114109
resolver.handleChunk(chunk2b);
115-
expect(onResponse).toHaveBeenCalledWith({
116-
data: {
117-
viewer: {
118-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
119-
user: { profile: null },
120-
},
121-
},
122-
});
110+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
123111
onResponse.mockClear();
124112

125113
const chunk3a = chunk3.substr(0, 10);
@@ -131,14 +119,7 @@ describe('PathResolver', function() {
131119
resolver.handleChunk(chunk3b);
132120
expect(onResponse).not.toHaveBeenCalled();
133121
resolver.handleChunk(chunk3c);
134-
expect(onResponse).toHaveBeenCalledWith({
135-
data: {
136-
viewer: {
137-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
138-
user: { profile: { displayName: 'Steven Seagal' } },
139-
},
140-
},
141-
});
122+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
142123
});
143124

144125
it('should work when chunks are combined', function() {
@@ -148,17 +129,8 @@ describe('PathResolver', function() {
148129
});
149130

150131
resolver.handleChunk(chunk1 + chunk2);
151-
expect(onResponse.mock.calls[0][0]).toEqual({
152-
data: { viewer: { currencies: null, user: { profile: null } } },
153-
});
154-
expect(onResponse.mock.calls[1][0]).toEqual({
155-
data: {
156-
viewer: {
157-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
158-
user: { profile: null },
159-
},
160-
},
161-
});
132+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
133+
expect(onResponse.mock.calls[1][0]).toMatchSnapshot();
162134
});
163135

164136
it('should work when chunks are combined and split', function() {
@@ -172,30 +144,14 @@ describe('PathResolver', function() {
172144
const chunk3c = chunk3.substr(11 + 20);
173145

174146
resolver.handleChunk(chunk1 + chunk2 + chunk3a);
175-
expect(onResponse.mock.calls[0][0]).toEqual({
176-
data: { viewer: { currencies: null, user: { profile: null } } },
177-
});
178-
expect(onResponse.mock.calls[1][0]).toEqual({
179-
data: {
180-
viewer: {
181-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
182-
user: { profile: null },
183-
},
184-
},
185-
});
147+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
148+
expect(onResponse.mock.calls[1][0]).toMatchSnapshot();
186149
onResponse.mockClear();
187150

188151
resolver.handleChunk(chunk3b);
189152
expect(onResponse).not.toHaveBeenCalled();
190153
resolver.handleChunk(chunk3c);
191-
expect(onResponse).toHaveBeenCalledWith({
192-
data: {
193-
viewer: {
194-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
195-
user: { profile: { displayName: 'Steven Seagal' } },
196-
},
197-
},
198-
});
154+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
199155
});
200156

201157
it('should work when chunks are combined across boundaries', function() {
@@ -208,20 +164,10 @@ describe('PathResolver', function() {
208164
const chunk2b = chunk2.substring(35);
209165

210166
resolver.handleChunk(chunk1 + chunk2a);
211-
expect(onResponse).toHaveBeenCalledWith({
212-
data: { viewer: { currencies: null, user: { profile: null } } },
213-
});
167+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
214168
onResponse.mockClear();
215169
resolver.handleChunk(chunk2b);
216-
217-
expect(onResponse).toHaveBeenCalledWith({
218-
data: {
219-
viewer: {
220-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
221-
user: { profile: null },
222-
},
223-
},
224-
});
170+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
225171
});
226172

227173
it('should merge errors', function() {
@@ -231,32 +177,12 @@ describe('PathResolver', function() {
231177
});
232178

233179
resolver.handleChunk(chunk1error);
234-
expect(onResponse).toHaveBeenCalledWith({
235-
data: { viewer: { currencies: null, user: { profile: null } } },
236-
errors: [{ message: 'Very Bad Error' }],
237-
});
180+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
238181
onResponse.mockClear();
239182
resolver.handleChunk(chunk2error);
240-
expect(onResponse).toHaveBeenCalledWith({
241-
data: {
242-
viewer: {
243-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
244-
user: { profile: null },
245-
},
246-
},
247-
errors: [{ message: 'Very Bad Error' }, { message: 'Not So Bad Error' }],
248-
});
183+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
249184
onResponse.mockClear();
250185
resolver.handleChunk(chunk3);
251-
expect(onResponse).toHaveBeenCalledWith({
252-
data: {
253-
viewer: {
254-
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', '😂'],
255-
user: { profile: { displayName: 'Steven Seagal' } },
256-
},
257-
},
258-
errors: [{ message: 'Very Bad Error' }, { message: 'Not So Bad Error' }],
259-
});
186+
expect(onResponse.mock.calls[0][0]).toMatchSnapshot();
260187
});
261-
it('should work', function() {});
262188
});

0 commit comments

Comments
 (0)