haori 0.1.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/LICENSE +21 -0
- package/README.ja.md +157 -0
- package/README.md +158 -0
- package/dist/haori.cjs.js +13 -0
- package/dist/haori.cjs.js.map +1 -0
- package/dist/haori.es.js +2929 -0
- package/dist/haori.es.js.map +1 -0
- package/dist/haori.iife.js +13 -0
- package/dist/haori.iife.js.map +1 -0
- package/dist/index.d.ts +824 -0
- package/dist/src/core.d.ts +144 -0
- package/dist/src/core.d.ts.map +1 -0
- package/dist/src/core.js +605 -0
- package/dist/src/core.js.map +1 -0
- package/dist/src/dev.d.ts +35 -0
- package/dist/src/dev.d.ts.map +1 -0
- package/dist/src/dev.js +44 -0
- package/dist/src/dev.js.map +1 -0
- package/dist/src/env.d.ts +25 -0
- package/dist/src/env.d.ts.map +1 -0
- package/dist/src/env.js +64 -0
- package/dist/src/env.js.map +1 -0
- package/dist/src/event.d.ts +144 -0
- package/dist/src/event.d.ts.map +1 -0
- package/dist/src/event.js +221 -0
- package/dist/src/event.js.map +1 -0
- package/dist/src/event_dispatcher.d.ts +50 -0
- package/dist/src/event_dispatcher.d.ts.map +1 -0
- package/dist/src/event_dispatcher.js +99 -0
- package/dist/src/event_dispatcher.js.map +1 -0
- package/dist/src/expression.d.ts +39 -0
- package/dist/src/expression.d.ts.map +1 -0
- package/dist/src/expression.js +148 -0
- package/dist/src/expression.js.map +1 -0
- package/dist/src/form.d.ts +113 -0
- package/dist/src/form.d.ts.map +1 -0
- package/dist/src/form.js +361 -0
- package/dist/src/form.js.map +1 -0
- package/dist/src/fragment.d.ts +427 -0
- package/dist/src/fragment.d.ts.map +1 -0
- package/dist/src/fragment.js +1168 -0
- package/dist/src/fragment.js.map +1 -0
- package/dist/src/haori.d.ts +54 -0
- package/dist/src/haori.d.ts.map +1 -0
- package/dist/src/haori.js +120 -0
- package/dist/src/haori.js.map +1 -0
- package/dist/src/import.d.ts +19 -0
- package/dist/src/import.d.ts.map +1 -0
- package/dist/src/import.js +64 -0
- package/dist/src/import.js.map +1 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +21 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/log.d.ts +32 -0
- package/dist/src/log.d.ts.map +1 -0
- package/dist/src/log.js +43 -0
- package/dist/src/log.js.map +1 -0
- package/dist/src/observer.d.ts +17 -0
- package/dist/src/observer.d.ts.map +1 -0
- package/dist/src/observer.js +102 -0
- package/dist/src/observer.js.map +1 -0
- package/dist/src/procedure.d.ts +203 -0
- package/dist/src/procedure.d.ts.map +1 -0
- package/dist/src/procedure.js +1040 -0
- package/dist/src/procedure.js.map +1 -0
- package/dist/src/queue.d.ts +28 -0
- package/dist/src/queue.d.ts.map +1 -0
- package/dist/src/queue.js +150 -0
- package/dist/src/queue.js.map +1 -0
- package/dist/src/url.d.ts +14 -0
- package/dist/src/url.d.ts.map +1 -0
- package/dist/src/url.js +22 -0
- package/dist/src/url.js.map +1 -0
- package/dist/tests/click-attributes.test.d.ts +2 -0
- package/dist/tests/click-attributes.test.d.ts.map +1 -0
- package/dist/tests/click-attributes.test.js +95 -0
- package/dist/tests/click-attributes.test.js.map +1 -0
- package/dist/tests/core.test.d.ts +5 -0
- package/dist/tests/core.test.d.ts.map +1 -0
- package/dist/tests/core.test.js +158 -0
- package/dist/tests/core.test.js.map +1 -0
- package/dist/tests/data-each-browserlike.test.d.ts +2 -0
- package/dist/tests/data-each-browserlike.test.d.ts.map +1 -0
- package/dist/tests/data-each-browserlike.test.js +48 -0
- package/dist/tests/data-each-browserlike.test.js.map +1 -0
- package/dist/tests/data-each-fragment-debug.test.d.ts +2 -0
- package/dist/tests/data-each-fragment-debug.test.d.ts.map +1 -0
- package/dist/tests/data-each-fragment-debug.test.js +119 -0
- package/dist/tests/data-each-fragment-debug.test.js.map +1 -0
- package/dist/tests/data-each-table.test.d.ts +2 -0
- package/dist/tests/data-each-table.test.d.ts.map +1 -0
- package/dist/tests/data-each-table.test.js +63 -0
- package/dist/tests/data-each-table.test.js.map +1 -0
- package/dist/tests/dev.test.d.ts +2 -0
- package/dist/tests/dev.test.d.ts.map +1 -0
- package/dist/tests/dev.test.js +51 -0
- package/dist/tests/dev.test.js.map +1 -0
- package/dist/tests/each_arg.test.d.ts +2 -0
- package/dist/tests/each_arg.test.d.ts.map +1 -0
- package/dist/tests/each_arg.test.js +41 -0
- package/dist/tests/each_arg.test.js.map +1 -0
- package/dist/tests/env.test.d.ts +2 -0
- package/dist/tests/env.test.d.ts.map +1 -0
- package/dist/tests/env.test.js +96 -0
- package/dist/tests/env.test.js.map +1 -0
- package/dist/tests/event.test.d.ts +2 -0
- package/dist/tests/event.test.d.ts.map +1 -0
- package/dist/tests/event.test.js +287 -0
- package/dist/tests/event.test.js.map +1 -0
- package/dist/tests/expression.test.d.ts +2 -0
- package/dist/tests/expression.test.d.ts.map +1 -0
- package/dist/tests/expression.test.js +281 -0
- package/dist/tests/expression.test.js.map +1 -0
- package/dist/tests/fetch-and-procedure-scenarios.test.d.ts +2 -0
- package/dist/tests/fetch-and-procedure-scenarios.test.d.ts.map +1 -0
- package/dist/tests/fetch-and-procedure-scenarios.test.js +133 -0
- package/dist/tests/fetch-and-procedure-scenarios.test.js.map +1 -0
- package/dist/tests/form.test.d.ts +2 -0
- package/dist/tests/form.test.d.ts.map +1 -0
- package/dist/tests/form.test.js +607 -0
- package/dist/tests/form.test.js.map +1 -0
- package/dist/tests/fragment.test.d.ts +2 -0
- package/dist/tests/fragment.test.d.ts.map +1 -0
- package/dist/tests/fragment.test.js +164 -0
- package/dist/tests/fragment.test.js.map +1 -0
- package/dist/tests/import.test.d.ts +2 -0
- package/dist/tests/import.test.d.ts.map +1 -0
- package/dist/tests/import.test.js +148 -0
- package/dist/tests/import.test.js.map +1 -0
- package/dist/tests/log.test.d.ts +2 -0
- package/dist/tests/log.test.d.ts.map +1 -0
- package/dist/tests/log.test.js +58 -0
- package/dist/tests/log.test.js.map +1 -0
- package/dist/tests/procedure-action-operations.test.d.ts +2 -0
- package/dist/tests/procedure-action-operations.test.d.ts.map +1 -0
- package/dist/tests/procedure-action-operations.test.js +148 -0
- package/dist/tests/procedure-action-operations.test.js.map +1 -0
- package/dist/tests/procedure-fetch-options.test.d.ts +2 -0
- package/dist/tests/procedure-fetch-options.test.d.ts.map +1 -0
- package/dist/tests/procedure-fetch-options.test.js +131 -0
- package/dist/tests/procedure-fetch-options.test.js.map +1 -0
- package/dist/tests/procedure.test.d.ts +2 -0
- package/dist/tests/procedure.test.d.ts.map +1 -0
- package/dist/tests/procedure.test.js +136 -0
- package/dist/tests/procedure.test.js.map +1 -0
- package/dist/tests/procedure_events.test.d.ts +7 -0
- package/dist/tests/procedure_events.test.d.ts.map +1 -0
- package/dist/tests/procedure_events.test.js +96 -0
- package/dist/tests/procedure_events.test.js.map +1 -0
- package/dist/tests/reset_each.test.d.ts +2 -0
- package/dist/tests/reset_each.test.d.ts.map +1 -0
- package/dist/tests/reset_each.test.js +215 -0
- package/dist/tests/reset_each.test.js.map +1 -0
- package/dist/tests/row-move.test.d.ts +2 -0
- package/dist/tests/row-move.test.d.ts.map +1 -0
- package/dist/tests/row-move.test.js +197 -0
- package/dist/tests/row-move.test.js.map +1 -0
- package/dist/tests/row-operations.test.d.ts +2 -0
- package/dist/tests/row-operations.test.d.ts.map +1 -0
- package/dist/tests/row-operations.test.js +238 -0
- package/dist/tests/row-operations.test.js.map +1 -0
- package/dist/tests/url.test.d.ts +2 -0
- package/dist/tests/url.test.d.ts.map +1 -0
- package/dist/tests/url.test.js +150 -0
- package/dist/tests/url.test.js.map +1 -0
- package/dist/vite.config.d.ts +3 -0
- package/dist/vite.config.d.ts.map +1 -0
- package/dist/vite.config.js +28 -0
- package/dist/vite.config.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +19 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/* @vitest-environment jsdom */
|
|
2
|
+
/**
|
|
3
|
+
* Procedure の fetch オプションと前後フックに関するテスト
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
6
|
+
import Core from '../src/core';
|
|
7
|
+
describe('Procedure fetch options and hooks', () => {
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
vi.restoreAllMocks();
|
|
10
|
+
await import('../src/observer');
|
|
11
|
+
});
|
|
12
|
+
it('sends JSON body for POST when method is POST', async () => {
|
|
13
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockImplementation(() => {
|
|
14
|
+
return Promise.resolve(new Response('{}', { headers: { 'Content-Type': 'application/json' } }));
|
|
15
|
+
});
|
|
16
|
+
const container = document.createElement('div');
|
|
17
|
+
document.body.appendChild(container);
|
|
18
|
+
// 非イベント fetch 属性を使って POST を要求
|
|
19
|
+
const src = document.createElement('div');
|
|
20
|
+
src.setAttribute('data-fetch', 'http://api.test/post');
|
|
21
|
+
src.setAttribute('data-fetch-method', 'POST');
|
|
22
|
+
src.setAttribute('data-fetch-data', 'x=1');
|
|
23
|
+
container.appendChild(src);
|
|
24
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
25
|
+
expect(fetchSpy).toHaveBeenCalled();
|
|
26
|
+
const called = fetchSpy.mock.calls.slice(-1)[0];
|
|
27
|
+
const options = called[1];
|
|
28
|
+
if (options) {
|
|
29
|
+
expect(String(options.method).toUpperCase()).toBe('POST');
|
|
30
|
+
}
|
|
31
|
+
container.remove();
|
|
32
|
+
});
|
|
33
|
+
it('handles multipart headers and FormData', async () => {
|
|
34
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockImplementation(() => {
|
|
35
|
+
return Promise.resolve(new Response('{}', { headers: { 'Content-Type': 'application/json' } }));
|
|
36
|
+
});
|
|
37
|
+
const container = document.createElement('div');
|
|
38
|
+
document.body.appendChild(container);
|
|
39
|
+
const src = document.createElement('div');
|
|
40
|
+
src.setAttribute('data-fetch', 'http://api.test/upload');
|
|
41
|
+
src.setAttribute('data-fetch-method', 'POST');
|
|
42
|
+
const headersObj = { 'Content-Type': 'multipart/form-data', 'X-Test': '1' };
|
|
43
|
+
src.setAttribute('data-fetch-headers', JSON.stringify(headersObj));
|
|
44
|
+
src.setAttribute('data-fetch-data', JSON.stringify({ a: 'b' }));
|
|
45
|
+
container.appendChild(src);
|
|
46
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
47
|
+
expect(fetchSpy).toHaveBeenCalled();
|
|
48
|
+
const called = fetchSpy.mock.calls.slice(-1)[0];
|
|
49
|
+
const options = called[1];
|
|
50
|
+
if (options) {
|
|
51
|
+
const headers = new Headers(options.headers || undefined);
|
|
52
|
+
// multipart の場合ライブラリは Content-Type を削除し FormData を body に設定する
|
|
53
|
+
expect(headers.get('Content-Type')).toBeNull();
|
|
54
|
+
expect(options.body).toBeInstanceOf(FormData);
|
|
55
|
+
}
|
|
56
|
+
container.remove();
|
|
57
|
+
});
|
|
58
|
+
it('bindArg binds response under key', async () => {
|
|
59
|
+
vi.spyOn(globalThis, 'fetch').mockImplementation(() => {
|
|
60
|
+
return Promise.resolve(new Response(JSON.stringify({ got: true }), {
|
|
61
|
+
headers: { 'Content-Type': 'application/json' },
|
|
62
|
+
}));
|
|
63
|
+
});
|
|
64
|
+
const sbd = vi.spyOn(Core, 'setBindingData').mockResolvedValue(undefined);
|
|
65
|
+
const container = document.createElement('div');
|
|
66
|
+
document.body.appendChild(container);
|
|
67
|
+
const target = document.createElement('div');
|
|
68
|
+
target.id = 'bind-target';
|
|
69
|
+
const src = document.createElement('div');
|
|
70
|
+
src.setAttribute('data-fetch', 'http://api.test/resp');
|
|
71
|
+
src.setAttribute('data-fetch-bind', '#bind-target');
|
|
72
|
+
src.setAttribute('data-fetch-bind-arg', 'result');
|
|
73
|
+
container.appendChild(target);
|
|
74
|
+
container.appendChild(src);
|
|
75
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
76
|
+
expect(sbd).toHaveBeenCalled();
|
|
77
|
+
const calls = sbd.mock.calls;
|
|
78
|
+
const last = calls[calls.length - 1];
|
|
79
|
+
const binding = last[1];
|
|
80
|
+
expect(binding).toHaveProperty('result');
|
|
81
|
+
container.remove();
|
|
82
|
+
});
|
|
83
|
+
it('beforeCallback can stop or modify options', async () => {
|
|
84
|
+
const fetchSpy = vi.spyOn(globalThis, 'fetch').mockImplementation(() => {
|
|
85
|
+
return Promise.resolve(new Response('{}', { headers: { 'Content-Type': 'application/json' } }));
|
|
86
|
+
});
|
|
87
|
+
// Case: beforeCallback returns false -> use data-click-before-run to return false
|
|
88
|
+
const container = document.createElement('div');
|
|
89
|
+
document.body.appendChild(container);
|
|
90
|
+
const btnStop = document.createElement('button');
|
|
91
|
+
btnStop.setAttribute('data-click-before-run', 'return false;');
|
|
92
|
+
btnStop.setAttribute('data-click-fetch', 'http://api.test/stop');
|
|
93
|
+
container.appendChild(btnStop);
|
|
94
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
95
|
+
btnStop.click();
|
|
96
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
97
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
98
|
+
// Case: beforeCallback modifies fetchOptions
|
|
99
|
+
const btnModify = document.createElement('button');
|
|
100
|
+
const modifyScript = 'return {fetchOptions:{headers:{"X-From-Before":"yes"}}};';
|
|
101
|
+
btnModify.setAttribute('data-click-before-run', modifyScript);
|
|
102
|
+
btnModify.setAttribute('data-click-fetch', 'http://api.test/modify');
|
|
103
|
+
container.appendChild(btnModify);
|
|
104
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
105
|
+
btnModify.click();
|
|
106
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
107
|
+
const called = fetchSpy.mock.calls.slice(-1)[0];
|
|
108
|
+
const headers = new Headers(called[1].headers || undefined);
|
|
109
|
+
expect(headers.get('X-From-Before')).toBe('yes');
|
|
110
|
+
container.remove();
|
|
111
|
+
});
|
|
112
|
+
it('afterCallback can stop further processing', async () => {
|
|
113
|
+
vi.spyOn(globalThis, 'fetch').mockImplementation(() => {
|
|
114
|
+
return Promise.resolve(new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }));
|
|
115
|
+
});
|
|
116
|
+
const sbd = vi.spyOn(Core, 'setBindingData').mockResolvedValue(undefined);
|
|
117
|
+
const container = document.createElement('div');
|
|
118
|
+
document.body.appendChild(container);
|
|
119
|
+
const btn = document.createElement('button');
|
|
120
|
+
btn.setAttribute('data-click-fetch', 'http://api.test/stop');
|
|
121
|
+
btn.setAttribute('data-click-after-run', 'return {stop:true};');
|
|
122
|
+
container.appendChild(btn);
|
|
123
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
124
|
+
btn.click();
|
|
125
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
126
|
+
// setBindingData should not be called because afterCallback returned stop
|
|
127
|
+
expect(sbd).not.toHaveBeenCalled();
|
|
128
|
+
container.remove();
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=procedure-fetch-options.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"procedure-fetch-options.test.js","sourceRoot":"","sources":["../../tests/procedure-fetch-options.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"procedure.test.d.ts","sourceRoot":"","sources":["../../tests/procedure.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { describe, it, beforeEach, expect, vi } from 'vitest';
|
|
2
|
+
import Procedure from '../src/procedure';
|
|
3
|
+
import Core from '../src/core';
|
|
4
|
+
import Haori from '../src/haori';
|
|
5
|
+
import Fragment from '../src/fragment';
|
|
6
|
+
vi.mock('../src/core');
|
|
7
|
+
vi.mock('../src/haori');
|
|
8
|
+
class MockFragment {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.value = '';
|
|
11
|
+
this.target = document.createElement('div');
|
|
12
|
+
this.getTarget = () => this.target;
|
|
13
|
+
this.getChildElementFragments = vi.fn(() => []);
|
|
14
|
+
this.getValue = vi.fn(() => this.value);
|
|
15
|
+
this.setValue = vi.fn(async (v) => {
|
|
16
|
+
this.value = v;
|
|
17
|
+
});
|
|
18
|
+
this.getBindingData = vi.fn(() => ({}));
|
|
19
|
+
}
|
|
20
|
+
setTarget(target) {
|
|
21
|
+
this.target = target;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
describe('Procedureクラス', () => {
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
vi.clearAllMocks();
|
|
27
|
+
});
|
|
28
|
+
it('バリデーションに失敗した場合は即resolveされる', async () => {
|
|
29
|
+
const fragment = new MockFragment();
|
|
30
|
+
const input = document.createElement('input');
|
|
31
|
+
vi.spyOn(input, 'reportValidity').mockReturnValue(false);
|
|
32
|
+
vi.spyOn(input, 'focus').mockImplementation(() => { });
|
|
33
|
+
fragment.setTarget(input);
|
|
34
|
+
const proc = new Procedure({
|
|
35
|
+
targetFragment: fragment,
|
|
36
|
+
formFragment: fragment,
|
|
37
|
+
valid: true,
|
|
38
|
+
});
|
|
39
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
40
|
+
expect(input.focus).toHaveBeenCalled();
|
|
41
|
+
});
|
|
42
|
+
it('confirmがfalseの場合は即resolveされる', async () => {
|
|
43
|
+
vi.spyOn(Haori, 'confirm').mockResolvedValue(false);
|
|
44
|
+
const proc = new Procedure({ confirmMessage: 'Are you sure?' });
|
|
45
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
46
|
+
expect(Haori.confirm).toHaveBeenCalledWith('Are you sure?');
|
|
47
|
+
});
|
|
48
|
+
it('beforeCallbackでstopが返った場合は停止する', async () => {
|
|
49
|
+
const beforeCallback = vi.fn(() => ({ stop: true }));
|
|
50
|
+
const proc = new Procedure({ beforeCallback });
|
|
51
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
52
|
+
expect(beforeCallback).toHaveBeenCalled();
|
|
53
|
+
});
|
|
54
|
+
it('afterCallbackでstopが返った場合は停止する', async () => {
|
|
55
|
+
global.fetch = vi
|
|
56
|
+
.fn()
|
|
57
|
+
.mockResolvedValue(new Response('{}', { headers: { 'Content-Type': 'application/json' } }));
|
|
58
|
+
const afterCallback = vi.fn(() => ({ stop: true }));
|
|
59
|
+
const proc = new Procedure({
|
|
60
|
+
fetchUrl: 'http://test',
|
|
61
|
+
afterCallback,
|
|
62
|
+
});
|
|
63
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
64
|
+
expect(afterCallback).toHaveBeenCalled();
|
|
65
|
+
});
|
|
66
|
+
it('bindFragmentsにバインドされる', async () => {
|
|
67
|
+
vi.spyOn(Core, 'setBindingData').mockResolvedValue(undefined);
|
|
68
|
+
global.fetch = vi.fn().mockResolvedValue(new Response(JSON.stringify({ foo: 'bar' }), {
|
|
69
|
+
headers: { 'Content-Type': 'application/json' },
|
|
70
|
+
}));
|
|
71
|
+
const fragment = new MockFragment();
|
|
72
|
+
const proc = new Procedure({
|
|
73
|
+
fetchUrl: 'http://test',
|
|
74
|
+
bindFragments: [fragment],
|
|
75
|
+
});
|
|
76
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
77
|
+
expect(Core.setBindingData).toHaveBeenCalled();
|
|
78
|
+
});
|
|
79
|
+
it('非イベント: data-fetch-arg で bindArg が適用される', async () => {
|
|
80
|
+
// 準備: ターゲットとソース要素
|
|
81
|
+
const container = document.createElement('div');
|
|
82
|
+
document.body.appendChild(container);
|
|
83
|
+
const target = document.createElement('div');
|
|
84
|
+
target.id = 'tgt';
|
|
85
|
+
const source = document.createElement('div');
|
|
86
|
+
source.setAttribute('data-fetch', 'http://test');
|
|
87
|
+
source.setAttribute('data-fetch-bind', '#tgt');
|
|
88
|
+
source.setAttribute('data-fetch-arg', 'wrapped');
|
|
89
|
+
container.append(target, source);
|
|
90
|
+
// fetch のモック
|
|
91
|
+
global.fetch = vi.fn().mockResolvedValue(new Response(JSON.stringify({ x: 1 }), {
|
|
92
|
+
headers: { 'Content-Type': 'application/json' },
|
|
93
|
+
}));
|
|
94
|
+
// setBindingData のスパイ
|
|
95
|
+
const sbd = vi
|
|
96
|
+
.spyOn(Core, 'setBindingData')
|
|
97
|
+
.mockResolvedValue(undefined);
|
|
98
|
+
// Procedure 実行(非イベント)
|
|
99
|
+
const frag = Fragment.get(source);
|
|
100
|
+
const proc = new (await import('../src/procedure')).default(frag, null);
|
|
101
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
102
|
+
// 呼び出し検証
|
|
103
|
+
expect(sbd).toHaveBeenCalled();
|
|
104
|
+
const calls = sbd.mock.calls;
|
|
105
|
+
// 最後の呼び出しのデータを確認
|
|
106
|
+
const last = calls[calls.length - 1];
|
|
107
|
+
expect(last[0].id).toBe('tgt');
|
|
108
|
+
const bound = last[1];
|
|
109
|
+
expect(bound).toHaveProperty('wrapped');
|
|
110
|
+
expect(bound['wrapped']).toEqual({ x: 1 });
|
|
111
|
+
// クリーンアップ
|
|
112
|
+
container.remove();
|
|
113
|
+
});
|
|
114
|
+
it('adjustFragmentsで値が増減される', async () => {
|
|
115
|
+
const fragment = new MockFragment();
|
|
116
|
+
fragment.getValue = vi.fn(() => '10');
|
|
117
|
+
fragment.setValue = vi.fn(() => Promise.resolve());
|
|
118
|
+
const proc = new Procedure({
|
|
119
|
+
adjustFragments: [fragment],
|
|
120
|
+
adjustValue: 5,
|
|
121
|
+
});
|
|
122
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
123
|
+
expect(fragment.setValue).toHaveBeenCalledWith('15');
|
|
124
|
+
});
|
|
125
|
+
it('validateOneは非input要素でtrueを返す', () => {
|
|
126
|
+
const fragment = new MockFragment();
|
|
127
|
+
fragment.setTarget(document.createElement('div'));
|
|
128
|
+
const proc = new Procedure({});
|
|
129
|
+
expect(proc['validateOne'](fragment)).toBe(true);
|
|
130
|
+
});
|
|
131
|
+
it('confirmはメッセージがなければtrueを返す', async () => {
|
|
132
|
+
const proc = new Procedure({});
|
|
133
|
+
await expect(proc['confirm']()).resolves.toBe(true);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=procedure.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"procedure.test.js","sourceRoot":"","sources":["../../tests/procedure.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"procedure_events.test.d.ts","sourceRoot":"","sources":["../../tests/procedure_events.test.ts"],"names":[],"mappings":"AAwHA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,EAAE,OAAO,CAAC;KACrB;CACF"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { describe, it, beforeEach, expect, vi, afterEach } from 'vitest';
|
|
2
|
+
import Procedure from '../src/procedure';
|
|
3
|
+
import Fragment from '../src/fragment';
|
|
4
|
+
import Haori from '../src/haori';
|
|
5
|
+
describe('イベント属性: before-run / after-run', () => {
|
|
6
|
+
let container;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
container = document.createElement('div');
|
|
9
|
+
document.body.appendChild(container);
|
|
10
|
+
// Reset global flag if used
|
|
11
|
+
// 型安全のために Window 拡張を使用
|
|
12
|
+
window.__afterRan = false;
|
|
13
|
+
});
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
container.remove();
|
|
16
|
+
vi.restoreAllMocks();
|
|
17
|
+
});
|
|
18
|
+
const createFragmentWith = (attrs) => {
|
|
19
|
+
const el = document.createElement('button');
|
|
20
|
+
for (const [k, v] of Object.entries(attrs)) {
|
|
21
|
+
el.setAttribute(k, v);
|
|
22
|
+
}
|
|
23
|
+
container.appendChild(el);
|
|
24
|
+
const frag = Fragment.get(el);
|
|
25
|
+
return frag;
|
|
26
|
+
};
|
|
27
|
+
it('data-???-before-run が false を返すと以後の処理を停止する(dialog が呼ばれない)', async () => {
|
|
28
|
+
const frag = createFragmentWith({
|
|
29
|
+
'data-click-before-run': 'return false;',
|
|
30
|
+
'data-click-dialog': 'OK',
|
|
31
|
+
});
|
|
32
|
+
const dialogSpy = vi.spyOn(Haori, 'dialog').mockResolvedValue();
|
|
33
|
+
const proc = new Procedure(frag, 'click');
|
|
34
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
35
|
+
expect(dialogSpy).not.toHaveBeenCalled();
|
|
36
|
+
});
|
|
37
|
+
it('data-???-after-run が false を返すと後続(dialog)が実行されない', async () => {
|
|
38
|
+
const frag = createFragmentWith({
|
|
39
|
+
'data-click-fetch': 'https://example.com/api',
|
|
40
|
+
'data-click-after-run': 'return false;',
|
|
41
|
+
'data-click-dialog': 'OK',
|
|
42
|
+
});
|
|
43
|
+
global.fetch = vi.fn().mockResolvedValue(new Response('{}', {
|
|
44
|
+
headers: { 'Content-Type': 'application/json' },
|
|
45
|
+
}));
|
|
46
|
+
const dialogSpy = vi.spyOn(Haori, 'dialog').mockResolvedValue();
|
|
47
|
+
const proc = new Procedure(frag, 'click');
|
|
48
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
49
|
+
expect(dialogSpy).not.toHaveBeenCalled();
|
|
50
|
+
});
|
|
51
|
+
it('フェッチエラー時は after-run が実行されない', async () => {
|
|
52
|
+
const frag = createFragmentWith({
|
|
53
|
+
'data-click-fetch': 'https://example.com/api',
|
|
54
|
+
'data-click-after-run': 'window.__afterRan = true;',
|
|
55
|
+
});
|
|
56
|
+
global.fetch = vi
|
|
57
|
+
.fn()
|
|
58
|
+
.mockResolvedValue(new Response('bad', { status: 400 }));
|
|
59
|
+
vi.spyOn(Haori, 'addErrorMessage').mockResolvedValue();
|
|
60
|
+
const proc = new Procedure(frag, 'click');
|
|
61
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
62
|
+
expect(window.__afterRan).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
it('baseline: fetch が呼ばれる(URL は元の値)', async () => {
|
|
65
|
+
const frag = createFragmentWith({
|
|
66
|
+
'data-click-fetch': 'https://example.com/original',
|
|
67
|
+
'data-click-after-run': 'return;',
|
|
68
|
+
});
|
|
69
|
+
const fetchMock = (global.fetch = vi.fn().mockResolvedValue(new Response('{}', {
|
|
70
|
+
headers: { 'Content-Type': 'application/json' },
|
|
71
|
+
})));
|
|
72
|
+
const proc = new Procedure(frag, 'click');
|
|
73
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
74
|
+
const calls = fetchMock.mock
|
|
75
|
+
.calls;
|
|
76
|
+
expect(calls.length).toBe(1);
|
|
77
|
+
expect(String(calls[0][0])).toBe('https://example.com/original');
|
|
78
|
+
});
|
|
79
|
+
it('before-run で fetchUrl を上書きできる', async () => {
|
|
80
|
+
const frag = createFragmentWith({
|
|
81
|
+
'data-click-fetch': 'https://example.com/original',
|
|
82
|
+
'data-click-before-run': 'return { fetchUrl: \'https://example.com/override\' };',
|
|
83
|
+
'data-click-after-run': 'return;',
|
|
84
|
+
});
|
|
85
|
+
const fetchMock = (global.fetch = vi.fn().mockResolvedValue(new Response('{}', {
|
|
86
|
+
headers: { 'Content-Type': 'application/json' },
|
|
87
|
+
})));
|
|
88
|
+
const proc = new Procedure(frag, 'click');
|
|
89
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
90
|
+
const calls = fetchMock.mock
|
|
91
|
+
.calls;
|
|
92
|
+
expect(calls.length).toBe(1);
|
|
93
|
+
expect(String(calls[0][0])).toBe('https://example.com/override');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=procedure_events.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"procedure_events.test.js","sourceRoot":"","sources":["../../tests/procedure_events.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset_each.test.d.ts","sourceRoot":"","sources":["../../tests/reset_each.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { describe, it, beforeEach, afterEach, expect, vi } from 'vitest';
|
|
2
|
+
import Fragment from '../src/fragment';
|
|
3
|
+
import Form from '../src/form';
|
|
4
|
+
import Core from '../src/core';
|
|
5
|
+
import Haori from '../src/haori';
|
|
6
|
+
describe('Form.reset と data-each 複製の境界ケース', () => {
|
|
7
|
+
let container;
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
container = document.createElement('div');
|
|
10
|
+
document.body.appendChild(container);
|
|
11
|
+
vi.spyOn(Core, 'evaluateAll').mockResolvedValue();
|
|
12
|
+
vi.spyOn(Haori, 'clearMessages').mockResolvedValue();
|
|
13
|
+
});
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
vi.restoreAllMocks();
|
|
16
|
+
container.remove();
|
|
17
|
+
});
|
|
18
|
+
const getFrag = (el) => {
|
|
19
|
+
const f = Fragment.get(el);
|
|
20
|
+
return f;
|
|
21
|
+
};
|
|
22
|
+
const markMounted = (f) => {
|
|
23
|
+
f.setMounted(true);
|
|
24
|
+
f.getChildElementFragments().forEach(child => markMounted(child));
|
|
25
|
+
};
|
|
26
|
+
it('data-each 配下で before/after を残し、それ以外の複製を削除する', async () => {
|
|
27
|
+
const each = document.createElement('div');
|
|
28
|
+
each.setAttribute('data-each', '[]');
|
|
29
|
+
const before = document.createElement('div');
|
|
30
|
+
before.setAttribute('data-each-before', '');
|
|
31
|
+
const c1 = document.createElement('div');
|
|
32
|
+
c1.className = 'clone1';
|
|
33
|
+
const c2 = document.createElement('div');
|
|
34
|
+
c2.className = 'clone2';
|
|
35
|
+
const after = document.createElement('div');
|
|
36
|
+
after.setAttribute('data-each-after', '');
|
|
37
|
+
each.append(before, c1, c2, after);
|
|
38
|
+
container.appendChild(each);
|
|
39
|
+
const frag = getFrag(each);
|
|
40
|
+
markMounted(frag);
|
|
41
|
+
await expect(Form.reset(frag)).resolves.toBeUndefined();
|
|
42
|
+
// before/after は残る
|
|
43
|
+
expect(each.querySelector('[data-each-before]')).not.toBeNull();
|
|
44
|
+
expect(each.querySelector('[data-each-after]')).not.toBeNull();
|
|
45
|
+
// クローンは削除される
|
|
46
|
+
expect(each.querySelector('.clone1')).toBeNull();
|
|
47
|
+
expect(each.querySelector('.clone2')).toBeNull();
|
|
48
|
+
expect(Core.evaluateAll).toHaveBeenCalledTimes(1);
|
|
49
|
+
expect(Haori.clearMessages).toHaveBeenCalled();
|
|
50
|
+
});
|
|
51
|
+
it('ネスト: before 内の内側 each の複製も削除される(再帰)', async () => {
|
|
52
|
+
const outer = document.createElement('section');
|
|
53
|
+
outer.setAttribute('data-each', '[]');
|
|
54
|
+
const before = document.createElement('div');
|
|
55
|
+
before.setAttribute('data-each-before', '');
|
|
56
|
+
const inner = document.createElement('div');
|
|
57
|
+
inner.setAttribute('data-each', '[]');
|
|
58
|
+
const ib = document.createElement('span');
|
|
59
|
+
ib.setAttribute('data-each-before', '');
|
|
60
|
+
const ic1 = document.createElement('span');
|
|
61
|
+
ic1.className = 'inner-clone1';
|
|
62
|
+
const ic2 = document.createElement('span');
|
|
63
|
+
ic2.className = 'inner-clone2';
|
|
64
|
+
const ia = document.createElement('span');
|
|
65
|
+
ia.setAttribute('data-each-after', '');
|
|
66
|
+
inner.append(ib, ic1, ic2, ia);
|
|
67
|
+
before.appendChild(inner);
|
|
68
|
+
const after = document.createElement('div');
|
|
69
|
+
after.setAttribute('data-each-after', '');
|
|
70
|
+
outer.append(before, after);
|
|
71
|
+
container.appendChild(outer);
|
|
72
|
+
const frag = getFrag(outer);
|
|
73
|
+
markMounted(frag);
|
|
74
|
+
await expect(Form.reset(frag)).resolves.toBeUndefined();
|
|
75
|
+
// 外側 before/after は残る
|
|
76
|
+
expect(outer.querySelector('[data-each-before]')).not.toBeNull();
|
|
77
|
+
expect(outer.querySelector('[data-each-after]')).not.toBeNull();
|
|
78
|
+
// 内側 each のクローンは削除される(before/after は残る)
|
|
79
|
+
expect(inner.querySelector('.inner-clone1')).toBeNull();
|
|
80
|
+
expect(inner.querySelector('.inner-clone2')).toBeNull();
|
|
81
|
+
expect(inner.querySelector('[data-each-before]')).not.toBeNull();
|
|
82
|
+
expect(inner.querySelector('[data-each-after]')).not.toBeNull();
|
|
83
|
+
});
|
|
84
|
+
it('大量の複製(100)でも全て削除され before/after のみ残る', async () => {
|
|
85
|
+
const each = document.createElement('ul');
|
|
86
|
+
each.setAttribute('data-each', '[]');
|
|
87
|
+
const before = document.createElement('li');
|
|
88
|
+
before.setAttribute('data-each-before', '');
|
|
89
|
+
each.appendChild(before);
|
|
90
|
+
for (let i = 0; i < 100; i++) {
|
|
91
|
+
const li = document.createElement('li');
|
|
92
|
+
li.className = `item-${i}`;
|
|
93
|
+
each.appendChild(li);
|
|
94
|
+
}
|
|
95
|
+
const after = document.createElement('li');
|
|
96
|
+
after.setAttribute('data-each-after', '');
|
|
97
|
+
each.appendChild(after);
|
|
98
|
+
container.appendChild(each);
|
|
99
|
+
const frag = getFrag(each);
|
|
100
|
+
markMounted(frag);
|
|
101
|
+
await expect(Form.reset(frag)).resolves.toBeUndefined();
|
|
102
|
+
// 100個のクローンが削除済み
|
|
103
|
+
let found = false;
|
|
104
|
+
for (let i = 0; i < 100; i++) {
|
|
105
|
+
if (each.querySelector(`.item-${i}`)) {
|
|
106
|
+
found = true;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
expect(found).toBe(false);
|
|
111
|
+
// before/after は残る
|
|
112
|
+
expect(each.querySelector('[data-each-before]')).not.toBeNull();
|
|
113
|
+
expect(each.querySelector('[data-each-after]')).not.toBeNull();
|
|
114
|
+
});
|
|
115
|
+
it('3段の深い入れ子でも各階層の複製が削除され before/after は保持される', async () => {
|
|
116
|
+
// outer -> middle -> inner と3段の each
|
|
117
|
+
const outer = document.createElement('div');
|
|
118
|
+
outer.setAttribute('data-each', '[]');
|
|
119
|
+
const ob = document.createElement('div');
|
|
120
|
+
ob.setAttribute('data-each-before', '');
|
|
121
|
+
const oa = document.createElement('div');
|
|
122
|
+
oa.setAttribute('data-each-after', '');
|
|
123
|
+
const middle = document.createElement('section');
|
|
124
|
+
middle.setAttribute('data-each', '[]');
|
|
125
|
+
const mb = document.createElement('div');
|
|
126
|
+
mb.setAttribute('data-each-before', '');
|
|
127
|
+
const mc1 = document.createElement('div');
|
|
128
|
+
mc1.className = 'm-clone1';
|
|
129
|
+
const mc2 = document.createElement('div');
|
|
130
|
+
mc2.className = 'm-clone2';
|
|
131
|
+
const ma = document.createElement('div');
|
|
132
|
+
ma.setAttribute('data-each-after', '');
|
|
133
|
+
const inner = document.createElement('article');
|
|
134
|
+
inner.setAttribute('data-each', '[]');
|
|
135
|
+
const ib = document.createElement('span');
|
|
136
|
+
ib.setAttribute('data-each-before', '');
|
|
137
|
+
const ic1 = document.createElement('span');
|
|
138
|
+
ic1.className = 'i-clone1';
|
|
139
|
+
const ic2 = document.createElement('span');
|
|
140
|
+
ic2.className = 'i-clone2';
|
|
141
|
+
const ia = document.createElement('span');
|
|
142
|
+
ia.setAttribute('data-each-after', '');
|
|
143
|
+
inner.append(ib, ic1, ic2, ia);
|
|
144
|
+
middle.append(mb, mc1, mc2, inner, ma);
|
|
145
|
+
// middle は outer の before 内に配置(outer の each で本体は保持される想定)
|
|
146
|
+
ob.appendChild(middle);
|
|
147
|
+
outer.append(ob, oa);
|
|
148
|
+
container.appendChild(outer);
|
|
149
|
+
const frag = getFrag(outer);
|
|
150
|
+
markMounted(frag);
|
|
151
|
+
await expect(Form.reset(frag)).resolves.toBeUndefined();
|
|
152
|
+
// outer 層: before/after 残存
|
|
153
|
+
expect(outer.querySelector('[data-each-before]')).not.toBeNull();
|
|
154
|
+
expect(outer.querySelector('[data-each-after]')).not.toBeNull();
|
|
155
|
+
// middle 層のクローンは削除(DOM 上からも消える)
|
|
156
|
+
expect(outer.querySelector('.m-clone1')).toBeNull();
|
|
157
|
+
expect(outer.querySelector('.m-clone2')).toBeNull();
|
|
158
|
+
// inner 層は本体ごと削除され、クローンも DOM 上に存在しない
|
|
159
|
+
expect(outer.querySelector('article[data-each]')).toBeNull();
|
|
160
|
+
expect(outer.querySelector('.i-clone1')).toBeNull();
|
|
161
|
+
expect(outer.querySelector('.i-clone2')).toBeNull();
|
|
162
|
+
});
|
|
163
|
+
it('複数フォーム混在時に selector 指定の reset で対象フォームのみ each 複製が削除される', async () => {
|
|
164
|
+
// form1 と form2 を用意し、どちらにも each の複製を配置
|
|
165
|
+
const form1 = document.createElement('form');
|
|
166
|
+
form1.id = 'f1';
|
|
167
|
+
const e1 = document.createElement('div');
|
|
168
|
+
e1.setAttribute('data-each', '[]');
|
|
169
|
+
const e1b = document.createElement('div');
|
|
170
|
+
e1b.setAttribute('data-each-before', '');
|
|
171
|
+
const e1c = document.createElement('div');
|
|
172
|
+
e1c.className = 'f1-clone';
|
|
173
|
+
const e1a = document.createElement('div');
|
|
174
|
+
e1a.setAttribute('data-each-after', '');
|
|
175
|
+
e1.append(e1b, e1c, e1a);
|
|
176
|
+
form1.appendChild(e1);
|
|
177
|
+
const form2 = document.createElement('form');
|
|
178
|
+
form2.id = 'f2';
|
|
179
|
+
const e2 = document.createElement('div');
|
|
180
|
+
e2.setAttribute('data-each', '[]');
|
|
181
|
+
const e2b = document.createElement('div');
|
|
182
|
+
e2b.setAttribute('data-each-before', '');
|
|
183
|
+
const e2c = document.createElement('div');
|
|
184
|
+
e2c.className = 'f2-clone';
|
|
185
|
+
const e2a = document.createElement('div');
|
|
186
|
+
e2a.setAttribute('data-each-after', '');
|
|
187
|
+
e2.append(e2b, e2c, e2a);
|
|
188
|
+
form2.appendChild(e2);
|
|
189
|
+
container.append(form1, form2);
|
|
190
|
+
// reset を発火させるボタン
|
|
191
|
+
const button = document.createElement('button');
|
|
192
|
+
button.setAttribute('data-click-reset', '#f1');
|
|
193
|
+
container.appendChild(button);
|
|
194
|
+
const f1 = getFrag(form1);
|
|
195
|
+
const f2 = getFrag(form2);
|
|
196
|
+
const btnFrag = getFrag(button);
|
|
197
|
+
// マウント状態にする(remove() が DOM から除去できるように)
|
|
198
|
+
markMounted(f1);
|
|
199
|
+
markMounted(f2);
|
|
200
|
+
markMounted(btnFrag);
|
|
201
|
+
// Procedure を実行(fetch 無し→成功系フローで reset 実行)
|
|
202
|
+
const Procedure = (await import('../src/procedure')).default;
|
|
203
|
+
const proc = new Procedure(btnFrag, 'click');
|
|
204
|
+
await expect(proc.run()).resolves.toBeUndefined();
|
|
205
|
+
// form1 側の each 複製は削除され、before/after は残る
|
|
206
|
+
expect(form1.querySelector('.f1-clone')).toBeNull();
|
|
207
|
+
expect(form1.querySelector('[data-each-before]')).not.toBeNull();
|
|
208
|
+
expect(form1.querySelector('[data-each-after]')).not.toBeNull();
|
|
209
|
+
// form2 側は影響を受けない(クローンは残存)
|
|
210
|
+
expect(form2.querySelector('.f2-clone')).not.toBeNull();
|
|
211
|
+
expect(form2.querySelector('[data-each-before]')).not.toBeNull();
|
|
212
|
+
expect(form2.querySelector('[data-each-after]')).not.toBeNull();
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
//# sourceMappingURL=reset_each.test.js.map
|