@gasboost/client 0.1.0 → 0.1.1
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/LICENSE +21 -0
- package/README.md +386 -0
- package/dist/navigation/AppsScriptIframe.js +5 -4
- package/package.json +21 -1
- package/dist/AppsScriptJob.d.ts +0 -28
- package/dist/AppsScriptJob.js +0 -84
- package/dist/AppsScriptJobQueue.d.ts +0 -14
- package/dist/AppsScriptJobQueue.js +0 -40
- package/dist/AppsScriptJobRunner.d.ts +0 -20
- package/dist/AppsScriptJobRunner.js +0 -93
- package/dist/AppsScriptJobStore.d.ts +0 -7
- package/dist/AppsScriptJobStore.js +0 -9
- package/src/AppsScriptClient.ts +0 -81
- package/src/google.ts +0 -55
- package/src/index.ts +0 -4
- package/src/job/AppsScriptJob.ts +0 -85
- package/src/job/AppsScriptJobQueue.ts +0 -48
- package/src/job/AppsScriptJobRunner.ts +0 -107
- package/src/job/AppsScriptJobStore.ts +0 -16
- package/src/navigation/AppsScriptContainer.ts +0 -47
- package/src/navigation/AppsScriptHistoryPipeline.ts +0 -29
- package/src/navigation/AppsScriptIframe.ts +0 -63
- package/src/navigation/HashProperty.ts +0 -20
- package/src/navigation/NavigationEntry.ts +0 -82
- package/src/navigation/NavigationLocation.ts +0 -54
- package/tests/AppsScriptClient.spec.ts +0 -322
- package/tests/AppsScriptClient.type.spec.ts +0 -52
- package/tests/AppsScriptContainer.spec.ts +0 -502
- package/tests/AppsScriptHistoryPipeline.spec.ts +0 -303
- package/tests/AppsScriptIframe.spec.ts +0 -452
- package/tests/AppsScriptJob.spec.ts +0 -83
- package/tests/AppsScriptJobQueue.spec.ts +0 -125
- package/tests/AppsScriptJobRunner.spec.ts +0 -361
- package/tests/HashProperty.spec.ts +0 -29
- package/tests/NavigationEntry.spec.ts +0 -507
- package/tests/NavigationLocation.spec.ts +0 -189
- package/tests/setup.ts +0 -15
- package/tsconfig.build.json +0 -14
- package/tsconfig.json +0 -6
- package/vitest.config.mts +0 -8
|
@@ -1,502 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
google,
|
|
5
|
-
type GoogleScriptHistoryEvent,
|
|
6
|
-
type GoogleScriptUrlLocation,
|
|
7
|
-
} from "../src/google";
|
|
8
|
-
import { AppsScriptContainer } from "../src/navigation/AppsScriptContainer";
|
|
9
|
-
import { HashProperty } from "../src/navigation/HashProperty";
|
|
10
|
-
import { NavigationEntry } from "../src/navigation/NavigationEntry";
|
|
11
|
-
import { NavigationLocation } from "../src/navigation/NavigationLocation";
|
|
12
|
-
|
|
13
|
-
describe("AppsScriptContainer", () => {
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
vi.restoreAllMocks();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
describe("load", () => {
|
|
19
|
-
it("google.script.url.getLocation を使って現在のコンテナ状態を読み込める", () => {
|
|
20
|
-
const getLocation = vi
|
|
21
|
-
.spyOn(google.script.url, "getLocation")
|
|
22
|
-
.mockImplementation((callback) => {
|
|
23
|
-
callback({
|
|
24
|
-
hash: "/users",
|
|
25
|
-
parameter: {
|
|
26
|
-
page: "1",
|
|
27
|
-
},
|
|
28
|
-
parameters: {
|
|
29
|
-
page: ["1"],
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const callback = vi.fn();
|
|
35
|
-
|
|
36
|
-
AppsScriptContainer.load(callback);
|
|
37
|
-
|
|
38
|
-
expect(getLocation).toHaveBeenCalledOnce();
|
|
39
|
-
expect(callback).toHaveBeenCalledOnce();
|
|
40
|
-
|
|
41
|
-
const container = callback.mock.calls[0][0];
|
|
42
|
-
|
|
43
|
-
expect(container.current().location.hash.normalize()).toBe("#/users");
|
|
44
|
-
expect(container.current().location.searchParams.get("page")).toBe("1");
|
|
45
|
-
expect(container.current().state).toEqual({});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("複数値の query parameter を欠損せず読み込める", () => {
|
|
49
|
-
mockLocation({
|
|
50
|
-
hash: "/users",
|
|
51
|
-
parameter: {
|
|
52
|
-
tag: "react",
|
|
53
|
-
},
|
|
54
|
-
parameters: {
|
|
55
|
-
tag: ["react", "typescript"],
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
AppsScriptContainer.load((container) => {
|
|
60
|
-
expect(container.current().location.searchParams.getAll("tag")).toEqual(
|
|
61
|
-
["react", "typescript"],
|
|
62
|
-
);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe("observe", () => {
|
|
68
|
-
it("google.script.history.setChangeHandler でコンテナの変更監視を開始する", () => {
|
|
69
|
-
mockLocation();
|
|
70
|
-
|
|
71
|
-
const setChangeHandler = vi
|
|
72
|
-
.spyOn(google.script.history, "setChangeHandler")
|
|
73
|
-
.mockImplementation(() => {});
|
|
74
|
-
|
|
75
|
-
AppsScriptContainer.load((container) => {
|
|
76
|
-
container.observe(vi.fn());
|
|
77
|
-
|
|
78
|
-
expect(setChangeHandler).toHaveBeenCalledOnce();
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it("コンテナの history が変更された時に NavigationEntry を通知する", () => {
|
|
83
|
-
mockLocation();
|
|
84
|
-
|
|
85
|
-
let changeHandler:
|
|
86
|
-
| ((event: GoogleScriptHistoryEvent) => void)
|
|
87
|
-
| undefined;
|
|
88
|
-
|
|
89
|
-
vi.spyOn(google.script.history, "setChangeHandler").mockImplementation(
|
|
90
|
-
(handler) => {
|
|
91
|
-
changeHandler = handler;
|
|
92
|
-
},
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const observer = vi.fn();
|
|
96
|
-
|
|
97
|
-
AppsScriptContainer.load((container) => {
|
|
98
|
-
container.observe(observer);
|
|
99
|
-
|
|
100
|
-
changeHandler?.({
|
|
101
|
-
state: {
|
|
102
|
-
selectedUserId: "123",
|
|
103
|
-
},
|
|
104
|
-
location: {
|
|
105
|
-
hash: "/users/123",
|
|
106
|
-
parameter: {
|
|
107
|
-
page: "2",
|
|
108
|
-
},
|
|
109
|
-
parameters: {
|
|
110
|
-
page: ["2"],
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
expect(observer).toHaveBeenCalledOnce();
|
|
116
|
-
|
|
117
|
-
const entry = observer.mock.calls[0][0];
|
|
118
|
-
|
|
119
|
-
expect(entry.state).toEqual({
|
|
120
|
-
selectedUserId: "123",
|
|
121
|
-
});
|
|
122
|
-
expect(entry.location.hash.normalize()).toBe("#/users/123");
|
|
123
|
-
expect(entry.location.searchParams.get("page")).toBe("2");
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it("コンテナの history が変更された時に自身の現在状態も更新する", () => {
|
|
128
|
-
mockLocation();
|
|
129
|
-
|
|
130
|
-
let changeHandler:
|
|
131
|
-
| ((event: GoogleScriptHistoryEvent) => void)
|
|
132
|
-
| undefined;
|
|
133
|
-
|
|
134
|
-
vi.spyOn(google.script.history, "setChangeHandler").mockImplementation(
|
|
135
|
-
(handler) => {
|
|
136
|
-
changeHandler = handler;
|
|
137
|
-
},
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
AppsScriptContainer.load((container) => {
|
|
141
|
-
container.observe(vi.fn());
|
|
142
|
-
|
|
143
|
-
changeHandler?.({
|
|
144
|
-
state: {
|
|
145
|
-
selectedUserId: "456",
|
|
146
|
-
},
|
|
147
|
-
location: {
|
|
148
|
-
hash: "/settings",
|
|
149
|
-
parameter: {},
|
|
150
|
-
parameters: {},
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
expect(container.current().state).toEqual({
|
|
155
|
-
selectedUserId: "456",
|
|
156
|
-
});
|
|
157
|
-
expect(container.current().location.hash.normalize()).toBe(
|
|
158
|
-
"#/settings",
|
|
159
|
-
);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it("複数回変更された場合は最新の状態を保持する", () => {
|
|
164
|
-
mockLocation();
|
|
165
|
-
|
|
166
|
-
let changeHandler:
|
|
167
|
-
| ((event: GoogleScriptHistoryEvent) => void)
|
|
168
|
-
| undefined;
|
|
169
|
-
|
|
170
|
-
vi.spyOn(google.script.history, "setChangeHandler").mockImplementation(
|
|
171
|
-
(handler) => {
|
|
172
|
-
changeHandler = handler;
|
|
173
|
-
},
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
AppsScriptContainer.load((container) => {
|
|
177
|
-
container.observe(vi.fn());
|
|
178
|
-
|
|
179
|
-
changeHandler?.({
|
|
180
|
-
state: {},
|
|
181
|
-
location: {
|
|
182
|
-
hash: "/users",
|
|
183
|
-
parameter: {},
|
|
184
|
-
parameters: {},
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
changeHandler?.({
|
|
189
|
-
state: {},
|
|
190
|
-
location: {
|
|
191
|
-
hash: "/settings",
|
|
192
|
-
parameter: {},
|
|
193
|
-
parameters: {},
|
|
194
|
-
},
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
expect(container.current().location.hash.normalize()).toBe(
|
|
198
|
-
"#/settings",
|
|
199
|
-
);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
describe("sync", () => {
|
|
205
|
-
it("異なる NavigationEntry を受け取った場合は親コンテナの history に同期する", () => {
|
|
206
|
-
mockLocation({
|
|
207
|
-
hash: "/users",
|
|
208
|
-
parameter: {},
|
|
209
|
-
parameters: {},
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
const push = vi
|
|
213
|
-
.spyOn(google.script.history, "push")
|
|
214
|
-
.mockImplementation(() => {});
|
|
215
|
-
|
|
216
|
-
AppsScriptContainer.load((container) => {
|
|
217
|
-
container.sync(createEntry("#/settings"));
|
|
218
|
-
|
|
219
|
-
expect(push).toHaveBeenCalledOnce();
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
it("同期時に state を google.script.history.push に渡す", () => {
|
|
224
|
-
mockLocation();
|
|
225
|
-
|
|
226
|
-
const push = vi
|
|
227
|
-
.spyOn(google.script.history, "push")
|
|
228
|
-
.mockImplementation(() => {});
|
|
229
|
-
|
|
230
|
-
AppsScriptContainer.load((container) => {
|
|
231
|
-
container.sync(
|
|
232
|
-
new NavigationEntry(
|
|
233
|
-
{
|
|
234
|
-
selectedUserId: "123",
|
|
235
|
-
filters: {
|
|
236
|
-
active: true,
|
|
237
|
-
},
|
|
238
|
-
},
|
|
239
|
-
new NavigationLocation(
|
|
240
|
-
new HashProperty("#/users"),
|
|
241
|
-
new URLSearchParams(),
|
|
242
|
-
),
|
|
243
|
-
),
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
expect(push).toHaveBeenCalledWith(
|
|
247
|
-
{
|
|
248
|
-
selectedUserId: "123",
|
|
249
|
-
filters: {
|
|
250
|
-
active: true,
|
|
251
|
-
},
|
|
252
|
-
},
|
|
253
|
-
expect.anything(),
|
|
254
|
-
expect.anything(),
|
|
255
|
-
);
|
|
256
|
-
});
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
it("同期時に query parameter を google.script.history.push に渡す", () => {
|
|
260
|
-
mockLocation();
|
|
261
|
-
|
|
262
|
-
const push = vi
|
|
263
|
-
.spyOn(google.script.history, "push")
|
|
264
|
-
.mockImplementation(() => {});
|
|
265
|
-
|
|
266
|
-
AppsScriptContainer.load((container) => {
|
|
267
|
-
container.sync(
|
|
268
|
-
new NavigationEntry(
|
|
269
|
-
{},
|
|
270
|
-
new NavigationLocation(
|
|
271
|
-
new HashProperty("#/users"),
|
|
272
|
-
new URLSearchParams("page=2&tag=react&tag=typescript"),
|
|
273
|
-
),
|
|
274
|
-
),
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
expect(push).toHaveBeenCalledWith({}, expect.anything(), "#/users");
|
|
278
|
-
|
|
279
|
-
const params = push.mock.calls[0][1];
|
|
280
|
-
|
|
281
|
-
expect(params).toEqual({
|
|
282
|
-
page: ["2"],
|
|
283
|
-
tag: ["react", "typescript"],
|
|
284
|
-
});
|
|
285
|
-
});
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
it("同期時に正規化した hash を google.script.history.push に渡す", () => {
|
|
289
|
-
mockLocation();
|
|
290
|
-
|
|
291
|
-
const push = vi
|
|
292
|
-
.spyOn(google.script.history, "push")
|
|
293
|
-
.mockImplementation(() => {});
|
|
294
|
-
|
|
295
|
-
AppsScriptContainer.load((container) => {
|
|
296
|
-
container.sync(createEntry("/users"));
|
|
297
|
-
|
|
298
|
-
expect(push).toHaveBeenCalledWith(
|
|
299
|
-
expect.anything(),
|
|
300
|
-
expect.anything(),
|
|
301
|
-
"#/users",
|
|
302
|
-
);
|
|
303
|
-
});
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
it("同期後に自身の現在状態を更新する", () => {
|
|
307
|
-
mockLocation();
|
|
308
|
-
|
|
309
|
-
vi.spyOn(google.script.history, "push").mockImplementation(() => {});
|
|
310
|
-
|
|
311
|
-
AppsScriptContainer.load((container) => {
|
|
312
|
-
const entry = createEntry("#/settings");
|
|
313
|
-
|
|
314
|
-
container.sync(entry);
|
|
315
|
-
|
|
316
|
-
expect(container.current()).toBe(entry);
|
|
317
|
-
});
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
it("同一の NavigationEntry を受け取った場合は history を更新しない", () => {
|
|
321
|
-
mockLocation({
|
|
322
|
-
hash: "/users",
|
|
323
|
-
parameter: {},
|
|
324
|
-
parameters: {},
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
const push = vi
|
|
328
|
-
.spyOn(google.script.history, "push")
|
|
329
|
-
.mockImplementation(() => {});
|
|
330
|
-
|
|
331
|
-
AppsScriptContainer.load((container) => {
|
|
332
|
-
container.sync(
|
|
333
|
-
new NavigationEntry(
|
|
334
|
-
{},
|
|
335
|
-
new NavigationLocation(
|
|
336
|
-
new HashProperty("#/users"),
|
|
337
|
-
new URLSearchParams(),
|
|
338
|
-
),
|
|
339
|
-
),
|
|
340
|
-
);
|
|
341
|
-
|
|
342
|
-
expect(push).not.toHaveBeenCalled();
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
it("同じ状態を複数回同期しても history.push を重複して呼ばない", () => {
|
|
347
|
-
mockLocation();
|
|
348
|
-
|
|
349
|
-
const push = vi
|
|
350
|
-
.spyOn(google.script.history, "push")
|
|
351
|
-
.mockImplementation(() => {});
|
|
352
|
-
|
|
353
|
-
AppsScriptContainer.load((container) => {
|
|
354
|
-
const entry = createEntry("#/users");
|
|
355
|
-
|
|
356
|
-
container.sync(entry);
|
|
357
|
-
container.sync(entry);
|
|
358
|
-
|
|
359
|
-
expect(push).toHaveBeenCalledOnce();
|
|
360
|
-
});
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
it("state が異なる場合は location が同じでも同期する", () => {
|
|
364
|
-
mockLocation({
|
|
365
|
-
hash: "/users",
|
|
366
|
-
parameter: {},
|
|
367
|
-
parameters: {},
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
const push = vi
|
|
371
|
-
.spyOn(google.script.history, "push")
|
|
372
|
-
.mockImplementation(() => {});
|
|
373
|
-
|
|
374
|
-
AppsScriptContainer.load((container) => {
|
|
375
|
-
container.sync(
|
|
376
|
-
new NavigationEntry(
|
|
377
|
-
{
|
|
378
|
-
page: 2,
|
|
379
|
-
},
|
|
380
|
-
new NavigationLocation(
|
|
381
|
-
new HashProperty("#/users"),
|
|
382
|
-
new URLSearchParams(),
|
|
383
|
-
),
|
|
384
|
-
),
|
|
385
|
-
);
|
|
386
|
-
|
|
387
|
-
expect(push).toHaveBeenCalledOnce();
|
|
388
|
-
});
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
it("query parameter が異なる場合は hash が同じでも同期する", () => {
|
|
392
|
-
mockLocation({
|
|
393
|
-
hash: "/users",
|
|
394
|
-
parameter: {
|
|
395
|
-
page: "1",
|
|
396
|
-
},
|
|
397
|
-
parameters: {
|
|
398
|
-
page: ["1"],
|
|
399
|
-
},
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
const push = vi
|
|
403
|
-
.spyOn(google.script.history, "push")
|
|
404
|
-
.mockImplementation(() => {});
|
|
405
|
-
|
|
406
|
-
AppsScriptContainer.load((container) => {
|
|
407
|
-
container.sync(
|
|
408
|
-
new NavigationEntry(
|
|
409
|
-
{},
|
|
410
|
-
new NavigationLocation(
|
|
411
|
-
new HashProperty("#/users"),
|
|
412
|
-
new URLSearchParams("page=2"),
|
|
413
|
-
),
|
|
414
|
-
),
|
|
415
|
-
);
|
|
416
|
-
|
|
417
|
-
expect(push).toHaveBeenCalledOnce();
|
|
418
|
-
});
|
|
419
|
-
});
|
|
420
|
-
|
|
421
|
-
it("query parameter のキー順だけが異なる場合は同期しない", () => {
|
|
422
|
-
mockLocation({
|
|
423
|
-
hash: "/users",
|
|
424
|
-
parameter: {
|
|
425
|
-
page: "1",
|
|
426
|
-
sort: "name",
|
|
427
|
-
},
|
|
428
|
-
parameters: {
|
|
429
|
-
page: ["1"],
|
|
430
|
-
sort: ["name"],
|
|
431
|
-
},
|
|
432
|
-
});
|
|
433
|
-
|
|
434
|
-
const push = vi
|
|
435
|
-
.spyOn(google.script.history, "push")
|
|
436
|
-
.mockImplementation(() => {});
|
|
437
|
-
|
|
438
|
-
AppsScriptContainer.load((container) => {
|
|
439
|
-
container.sync(
|
|
440
|
-
new NavigationEntry(
|
|
441
|
-
{},
|
|
442
|
-
new NavigationLocation(
|
|
443
|
-
new HashProperty("#/users"),
|
|
444
|
-
new URLSearchParams("sort=name&page=1"),
|
|
445
|
-
),
|
|
446
|
-
),
|
|
447
|
-
);
|
|
448
|
-
|
|
449
|
-
expect(push).not.toHaveBeenCalled();
|
|
450
|
-
});
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
it("同一キーの複数値の順序が異なる場合は同期する", () => {
|
|
454
|
-
mockLocation({
|
|
455
|
-
hash: "/users",
|
|
456
|
-
parameter: {
|
|
457
|
-
tag: "react",
|
|
458
|
-
},
|
|
459
|
-
parameters: {
|
|
460
|
-
tag: ["react", "typescript"],
|
|
461
|
-
},
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
const push = vi
|
|
465
|
-
.spyOn(google.script.history, "push")
|
|
466
|
-
.mockImplementation(() => {});
|
|
467
|
-
|
|
468
|
-
AppsScriptContainer.load((container) => {
|
|
469
|
-
container.sync(
|
|
470
|
-
new NavigationEntry(
|
|
471
|
-
{},
|
|
472
|
-
new NavigationLocation(
|
|
473
|
-
new HashProperty("#/users"),
|
|
474
|
-
new URLSearchParams("tag=typescript&tag=react"),
|
|
475
|
-
),
|
|
476
|
-
),
|
|
477
|
-
);
|
|
478
|
-
|
|
479
|
-
expect(push).toHaveBeenCalledOnce();
|
|
480
|
-
});
|
|
481
|
-
});
|
|
482
|
-
});
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
function mockLocation(
|
|
486
|
-
location: GoogleScriptUrlLocation = {
|
|
487
|
-
hash: "",
|
|
488
|
-
parameter: {},
|
|
489
|
-
parameters: {},
|
|
490
|
-
},
|
|
491
|
-
) {
|
|
492
|
-
vi.spyOn(google.script.url, "getLocation").mockImplementation((callback) => {
|
|
493
|
-
callback(location);
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
function createEntry(hash = "#/") {
|
|
498
|
-
return new NavigationEntry(
|
|
499
|
-
{},
|
|
500
|
-
new NavigationLocation(new HashProperty(hash), new URLSearchParams()),
|
|
501
|
-
);
|
|
502
|
-
}
|