|
1 | | -import { render, screen } from '@testing-library/react'; |
| 1 | +import { act, render, screen, } from '@testing-library/react'; |
| 2 | +import { observer } from 'mobx-react-lite'; |
| 3 | +import { ReactNode } from 'react'; |
2 | 4 | import { describe, expect, test } from 'vitest'; |
3 | 5 |
|
4 | | -import { ViewModelsContext } from '../contexts'; |
| 6 | +import { ViewModelsProvider } from '..'; |
5 | 7 | import { TestViewModelStoreImpl } from '../view-model/abstract-view-model.store.test'; |
6 | 8 | import { TestViewModelImpl } from '../view-model/view-model.impl.test'; |
7 | 9 |
|
8 | 10 | import { ViewModelProps, withViewModel } from './with-view-model'; |
| 11 | +import { createCounter } from '../utils'; |
| 12 | + |
| 13 | +const createIdGenerator = (prefix?: string) => { |
| 14 | + const counter = createCounter(); |
| 15 | + return () => (prefix || '') + counter().toString() |
| 16 | +} |
9 | 17 |
|
10 | 18 | describe('withViewModel', () => { |
11 | 19 | test('renders', () => { |
12 | 20 | class VM extends TestViewModelImpl { } |
13 | 21 | const View = ({ model }: ViewModelProps<VM>) => { |
14 | 22 | return <div>{`hello ${model.id}`}</div>; |
15 | 23 | }; |
16 | | - const Component = withViewModel(VM)(View); |
| 24 | + const Component = withViewModel(VM, { generateId: createIdGenerator() })(View); |
17 | 25 |
|
18 | 26 | render(<Component />); |
19 | | - expect(screen.getByText('hello VM_0_00000')).toBeDefined(); |
| 27 | + expect(screen.getByText('hello VM_0')).toBeDefined(); |
| 28 | + }); |
| 29 | + |
| 30 | + test('renders nesting', () => { |
| 31 | + class VM1 extends TestViewModelImpl { } |
| 32 | + const View1 = ({ |
| 33 | + children, |
| 34 | + }: ViewModelProps<VM1> & { children?: ReactNode }) => { |
| 35 | + return ( |
| 36 | + <div data-testid="parent-container"> |
| 37 | + <div>parent</div> |
| 38 | + <div>{children}</div> |
| 39 | + </div> |
| 40 | + ); |
| 41 | + }; |
| 42 | + const Component1 = withViewModel(VM1, { generateId: createIdGenerator() })(View1); |
| 43 | + |
| 44 | + const Component2 = withViewModel(class VM2 extends TestViewModelImpl { }, { generateId: createIdGenerator() })( |
| 45 | + () => { |
| 46 | + return <div>child</div>; |
| 47 | + }, |
| 48 | + |
| 49 | + ); |
| 50 | + |
| 51 | + render( |
| 52 | + <Component1> |
| 53 | + <Component2 /> |
| 54 | + </Component1>, |
| 55 | + ); |
| 56 | + expect(screen.getByTestId('parent-container')).toBe(`<div |
| 57 | + data-testid="parent-container" |
| 58 | +> |
| 59 | + <div> |
| 60 | + parent |
| 61 | + </div> |
| 62 | + <div> |
| 63 | + <div> |
| 64 | + child |
| 65 | + </div> |
| 66 | + </div> |
| 67 | +</div>`); |
20 | 68 | }); |
21 | 69 |
|
22 | 70 | test('renders twice', async () => { |
23 | 71 | class VM extends TestViewModelImpl { } |
24 | 72 | const View = ({ model }: ViewModelProps<VM>) => { |
25 | 73 | return <div>{`hello ${model.id}`}</div>; |
26 | 74 | }; |
27 | | - const Component = withViewModel(VM)(View); |
| 75 | + const Component = withViewModel(VM, { generateId: createIdGenerator() })(View); |
28 | 76 |
|
29 | 77 | render( |
30 | 78 | <> |
31 | 79 | <Component /> |
32 | 80 | <Component /> |
33 | 81 | </>, |
34 | 82 | ); |
35 | | - expect(screen.getByText('hello VM_1_00000')).toBeDefined(); |
36 | | - expect(screen.getByText('hello VM_1_00001')).toBeDefined(); |
| 83 | + expect(screen.getByText('hello VM_0')).toBeDefined(); |
| 84 | + expect(screen.getByText('hello VM_1')).toBeDefined(); |
37 | 85 | }); |
38 | 86 |
|
39 | 87 | test('renders with fixed id', () => { |
@@ -63,32 +111,32 @@ describe('withViewModel', () => { |
63 | 111 | expect(await screen.findAllByText('hello my-test')).toHaveLength(2); |
64 | 112 | }); |
65 | 113 |
|
66 | | - test('renders with view model store', () => { |
| 114 | + test('renders with view model store', async () => { |
67 | 115 | class VM extends TestViewModelImpl { } |
68 | | - const View = ({ model }: ViewModelProps<VM>) => { |
69 | | - return <div>{`hello ${model.id}`}</div>; |
70 | | - }; |
| 116 | + const View = observer(({ model }: ViewModelProps<VM>) => { |
| 117 | + return ( |
| 118 | + <div> |
| 119 | + <div>{`hello my friend. Model has id ? ${!!model.id}`}</div> |
| 120 | + </div> |
| 121 | + ); |
| 122 | + }); |
71 | 123 | const Component = withViewModel(VM)(View); |
72 | 124 | const vmStore = new TestViewModelStoreImpl(); |
73 | 125 |
|
74 | | - render( |
75 | | - <div> |
76 | | - 2 |
77 | | - <Component /> |
78 | | - 1 |
79 | | - </div>, |
80 | | - { |
81 | | - wrapper: ({ children }) => { |
82 | | - return ( |
83 | | - <ViewModelsContext.Provider value={vmStore}> |
84 | | - {children} |
85 | | - </ViewModelsContext.Provider> |
86 | | - ); |
87 | | - }, |
88 | | - }, |
| 126 | + const Wrapper = ({ children }: { children?: ReactNode }) => { |
| 127 | + return ( |
| 128 | + <ViewModelsProvider value={vmStore}>{children}</ViewModelsProvider> |
| 129 | + ); |
| 130 | + }; |
| 131 | + |
| 132 | + await act(async () => |
| 133 | + render(<Component />, { |
| 134 | + wrapper: Wrapper, |
| 135 | + }), |
89 | 136 | ); |
90 | 137 |
|
91 | | - screen.debug(); |
92 | | - expect(screen.getByText('hello VM_0_00000')).toBeDefined(); |
| 138 | + expect( |
| 139 | + screen.getByText('hello my friend. Model has id ? true'), |
| 140 | + ).toBeDefined(); |
93 | 141 | }); |
94 | 142 | }); |
0 commit comments