@blueprint-ts/core 4.0.0-beta.8 → 4.0.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 +14 -0
- package/docs/services/pagination/index.md +1 -1
- package/docs/services/pagination/updating-rows.md +16 -0
- package/package.json +1 -1
- package/release-tool.json +1 -1
- package/src/pagination/BasePaginator.ts +19 -0
- package/src/requests/BaseRequest.ts +2 -1
- package/src/vue/forms/validation/rules/EmailRule.ts +1 -1
- package/tests/service/bulkRequests/BulkRequestSender.test.ts +76 -0
- package/tests/service/bulkRequests/BulkRequestWrapper.test.ts +51 -0
- package/tests/service/pagination/BasePaginator.test.ts +100 -0
- package/tests/service/pagination/InfiniteScroller.test.ts +101 -0
- package/tests/service/pagination/PageAwarePaginator.test.ts +133 -0
- package/tests/service/pagination/StatePaginator.test.ts +76 -0
- package/tests/service/pagination/VueViewDrivers.test.ts +46 -0
- package/tests/service/pagination/dtos/StatePaginationDataDto.test.ts +14 -0
- package/tests/service/persistenceDrivers/PersistenceDrivers.test.ts +56 -0
- package/tests/service/requests/BaseRequest.test.ts +199 -0
- package/tests/service/requests/BodiesAndFactories.test.ts +28 -0
- package/tests/service/requests/Enums.test.ts +19 -0
- package/tests/service/requests/ErrorHandler.test.ts +45 -1
- package/tests/service/requests/RequestErrorRouter.test.ts +44 -0
- package/tests/service/requests/Responses.test.ts +83 -0
- package/tests/service/requests/exceptions/Exceptions.test.ts +43 -0
- package/tests/service/requests/fetch/FetchDriver.test.ts +76 -0
- package/tests/service/requests/fetch/FetchResponse.test.ts +21 -0
- package/tests/service/support/DeferredPromise.test.ts +40 -0
- package/tests/service/support/helpers.test.ts +37 -0
- package/tests/vue/composables/useConfirmDialog.test.ts +77 -0
- package/tests/vue/composables/useGlobalCheckbox.test.ts +126 -0
- package/tests/vue/composables/useIsEmpty.test.ts +18 -0
- package/tests/vue/composables/useIsOpen.test.ts +25 -0
- package/tests/vue/composables/useIsOpenFromVar.test.ts +22 -0
- package/tests/vue/composables/useModelWrapper.test.ts +30 -0
- package/tests/vue/composables/useOnOpen.test.ts +26 -0
- package/tests/vue/forms/PropertyAwareArray.test.ts +30 -0
- package/tests/vue/forms/validation/ValidationRules.test.ts +79 -0
- package/tests/vue/requests/VueRequestLoaders.test.ts +48 -0
- package/tests/vue/router/routeResourceBinding/RouteResourceUtils.test.ts +70 -0
- package/tests/vue/state/State.test.ts +151 -0
- package/vitest.config.ts +10 -1
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { nextTick } from 'vue'
|
|
3
|
+
import { State } from '../../../src/vue/state/State'
|
|
4
|
+
import type { PersistenceDriver } from '../../../src/persistenceDrivers/types/PersistenceDriver'
|
|
5
|
+
|
|
6
|
+
class MemoryDriver implements PersistenceDriver {
|
|
7
|
+
public store = new Map<string, unknown>()
|
|
8
|
+
|
|
9
|
+
get<T>(key: string): T | null {
|
|
10
|
+
return (this.store.get(key) as T) ?? null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
set<T>(key: string, state: T): void {
|
|
14
|
+
this.store.set(key, state)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
remove(key: string): void {
|
|
18
|
+
this.store.delete(key)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let driver: MemoryDriver
|
|
23
|
+
|
|
24
|
+
class TestState extends State<{ count: number; nested: { value: string }; items: number[] }> {
|
|
25
|
+
protected getPersistenceDriver(): PersistenceDriver {
|
|
26
|
+
return driver
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe('State', () => {
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
driver = new MemoryDriver()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('exposes proxy access and deep exports', () => {
|
|
36
|
+
const state = new TestState({ count: 1, nested: { value: 'a' }, items: [1] })
|
|
37
|
+
|
|
38
|
+
state.state.count = 2
|
|
39
|
+
expect(state.state.count).toBe(2)
|
|
40
|
+
|
|
41
|
+
const exported = state.export()
|
|
42
|
+
exported.nested.value = 'changed'
|
|
43
|
+
|
|
44
|
+
expect(state.state.nested.value).toBe('a')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('imports values and persists when enabled', () => {
|
|
48
|
+
const state = new TestState(
|
|
49
|
+
{ count: 1, nested: { value: 'a' }, items: [1] },
|
|
50
|
+
{ persist: true }
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
state.import({ count: 5 })
|
|
54
|
+
|
|
55
|
+
expect(state.state.count).toBe(5)
|
|
56
|
+
expect(driver.get(state.persistKey)).toEqual({ count: 5, nested: { value: 'a' }, items: [1] })
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('loads persisted values when keys match', () => {
|
|
60
|
+
driver.set('TestState', { count: 9, nested: { value: 'persisted' }, items: [2] })
|
|
61
|
+
|
|
62
|
+
const state = new TestState({ count: 1, nested: { value: 'a' }, items: [1] }, { persist: true })
|
|
63
|
+
|
|
64
|
+
expect(state.state.count).toBe(9)
|
|
65
|
+
expect(state.state.nested.value).toBe('persisted')
|
|
66
|
+
expect(state.state.items).toEqual([2])
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('clears persisted values when keys mismatch', () => {
|
|
70
|
+
driver.set('TestState', { count: 9 })
|
|
71
|
+
|
|
72
|
+
const state = new TestState({ count: 1, nested: { value: 'a' }, items: [1] }, { persist: true })
|
|
73
|
+
|
|
74
|
+
expect(driver.get(state.persistKey)).toBeNull()
|
|
75
|
+
expect(state.state.count).toBe(1)
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('subscribes to top-level and nested changes', async () => {
|
|
79
|
+
const state = new TestState({ count: 1, nested: { value: 'a' }, items: [] })
|
|
80
|
+
|
|
81
|
+
const countHandler = vi.fn()
|
|
82
|
+
const nestedHandler = vi.fn()
|
|
83
|
+
|
|
84
|
+
const stopCount = state.subscribe('count', countHandler)
|
|
85
|
+
const stopNested = state.subscribe('nested.value', nestedHandler)
|
|
86
|
+
|
|
87
|
+
state.state.count = 2
|
|
88
|
+
state.state.nested.value = 'b'
|
|
89
|
+
|
|
90
|
+
await nextTick()
|
|
91
|
+
|
|
92
|
+
expect(countHandler).toHaveBeenCalledTimes(1)
|
|
93
|
+
expect(nestedHandler).toHaveBeenCalledTimes(1)
|
|
94
|
+
|
|
95
|
+
stopCount()
|
|
96
|
+
stopNested()
|
|
97
|
+
|
|
98
|
+
state.state.count = 3
|
|
99
|
+
await nextTick()
|
|
100
|
+
expect(countHandler).toHaveBeenCalledTimes(1)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
it('supports array path subscriptions and reset handlers', async () => {
|
|
104
|
+
const state = new TestState({ count: 1, nested: { value: 'a' }, items: [] })
|
|
105
|
+
|
|
106
|
+
const handler = vi.fn()
|
|
107
|
+
state.subscribe(['count', 'nested.value'], handler, { executeOnReset: true })
|
|
108
|
+
|
|
109
|
+
state.reset()
|
|
110
|
+
|
|
111
|
+
await nextTick()
|
|
112
|
+
|
|
113
|
+
const calls = handler.mock.calls.map((call) => call[0])
|
|
114
|
+
expect(calls).toContain('count')
|
|
115
|
+
expect(calls).toContain('nested.value')
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('debounces change handlers', async () => {
|
|
119
|
+
vi.useFakeTimers()
|
|
120
|
+
|
|
121
|
+
const state = new TestState({ count: 1, nested: { value: 'a' }, items: [] })
|
|
122
|
+
const handler = vi.fn()
|
|
123
|
+
|
|
124
|
+
state.subscribe('count', handler, { debounce: 50 })
|
|
125
|
+
state.state.count = 2
|
|
126
|
+
|
|
127
|
+
await nextTick()
|
|
128
|
+
expect(handler).not.toHaveBeenCalled()
|
|
129
|
+
|
|
130
|
+
vi.advanceTimersByTime(50)
|
|
131
|
+
await nextTick()
|
|
132
|
+
|
|
133
|
+
expect(handler).toHaveBeenCalledTimes(1)
|
|
134
|
+
|
|
135
|
+
vi.useRealTimers()
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('destroys watchers and clears internal state', async () => {
|
|
139
|
+
const state = new TestState({ count: 1, nested: { value: 'a' }, items: [] })
|
|
140
|
+
const handler = vi.fn()
|
|
141
|
+
|
|
142
|
+
state.subscribe('count', handler)
|
|
143
|
+
|
|
144
|
+
state.destroy()
|
|
145
|
+
|
|
146
|
+
state.state.count = 2
|
|
147
|
+
await nextTick()
|
|
148
|
+
|
|
149
|
+
expect(handler).not.toHaveBeenCalled()
|
|
150
|
+
})
|
|
151
|
+
})
|
package/vitest.config.ts
CHANGED
|
@@ -8,7 +8,16 @@ export default mergeConfig(
|
|
|
8
8
|
test: {
|
|
9
9
|
environment: 'jsdom',
|
|
10
10
|
exclude: [...configDefaults.exclude, 'e2e/*'],
|
|
11
|
-
root: fileURLToPath(new URL('./', import.meta.url))
|
|
11
|
+
root: fileURLToPath(new URL('./', import.meta.url)),
|
|
12
|
+
reporters: ['default', 'json'],
|
|
13
|
+
outputFile: { json: 'vitest-results.json' },
|
|
14
|
+
coverage: {
|
|
15
|
+
provider: 'v8',
|
|
16
|
+
reportsDirectory: 'coverage',
|
|
17
|
+
reporter: ['text', 'text-summary', 'json-summary', 'lcov', 'json'],
|
|
18
|
+
include: ['src/**/*.ts'],
|
|
19
|
+
exclude: ['**/*.d.ts']
|
|
20
|
+
}
|
|
12
21
|
}
|
|
13
22
|
})
|
|
14
23
|
)
|