@tanstack/angular-table 9.0.0-alpha.6 → 9.0.0-alpha.8
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/dist/esm2022/flex-render.mjs +3 -3
- package/dist/fesm2022/tanstack-angular-table.mjs +3 -3
- package/package.json +2 -2
- package/src/__tests__/createAngularTable.test.ts +0 -95
- package/src/__tests__/flex-render.test.ts +0 -178
- package/src/__tests__/lazy-init.test.ts +0 -124
- package/src/__tests__/test-setup.ts +0 -12
- package/src/__tests__/test-utils.ts +0 -62
|
@@ -108,10 +108,10 @@ export class FlexRenderDirective {
|
|
|
108
108
|
},
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.
|
|
112
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.
|
|
111
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FlexRenderDirective, deps: [{ token: ViewContainerRef }, { token: TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
112
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.5", type: FlexRenderDirective, isStandalone: true, selector: "[flexRender]", inputs: { content: ["flexRender", "content"], props: ["flexRenderProps", "props"], injector: ["flexRenderInjector", "injector"] }, ngImport: i0 });
|
|
113
113
|
}
|
|
114
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.
|
|
114
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FlexRenderDirective, decorators: [{
|
|
115
115
|
type: Directive,
|
|
116
116
|
args: [{
|
|
117
117
|
selector: '[flexRender]',
|
|
@@ -235,10 +235,10 @@ class FlexRenderDirective {
|
|
|
235
235
|
},
|
|
236
236
|
};
|
|
237
237
|
}
|
|
238
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.
|
|
239
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.
|
|
238
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FlexRenderDirective, deps: [{ token: ViewContainerRef }, { token: TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
239
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.5", type: FlexRenderDirective, isStandalone: true, selector: "[flexRender]", inputs: { content: ["flexRender", "content"], props: ["flexRenderProps", "props"], injector: ["flexRenderInjector", "injector"] }, ngImport: i0 });
|
|
240
240
|
}
|
|
241
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.
|
|
241
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FlexRenderDirective, decorators: [{
|
|
242
242
|
type: Directive,
|
|
243
243
|
args: [{
|
|
244
244
|
selector: '[flexRender]',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/angular-table",
|
|
3
|
-
"version": "9.0.0-alpha.
|
|
3
|
+
"version": "9.0.0-alpha.8",
|
|
4
4
|
"description": "Headless UI for building powerful tables & datagrids for Angular.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"tslib": "^2.6.3",
|
|
46
|
-
"@tanstack/table-core": "9.0.0-alpha.
|
|
46
|
+
"@tanstack/table-core": "9.0.0-alpha.8"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@analogjs/vite-plugin-angular": "^1.5.0",
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
type ColumnDef,
|
|
4
|
-
injectTable,
|
|
5
|
-
getCoreRowModel,
|
|
6
|
-
type Table,
|
|
7
|
-
} from '../index'
|
|
8
|
-
import { Component, input, isSignal, signal, untracked } from '@angular/core'
|
|
9
|
-
import { TestBed } from '@angular/core/testing'
|
|
10
|
-
import { setSignalInputs } from './test-utils'
|
|
11
|
-
|
|
12
|
-
describe('injectTable', () => {
|
|
13
|
-
test('should render with required signal inputs', () => {
|
|
14
|
-
@Component({
|
|
15
|
-
selector: 'app-fake',
|
|
16
|
-
template: ``,
|
|
17
|
-
standalone: true,
|
|
18
|
-
})
|
|
19
|
-
class FakeComponent {
|
|
20
|
-
data = input.required<any[]>()
|
|
21
|
-
|
|
22
|
-
table = injectTable(() => ({
|
|
23
|
-
data: this.data(),
|
|
24
|
-
columns: [],
|
|
25
|
-
getCoreRowModel: getCoreRowModel(),
|
|
26
|
-
}))
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const fixture = TestBed.createComponent(FakeComponent)
|
|
30
|
-
setSignalInputs(fixture.componentInstance, {
|
|
31
|
-
data: [],
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
fixture.detectChanges()
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
describe('Proxy table', () => {
|
|
38
|
-
type Data = { id: string; title: string }
|
|
39
|
-
const data = signal<Data[]>([{ id: '1', title: 'Title' }])
|
|
40
|
-
const columns: ColumnDef<Data>[] = [
|
|
41
|
-
{ id: 'id', header: 'Id', cell: context => context.getValue() },
|
|
42
|
-
{ id: 'title', header: 'Title', cell: context => context.getValue() },
|
|
43
|
-
]
|
|
44
|
-
const table = injectTable(() => ({
|
|
45
|
-
data: data(),
|
|
46
|
-
columns: columns,
|
|
47
|
-
getCoreRowModel: getCoreRowModel(),
|
|
48
|
-
getRowId: row => row.id,
|
|
49
|
-
}))
|
|
50
|
-
const tablePropertyKeys = Object.keys(table())
|
|
51
|
-
|
|
52
|
-
test('table must be a signal', () => {
|
|
53
|
-
expect(isSignal(table)).toEqual(true)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
test('supports "in" operator', () => {
|
|
57
|
-
expect('getCoreRowModel' in table).toBe(true)
|
|
58
|
-
expect('options' in table).toBe(true)
|
|
59
|
-
expect('notFound' in table).toBe(false)
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
test('supports "Object.keys"', () => {
|
|
63
|
-
const keys = Object.keys(table())
|
|
64
|
-
expect(Object.keys(table)).toEqual(keys)
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
test.each(
|
|
68
|
-
tablePropertyKeys.map(property => [
|
|
69
|
-
property,
|
|
70
|
-
testShouldBeComputedProperty(untracked(table), property),
|
|
71
|
-
])
|
|
72
|
-
)('property (%s) is computed -> (%s)', (name, expected) => {
|
|
73
|
-
const tableProperty = table[name as keyof typeof table]
|
|
74
|
-
expect(isSignal(tableProperty)).toEqual(expected)
|
|
75
|
-
})
|
|
76
|
-
})
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
const testShouldBeComputedProperty = (
|
|
80
|
-
table: Table<any>,
|
|
81
|
-
propertyName: string
|
|
82
|
-
) => {
|
|
83
|
-
if (propertyName.endsWith('Handler') || propertyName.endsWith('Model')) {
|
|
84
|
-
return false
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (propertyName.startsWith('get')) {
|
|
88
|
-
// Only properties with no arguments are computed
|
|
89
|
-
const fn = table[propertyName as keyof Table<any>]
|
|
90
|
-
// Cannot test if is lazy computed since we return the unwrapped value
|
|
91
|
-
return fn instanceof Function && fn.length === 0
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return false
|
|
95
|
-
}
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import { Component, ViewChild, input, type TemplateRef } from '@angular/core'
|
|
2
|
-
import { TestBed, type ComponentFixture } from '@angular/core/testing'
|
|
3
|
-
import { createColumnHelper } from '@tanstack/table-core'
|
|
4
|
-
import { skip } from 'node:test'
|
|
5
|
-
import { describe, expect, test } from 'vitest'
|
|
6
|
-
import {
|
|
7
|
-
FlexRenderComponent,
|
|
8
|
-
FlexRenderDirective,
|
|
9
|
-
injectFlexRenderContext,
|
|
10
|
-
} from '../flex-render'
|
|
11
|
-
import { setFixtureSignalInput, setFixtureSignalInputs } from './test-utils'
|
|
12
|
-
|
|
13
|
-
interface Data {
|
|
14
|
-
id: string
|
|
15
|
-
title: string
|
|
16
|
-
description: string
|
|
17
|
-
status: 'success' | 'failed' | 'pending'
|
|
18
|
-
favorite?: boolean
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
describe('FlexRenderDirective', () => {
|
|
22
|
-
const helper = createColumnHelper<Data>()
|
|
23
|
-
|
|
24
|
-
test('should render primitives', async () => {
|
|
25
|
-
const fixture = TestBed.createComponent(TestRenderComponent)
|
|
26
|
-
|
|
27
|
-
// String
|
|
28
|
-
setFixtureSignalInputs(fixture, {
|
|
29
|
-
content: 'My value',
|
|
30
|
-
context: {},
|
|
31
|
-
})
|
|
32
|
-
expectPrimitiveValueIs(fixture, 'My value')
|
|
33
|
-
|
|
34
|
-
// Numbers
|
|
35
|
-
setFixtureSignalInputs(fixture, {
|
|
36
|
-
content: 0,
|
|
37
|
-
context: {},
|
|
38
|
-
})
|
|
39
|
-
expectPrimitiveValueIs(fixture, '0')
|
|
40
|
-
|
|
41
|
-
// Functions that returns primitives
|
|
42
|
-
setFixtureSignalInputs(fixture, {
|
|
43
|
-
content: () => 'My value 2',
|
|
44
|
-
context: {},
|
|
45
|
-
})
|
|
46
|
-
expectPrimitiveValueIs(fixture, 'My value 2')
|
|
47
|
-
|
|
48
|
-
// Null
|
|
49
|
-
setFixtureSignalInputs(fixture, {
|
|
50
|
-
content: () => null,
|
|
51
|
-
context: {},
|
|
52
|
-
})
|
|
53
|
-
expectPrimitiveValueIs(fixture, '')
|
|
54
|
-
|
|
55
|
-
// Undefined
|
|
56
|
-
setFixtureSignalInputs(fixture, {
|
|
57
|
-
content: () => undefined,
|
|
58
|
-
context: {},
|
|
59
|
-
})
|
|
60
|
-
expectPrimitiveValueIs(fixture, '')
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
test('should render TemplateRef', () => {
|
|
64
|
-
@Component({
|
|
65
|
-
template: `
|
|
66
|
-
<ng-template #template let-context>{{ context.property }}</ng-template>
|
|
67
|
-
`,
|
|
68
|
-
standalone: true,
|
|
69
|
-
})
|
|
70
|
-
class FakeTemplateRefComponent {
|
|
71
|
-
@ViewChild('template', { static: true })
|
|
72
|
-
templateRef!: TemplateRef<any>
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const templateRef = TestBed.createComponent(FakeTemplateRefComponent)
|
|
76
|
-
.componentInstance.templateRef
|
|
77
|
-
|
|
78
|
-
const fixture = TestBed.createComponent(TestRenderComponent)
|
|
79
|
-
setFixtureSignalInputs(fixture, {
|
|
80
|
-
content: () => templateRef,
|
|
81
|
-
context: {
|
|
82
|
-
property: 'Property context value',
|
|
83
|
-
},
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
expect(fixture.nativeElement.textContent).toEqual('Property context value')
|
|
87
|
-
|
|
88
|
-
setFixtureSignalInput(fixture, 'context', { property: 'Updated value' })
|
|
89
|
-
fixture.detectChanges()
|
|
90
|
-
|
|
91
|
-
expect(fixture.nativeElement.textContent).toEqual('Updated value')
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
test('should render components', () => {
|
|
95
|
-
@Component({
|
|
96
|
-
template: `{{ context.property }}`,
|
|
97
|
-
standalone: true,
|
|
98
|
-
})
|
|
99
|
-
class FakeComponent {
|
|
100
|
-
context = injectFlexRenderContext<{ property: string }>()
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const fixture = TestBed.createComponent(TestRenderComponent)
|
|
104
|
-
setFixtureSignalInputs(fixture, {
|
|
105
|
-
content: () => new FlexRenderComponent(FakeComponent),
|
|
106
|
-
context: {
|
|
107
|
-
property: 'Context value',
|
|
108
|
-
},
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
expect(fixture.nativeElement.textContent).toEqual('Context value')
|
|
112
|
-
|
|
113
|
-
setFixtureSignalInput(fixture, 'context', { property: 'Updated value' })
|
|
114
|
-
fixture.detectChanges()
|
|
115
|
-
|
|
116
|
-
expect(fixture.nativeElement.textContent).toEqual('Updated value')
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
// Skip for now, test framework (using ComponentRef.setInput) cannot recognize signal inputs
|
|
120
|
-
// as component inputs
|
|
121
|
-
skip('should render custom components', () => {
|
|
122
|
-
@Component({
|
|
123
|
-
template: `{{ row().property }}`,
|
|
124
|
-
standalone: true,
|
|
125
|
-
})
|
|
126
|
-
class FakeComponent {
|
|
127
|
-
row = input.required<{ property: string }>()
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const fixture = TestBed.createComponent(TestRenderComponent)
|
|
131
|
-
setFixtureSignalInputs(fixture, {
|
|
132
|
-
content: () => FakeComponent,
|
|
133
|
-
context: {
|
|
134
|
-
row: {
|
|
135
|
-
property: 'Row value',
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
expect(fixture.nativeElement.textContent).toEqual('Row value')
|
|
141
|
-
|
|
142
|
-
setFixtureSignalInput(fixture, 'context', {
|
|
143
|
-
row: { property: 'Updated value' },
|
|
144
|
-
})
|
|
145
|
-
fixture.detectChanges()
|
|
146
|
-
|
|
147
|
-
expect(fixture.nativeElement.textContent).toEqual('Updated value')
|
|
148
|
-
})
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
@Component({
|
|
152
|
-
selector: 'app-test-render',
|
|
153
|
-
template: `
|
|
154
|
-
<ng-container *flexRender="content(); props: context(); let renderValue">
|
|
155
|
-
<span [innerHTML]="renderValue"></span>
|
|
156
|
-
</ng-container>
|
|
157
|
-
`,
|
|
158
|
-
standalone: true,
|
|
159
|
-
imports: [FlexRenderDirective],
|
|
160
|
-
})
|
|
161
|
-
class TestRenderComponent {
|
|
162
|
-
readonly content = input.required<FlexRenderDirectiveAllowedContent>()
|
|
163
|
-
|
|
164
|
-
readonly context = input.required<Record<string, unknown>>()
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
type FlexRenderDirectiveAllowedContent = FlexRenderDirective<
|
|
168
|
-
NonNullable<unknown>
|
|
169
|
-
>['content']
|
|
170
|
-
|
|
171
|
-
function expectPrimitiveValueIs(
|
|
172
|
-
fixture: ComponentFixture<unknown>,
|
|
173
|
-
value: unknown
|
|
174
|
-
) {
|
|
175
|
-
const span = fixture.nativeElement.querySelector('span')
|
|
176
|
-
expect(span).toBeDefined()
|
|
177
|
-
expect(span.innerHTML).toEqual(value)
|
|
178
|
-
}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'vitest'
|
|
2
|
-
import {
|
|
3
|
-
ChangeDetectionStrategy,
|
|
4
|
-
Component,
|
|
5
|
-
type WritableSignal,
|
|
6
|
-
computed,
|
|
7
|
-
effect,
|
|
8
|
-
input,
|
|
9
|
-
signal,
|
|
10
|
-
} from '@angular/core'
|
|
11
|
-
import { TestBed } from '@angular/core/testing'
|
|
12
|
-
import { lazyInit } from '../lazy-signal-initializer'
|
|
13
|
-
import { flushQueue, setFixtureSignalInputs } from './test-utils'
|
|
14
|
-
|
|
15
|
-
describe('lazyInit', () => {
|
|
16
|
-
test('should init lazily in next tick when not accessing manually', async () => {
|
|
17
|
-
const mockFn = vi.fn()
|
|
18
|
-
|
|
19
|
-
TestBed.runInInjectionContext(() => {
|
|
20
|
-
lazyInit(() => {
|
|
21
|
-
mockFn()
|
|
22
|
-
return {
|
|
23
|
-
data: signal(true),
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
expect(mockFn).not.toHaveBeenCalled()
|
|
29
|
-
|
|
30
|
-
await new Promise(setImmediate)
|
|
31
|
-
|
|
32
|
-
expect(mockFn).toHaveBeenCalled()
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test('should init eagerly accessing manually', async () => {
|
|
36
|
-
const mockFn = vi.fn()
|
|
37
|
-
|
|
38
|
-
TestBed.runInInjectionContext(() => {
|
|
39
|
-
const lazySignal = lazyInit(() => {
|
|
40
|
-
mockFn()
|
|
41
|
-
return {
|
|
42
|
-
data: signal(true),
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
lazySignal.data()
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
expect(mockFn).toHaveBeenCalled()
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
test('should init lazily and only once', async () => {
|
|
53
|
-
const initCallFn = vi.fn()
|
|
54
|
-
const registerDataValue = vi.fn<[number]>()
|
|
55
|
-
|
|
56
|
-
let value!: { data: WritableSignal<number> }
|
|
57
|
-
const outerSignal = signal(0)
|
|
58
|
-
|
|
59
|
-
TestBed.runInInjectionContext(() => {
|
|
60
|
-
value = lazyInit(() => {
|
|
61
|
-
initCallFn()
|
|
62
|
-
|
|
63
|
-
void outerSignal()
|
|
64
|
-
|
|
65
|
-
return { data: signal(0) }
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
effect(() => registerDataValue(value.data()))
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
value.data()
|
|
72
|
-
|
|
73
|
-
await flushQueue()
|
|
74
|
-
|
|
75
|
-
expect(outerSignal).toBeDefined()
|
|
76
|
-
|
|
77
|
-
expect(initCallFn).toHaveBeenCalledTimes(1)
|
|
78
|
-
|
|
79
|
-
outerSignal.set(1)
|
|
80
|
-
await flushQueue()
|
|
81
|
-
outerSignal.set(2)
|
|
82
|
-
await flushQueue()
|
|
83
|
-
value.data.set(4)
|
|
84
|
-
await flushQueue()
|
|
85
|
-
|
|
86
|
-
expect(initCallFn).toHaveBeenCalledTimes(1)
|
|
87
|
-
expect(registerDataValue).toHaveBeenCalledTimes(2)
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
test('should support required signal input', async () => {
|
|
91
|
-
@Component({
|
|
92
|
-
standalone: true,
|
|
93
|
-
template: `{{ call }} - {{ lazySignal.data() }}`,
|
|
94
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
95
|
-
})
|
|
96
|
-
class Test {
|
|
97
|
-
readonly title = input.required<string>()
|
|
98
|
-
call = 0
|
|
99
|
-
|
|
100
|
-
lazySignal = lazyInit(() => {
|
|
101
|
-
this.call++
|
|
102
|
-
return {
|
|
103
|
-
data: computed(() => this.title()),
|
|
104
|
-
}
|
|
105
|
-
})
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const fixture = TestBed.createComponent(Test)
|
|
109
|
-
|
|
110
|
-
setFixtureSignalInputs(fixture, { title: 'newValue' })
|
|
111
|
-
expect(fixture.debugElement.nativeElement.textContent).toBe('0 - newValue')
|
|
112
|
-
await flushQueue()
|
|
113
|
-
|
|
114
|
-
setFixtureSignalInputs(fixture, { title: 'updatedValue' })
|
|
115
|
-
expect(fixture.debugElement.nativeElement.textContent).toBe(
|
|
116
|
-
'1 - updatedValue'
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
setFixtureSignalInputs(fixture, { title: 'newUpdatedValue' })
|
|
120
|
-
expect(fixture.debugElement.nativeElement.textContent).toBe(
|
|
121
|
-
'1 - newUpdatedValue'
|
|
122
|
-
)
|
|
123
|
-
})
|
|
124
|
-
})
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import '@analogjs/vite-plugin-angular/setup-vitest'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
BrowserDynamicTestingModule,
|
|
5
|
-
platformBrowserDynamicTesting,
|
|
6
|
-
} from '@angular/platform-browser-dynamic/testing'
|
|
7
|
-
import { getTestBed } from '@angular/core/testing'
|
|
8
|
-
|
|
9
|
-
getTestBed().initTestEnvironment(
|
|
10
|
-
BrowserDynamicTestingModule,
|
|
11
|
-
platformBrowserDynamicTesting()
|
|
12
|
-
)
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import type { InputSignal } from '@angular/core'
|
|
2
|
-
import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals'
|
|
3
|
-
import type { ComponentFixture } from '@angular/core/testing'
|
|
4
|
-
|
|
5
|
-
type ToSignalInputUpdatableMap<T> = {
|
|
6
|
-
[K in keyof T as T[K] extends InputSignal<any>
|
|
7
|
-
? K
|
|
8
|
-
: never]: T[K] extends InputSignal<infer Value> ? Value : never
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Set required signal input value to component fixture
|
|
13
|
-
* @see https://github.com/angular/angular/issues/54013
|
|
14
|
-
*/
|
|
15
|
-
export function setSignalInputs<T extends NonNullable<unknown>>(
|
|
16
|
-
component: T,
|
|
17
|
-
inputs: ToSignalInputUpdatableMap<T>
|
|
18
|
-
) {
|
|
19
|
-
for (const inputKey in inputs) {
|
|
20
|
-
if (componentHasSignalInputProperty(component, inputKey)) {
|
|
21
|
-
signalSetFn(component[inputKey][SIGNAL], inputs[inputKey])
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function setFixtureSignalInputs<T extends NonNullable<unknown>>(
|
|
27
|
-
componentFixture: ComponentFixture<T>,
|
|
28
|
-
inputs: ToSignalInputUpdatableMap<T>,
|
|
29
|
-
options: { detectChanges: boolean } = { detectChanges: true }
|
|
30
|
-
) {
|
|
31
|
-
setSignalInputs(componentFixture.componentInstance, inputs)
|
|
32
|
-
if (options.detectChanges) {
|
|
33
|
-
componentFixture.detectChanges()
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function setFixtureSignalInput<
|
|
38
|
-
T extends NonNullable<unknown>,
|
|
39
|
-
InputMaps extends ToSignalInputUpdatableMap<T>,
|
|
40
|
-
InputName extends keyof InputMaps,
|
|
41
|
-
>(
|
|
42
|
-
componentFixture: ComponentFixture<T>,
|
|
43
|
-
inputName: InputName,
|
|
44
|
-
value: InputMaps[InputName]
|
|
45
|
-
) {
|
|
46
|
-
setSignalInputs(componentFixture.componentInstance, {
|
|
47
|
-
[inputName]: value,
|
|
48
|
-
} as ToSignalInputUpdatableMap<T>)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function componentHasSignalInputProperty<TProperty extends string>(
|
|
52
|
-
component: object,
|
|
53
|
-
property: TProperty
|
|
54
|
-
): component is { [key in TProperty]: InputSignal<unknown> } {
|
|
55
|
-
return (
|
|
56
|
-
component.hasOwnProperty(property) && (component as any)[property][SIGNAL]
|
|
57
|
-
)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function flushQueue() {
|
|
61
|
-
await new Promise(setImmediate)
|
|
62
|
-
}
|