ripple 0.3.72 → 0.3.76
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 +116 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +4 -10
- package/src/runtime/dynamic-client.js +33 -0
- package/src/runtime/dynamic-server.js +80 -0
- package/src/runtime/index-client.js +5 -13
- package/src/runtime/index-server.js +2 -0
- package/src/runtime/internal/client/blocks.js +6 -27
- package/src/runtime/internal/client/composite.js +11 -6
- package/src/runtime/internal/client/for.js +80 -5
- package/src/runtime/internal/client/index.js +0 -2
- package/src/runtime/internal/client/render.js +5 -2
- package/src/runtime/internal/client/types.d.ts +0 -10
- package/src/runtime/internal/server/index.js +8 -1
- package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
- package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
- package/tests/client/array/array.copy-within.test.tsrx +19 -19
- package/tests/client/array/array.derived.test.tsrx +97 -109
- package/tests/client/array/array.iteration.test.tsrx +28 -28
- package/tests/client/array/array.mutations.test.tsrx +68 -68
- package/tests/client/array/array.static.test.tsrx +82 -92
- package/tests/client/array/array.to-methods.test.tsrx +15 -15
- package/tests/client/async-suspend.test.tsrx +180 -179
- package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
- package/tests/client/basic/basic.attributes.test.tsrx +273 -317
- package/tests/client/basic/basic.collections.test.tsrx +55 -61
- package/tests/client/basic/basic.components.test.tsrx +198 -220
- package/tests/client/basic/basic.errors.test.tsrx +70 -76
- package/tests/client/basic/basic.events.test.tsrx +80 -85
- package/tests/client/basic/basic.get-set.test.tsrx +54 -64
- package/tests/client/basic/basic.hmr.test.tsrx +15 -19
- package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
- package/tests/client/basic/basic.rendering.test.tsrx +273 -178
- package/tests/client/basic/basic.styling.test.tsrx +16 -14
- package/tests/client/basic/basic.utilities.test.tsrx +8 -10
- package/tests/client/boundaries.test.tsrx +18 -18
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
- package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
- package/tests/client/compiler/compiler.basic.test.tsrx +357 -288
- package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
- package/tests/client/composite/composite.dynamic-components.test.tsrx +62 -47
- package/tests/client/composite/composite.generics.test.tsrx +165 -167
- package/tests/client/composite/composite.props.test.tsrx +66 -74
- package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
- package/tests/client/composite/composite.render.test.tsrx +92 -101
- package/tests/client/computed-properties.test.tsrx +14 -18
- package/tests/client/context.test.tsrx +14 -18
- package/tests/client/css/global-additional-cases.test.tsrx +493 -439
- package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
- package/tests/client/css/global-at-rules.test.tsrx +71 -66
- package/tests/client/css/global-basic.test.tsrx +105 -98
- package/tests/client/css/global-classes-ids.test.tsrx +128 -114
- package/tests/client/css/global-combinators.test.tsrx +83 -78
- package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
- package/tests/client/css/global-edge-cases.test.tsrx +138 -120
- package/tests/client/css/global-keyframes.test.tsrx +108 -96
- package/tests/client/css/global-nested.test.tsrx +88 -78
- package/tests/client/css/global-pseudo.test.tsrx +104 -98
- package/tests/client/css/global-scoping.test.tsrx +145 -125
- package/tests/client/css/style-identifier.test.tsrx +65 -72
- package/tests/client/date.test.tsrx +83 -83
- package/tests/client/dynamic-elements.test.tsrx +318 -299
- package/tests/client/events.test.tsrx +252 -266
- package/tests/client/for.test.tsrx +120 -127
- package/tests/client/head.test.tsrx +74 -48
- package/tests/client/html.test.tsrx +37 -49
- package/tests/client/input-value.test.tsrx +1125 -1354
- package/tests/client/lazy-array.test.tsrx +10 -16
- package/tests/client/lazy-destructuring.test.tsrx +169 -221
- package/tests/client/map.test.tsrx +39 -41
- package/tests/client/media-query.test.tsrx +15 -19
- package/tests/client/object.test.tsrx +46 -56
- package/tests/client/portal.test.tsrx +31 -37
- package/tests/client/ref.test.tsrx +173 -193
- package/tests/client/return.test.tsrx +62 -37
- package/tests/client/set.test.tsrx +33 -33
- package/tests/client/svg.test.tsrx +197 -216
- package/tests/client/switch.test.tsrx +201 -191
- package/tests/client/track-async-hydration.test.tsrx +14 -18
- package/tests/client/tracked-index-access.test.tsrx +18 -28
- package/tests/client/try.test.tsrx +494 -619
- package/tests/client/tsx.test.tsrx +286 -292
- package/tests/client/typescript-generics.test.tsrx +121 -129
- package/tests/client/url/url.derived.test.tsrx +21 -25
- package/tests/client/url/url.parsing.test.tsrx +35 -35
- package/tests/client/url/url.partial-removal.test.tsrx +32 -32
- package/tests/client/url/url.reactivity.test.tsrx +68 -72
- package/tests/client/url/url.serialization.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
- package/tests/hydration/compiled/client/basic.js +390 -319
- package/tests/hydration/compiled/client/composite.js +52 -44
- package/tests/hydration/compiled/client/for.js +734 -604
- package/tests/hydration/compiled/client/head.js +183 -103
- package/tests/hydration/compiled/client/html.js +93 -86
- package/tests/hydration/compiled/client/if-children.js +95 -71
- package/tests/hydration/compiled/client/if.js +113 -89
- package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
- package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
- package/tests/hydration/compiled/client/reactivity.js +26 -24
- package/tests/hydration/compiled/client/return.js +8 -42
- package/tests/hydration/compiled/client/switch.js +208 -173
- package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
- package/tests/hydration/compiled/client/try.js +29 -21
- package/tests/hydration/compiled/server/basic.js +210 -221
- package/tests/hydration/compiled/server/composite.js +13 -14
- package/tests/hydration/compiled/server/for.js +427 -444
- package/tests/hydration/compiled/server/head.js +199 -189
- package/tests/hydration/compiled/server/html.js +33 -41
- package/tests/hydration/compiled/server/if-children.js +114 -117
- package/tests/hydration/compiled/server/if.js +77 -83
- package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
- package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
- package/tests/hydration/compiled/server/reactivity.js +24 -22
- package/tests/hydration/compiled/server/return.js +6 -18
- package/tests/hydration/compiled/server/switch.js +179 -176
- package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
- package/tests/hydration/compiled/server/try.js +31 -35
- package/tests/hydration/components/basic.tsrx +216 -258
- package/tests/hydration/components/composite.tsrx +32 -42
- package/tests/hydration/components/events.tsrx +81 -101
- package/tests/hydration/components/for.tsrx +270 -336
- package/tests/hydration/components/head.tsrx +43 -39
- package/tests/hydration/components/hmr.tsrx +16 -22
- package/tests/hydration/components/html-in-template.tsrx +15 -21
- package/tests/hydration/components/html.tsrx +442 -526
- package/tests/hydration/components/if-children.tsrx +107 -125
- package/tests/hydration/components/if.tsrx +68 -90
- package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
- package/tests/hydration/components/nested-control-flow.tsrx +202 -216
- package/tests/hydration/components/portal.tsrx +33 -41
- package/tests/hydration/components/reactivity.tsrx +26 -34
- package/tests/hydration/components/return.tsrx +4 -6
- package/tests/hydration/components/switch.tsrx +73 -78
- package/tests/hydration/components/track-async-serialization.tsrx +83 -93
- package/tests/hydration/components/try.tsrx +37 -51
- package/tests/hydration/switch.test.js +8 -8
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +117 -162
- package/tests/server/basic.components.test.tsrx +164 -194
- package/tests/server/basic.test.tsrx +299 -199
- package/tests/server/compiler.test.tsrx +142 -72
- package/tests/server/composite.props.test.tsrx +54 -58
- package/tests/server/composite.test.tsrx +165 -167
- package/tests/server/context.test.tsrx +13 -17
- package/tests/server/dynamic-elements.test.tsrx +147 -148
- package/tests/server/for.test.tsrx +115 -84
- package/tests/server/head.test.tsrx +54 -31
- package/tests/server/html-nesting-validation.test.tsrx +16 -8
- package/tests/server/if.test.tsrx +49 -59
- package/tests/server/lazy-destructuring.test.tsrx +288 -366
- package/tests/server/return.test.tsrx +58 -36
- package/tests/server/streaming-ssr.test.tsrx +4 -4
- package/tests/server/style-identifier.test.tsrx +61 -69
- package/tests/server/switch.test.tsrx +89 -97
- package/tests/server/track-async-serialization.test.tsrx +85 -103
- package/tests/server/try.test.tsrx +275 -360
- package/tests/utils/ref-types.test.js +72 -0
- package/tests/utils/vite-plugin-config.test.js +41 -74
- package/types/index.d.ts +29 -4
- package/src/runtime/internal/client/compat.js +0 -40
- package/tests/utils/compiler-compat-config.test.js +0 -38
|
@@ -2,25 +2,26 @@ import { flushSync, track } from 'ripple';
|
|
|
2
2
|
|
|
3
3
|
describe('switch statements', () => {
|
|
4
4
|
it('renders simple switch with literal cases', () => {
|
|
5
|
-
function App() {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
function App() @{
|
|
6
|
+
let &[value] = track('b');
|
|
7
|
+
<>
|
|
8
8
|
<button onClick={() => (value = 'c')}>{'Change to C'}</button>
|
|
9
9
|
<button onClick={() => (value = 'a')}>{'Change to A'}</button>
|
|
10
|
-
switch (value) {
|
|
11
|
-
case 'a':
|
|
12
|
-
<div>
|
|
13
|
-
|
|
14
|
-
case 'b':
|
|
15
|
-
<div>
|
|
16
|
-
|
|
17
|
-
case 'c':
|
|
10
|
+
@switch (value) {
|
|
11
|
+
@case 'a': {
|
|
12
|
+
<div>Case A</div>
|
|
13
|
+
}
|
|
14
|
+
@case 'b': {
|
|
15
|
+
<div>Case B</div>
|
|
16
|
+
}
|
|
17
|
+
@case 'c': {
|
|
18
18
|
<div>{'Case C'}</div>
|
|
19
|
-
|
|
20
|
-
default:
|
|
19
|
+
}
|
|
20
|
+
@default: {
|
|
21
21
|
<div>{'Default Case'}</div>
|
|
22
|
+
}
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
+
</>
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
render(App);
|
|
@@ -37,21 +38,22 @@ describe('switch statements', () => {
|
|
|
37
38
|
});
|
|
38
39
|
|
|
39
40
|
it('renders switch with reactive discriminant', () => {
|
|
40
|
-
function App() {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
function App() @{
|
|
42
|
+
let &[count] = track(1);
|
|
43
|
+
<>
|
|
43
44
|
<button onClick={() => count++}>{'Increment'}</button>
|
|
44
|
-
switch (count) {
|
|
45
|
-
case 1:
|
|
45
|
+
@switch (count) {
|
|
46
|
+
@case 1: {
|
|
46
47
|
<div>{'Count is 1'}</div>
|
|
47
|
-
|
|
48
|
-
case 2:
|
|
48
|
+
}
|
|
49
|
+
@case 2: {
|
|
49
50
|
<div>{'Count is 2'}</div>
|
|
50
|
-
|
|
51
|
-
default:
|
|
51
|
+
}
|
|
52
|
+
@default: {
|
|
52
53
|
<div>{'Count is other'}</div>
|
|
54
|
+
}
|
|
53
55
|
}
|
|
54
|
-
|
|
56
|
+
</>
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
render(App);
|
|
@@ -69,15 +71,18 @@ describe('switch statements', () => {
|
|
|
69
71
|
});
|
|
70
72
|
|
|
71
73
|
it('renders switch with default clause only', () => {
|
|
72
|
-
function App() {
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
function App() @{
|
|
75
|
+
let &[value] = track('x');
|
|
76
|
+
<>
|
|
75
77
|
<button onClick={() => (value = 'y')}>{'Change Value'}</button>
|
|
76
|
-
switch (value) {
|
|
77
|
-
default:
|
|
78
|
-
<div>
|
|
78
|
+
@switch (value) {
|
|
79
|
+
@default: {
|
|
80
|
+
<div>
|
|
81
|
+
{'Default for ' + value}
|
|
82
|
+
</div>
|
|
83
|
+
}
|
|
79
84
|
}
|
|
80
|
-
|
|
85
|
+
</>
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
render(App);
|
|
@@ -89,24 +94,26 @@ describe('switch statements', () => {
|
|
|
89
94
|
expect(container.querySelector('div').textContent).toBe('Default for y');
|
|
90
95
|
});
|
|
91
96
|
|
|
92
|
-
it('renders switch
|
|
93
|
-
function App() {
|
|
94
|
-
|
|
95
|
-
|
|
97
|
+
it('renders switch with isolated empty cases', () => {
|
|
98
|
+
function App() @{
|
|
99
|
+
let &[value] = track('a');
|
|
100
|
+
<>
|
|
96
101
|
<button onClick={() => (value = 'b')}>{'Change to B'}</button>
|
|
97
102
|
<button onClick={() => (value = 'c')}>{'Change to C'}</button>
|
|
98
|
-
switch (value) {
|
|
99
|
-
case 'a':
|
|
100
|
-
<div>
|
|
101
|
-
|
|
102
|
-
case 'b':
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
@switch (value) {
|
|
104
|
+
@case 'a': {
|
|
105
|
+
<div>Case A</div>
|
|
106
|
+
}
|
|
107
|
+
@case 'b': {
|
|
108
|
+
}
|
|
109
|
+
@case 'c': {
|
|
110
|
+
<div>Case B or C</div>
|
|
111
|
+
}
|
|
112
|
+
@default: {
|
|
107
113
|
<div>{'Default Case'}</div>
|
|
114
|
+
}
|
|
108
115
|
}
|
|
109
|
-
|
|
116
|
+
</>
|
|
110
117
|
}
|
|
111
118
|
|
|
112
119
|
render(App);
|
|
@@ -117,7 +124,7 @@ describe('switch statements', () => {
|
|
|
117
124
|
buttonB.click();
|
|
118
125
|
flushSync();
|
|
119
126
|
|
|
120
|
-
expect(container.querySelector('div')
|
|
127
|
+
expect(container.querySelector('div')).toBeNull();
|
|
121
128
|
|
|
122
129
|
buttonC.click();
|
|
123
130
|
flushSync();
|
|
@@ -125,38 +132,47 @@ describe('switch statements', () => {
|
|
|
125
132
|
expect(container.querySelector('div').textContent).toBe('Case B or C');
|
|
126
133
|
|
|
127
134
|
container.querySelector('div').textContent = 'DOM check';
|
|
128
|
-
|
|
135
|
+
buttonC.click();
|
|
129
136
|
flushSync();
|
|
130
137
|
|
|
131
138
|
expect(container.querySelector('div').textContent).toBe('DOM check');
|
|
132
139
|
});
|
|
133
140
|
|
|
134
141
|
it('renders switch with template content and reacts to tracked changes', () => {
|
|
135
|
-
function App() {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
142
|
+
function App() @{
|
|
143
|
+
let &[status] = track('active');
|
|
144
|
+
let &[message] = track('');
|
|
145
|
+
<>
|
|
139
146
|
<button onClick={() => (status = 'pending')}>{'Pending'}</button>
|
|
140
147
|
<button onClick={() => (status = 'completed')}>{'Completed'}</button>
|
|
141
148
|
<button onClick={() => (status = 'error')}>{'Error'}</button>
|
|
142
|
-
switch (status) {
|
|
143
|
-
case 'active':
|
|
149
|
+
@switch (status) {
|
|
150
|
+
@case 'active': {
|
|
144
151
|
message = 'Currently active.';
|
|
145
|
-
<div>
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
<div>
|
|
153
|
+
{'Status: ' + message}
|
|
154
|
+
</div>
|
|
155
|
+
}
|
|
156
|
+
@case 'pending': {
|
|
148
157
|
message = 'Waiting for completion.';
|
|
149
|
-
<div>
|
|
150
|
-
|
|
151
|
-
|
|
158
|
+
<div>
|
|
159
|
+
{'Status: ' + message}
|
|
160
|
+
</div>
|
|
161
|
+
}
|
|
162
|
+
@case 'completed': {
|
|
152
163
|
message = 'Task finished!';
|
|
153
|
-
<div class="success">
|
|
154
|
-
|
|
155
|
-
|
|
164
|
+
<div class="success">
|
|
165
|
+
{'Status: ' + message}
|
|
166
|
+
</div>
|
|
167
|
+
}
|
|
168
|
+
@default: {
|
|
156
169
|
message = 'An error occurred.';
|
|
157
|
-
<div class="error">
|
|
170
|
+
<div class="error">
|
|
171
|
+
{'Status: ' + message}
|
|
172
|
+
</div>
|
|
173
|
+
}
|
|
158
174
|
}
|
|
159
|
-
|
|
175
|
+
</>
|
|
160
176
|
}
|
|
161
177
|
|
|
162
178
|
render(App);
|
|
@@ -182,50 +198,56 @@ describe('switch statements', () => {
|
|
|
182
198
|
});
|
|
183
199
|
|
|
184
200
|
it(
|
|
185
|
-
'renders switch with
|
|
201
|
+
'renders switch with isolated cases and reacts to tracked changes without recreating DOM unnecessarily',
|
|
186
202
|
() => {
|
|
187
|
-
function App() {
|
|
188
|
-
|
|
189
|
-
|
|
203
|
+
function App() @{
|
|
204
|
+
let &[status] = track(0);
|
|
205
|
+
<>
|
|
190
206
|
<div>
|
|
191
|
-
switch (status) {
|
|
192
|
-
case -1:
|
|
193
|
-
|
|
207
|
+
@switch (status) {
|
|
208
|
+
@case -1: {
|
|
209
|
+
}
|
|
210
|
+
@case 0: {
|
|
194
211
|
<p>{' Idle'}</p>
|
|
195
|
-
|
|
212
|
+
}
|
|
213
|
+
@case 1: {
|
|
196
214
|
<p>{' Loading'}</p>
|
|
197
|
-
|
|
215
|
+
}
|
|
216
|
+
@case 2: {
|
|
198
217
|
<p>{' Success'}</p>
|
|
199
|
-
|
|
200
|
-
default:
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
218
|
+
}
|
|
219
|
+
@default: {
|
|
220
|
+
<>
|
|
221
|
+
<p>{' Unknown status'}</p>
|
|
222
|
+
<p>{' Unknown 2'}</p>
|
|
223
|
+
</>
|
|
224
|
+
}
|
|
225
|
+
@case 3: {
|
|
226
|
+
<>
|
|
227
|
+
<p>{' Error'}</p>
|
|
228
|
+
<p>{' Error 2'}</p>
|
|
229
|
+
<p>{' Error 3'}</p>
|
|
230
|
+
</>
|
|
231
|
+
}
|
|
208
232
|
}
|
|
209
233
|
</div>
|
|
210
234
|
<button
|
|
211
235
|
onClick={() => {
|
|
212
236
|
status = (status + 1) % 5;
|
|
213
237
|
}}
|
|
214
|
-
>
|
|
215
|
-
|
|
216
|
-
</button>
|
|
217
|
-
</>;
|
|
238
|
+
>{'Next Status'}</button>
|
|
239
|
+
</>
|
|
218
240
|
}
|
|
219
241
|
|
|
220
242
|
render(App);
|
|
221
243
|
const button = container.querySelector('button');
|
|
222
244
|
|
|
223
|
-
expect(container.querySelector('div').textContent).toBe(' Idle
|
|
245
|
+
expect(container.querySelector('div').textContent).toBe(' Idle');
|
|
224
246
|
|
|
225
247
|
button.click();
|
|
226
248
|
flushSync();
|
|
227
249
|
|
|
228
|
-
expect(container.querySelector('div').textContent).toBe(' Loading
|
|
250
|
+
expect(container.querySelector('div').textContent).toBe(' Loading');
|
|
229
251
|
|
|
230
252
|
button.click();
|
|
231
253
|
flushSync();
|
|
@@ -240,152 +262,140 @@ describe('switch statements', () => {
|
|
|
240
262
|
button.click();
|
|
241
263
|
flushSync();
|
|
242
264
|
|
|
243
|
-
expect(container.querySelector('div').textContent).toBe(
|
|
244
|
-
' Unknown status Unknown 2 Error Error 2 Error 3',
|
|
245
|
-
);
|
|
265
|
+
expect(container.querySelector('div').textContent).toBe(' Unknown status Unknown 2');
|
|
246
266
|
|
|
247
267
|
button.click();
|
|
248
268
|
flushSync();
|
|
249
269
|
|
|
250
|
-
expect(container.querySelector('div').textContent).toBe(' Idle
|
|
270
|
+
expect(container.querySelector('div').textContent).toBe(' Idle');
|
|
251
271
|
},
|
|
252
272
|
);
|
|
253
273
|
|
|
254
|
-
it(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
case 'a':
|
|
267
|
-
<div>{' Case A'}</div>
|
|
268
|
-
break;
|
|
269
|
-
// NOTE: This should be the default in the middle of the cases
|
|
270
|
-
// However, jsdom (and other node-based dom libs) has a bug
|
|
271
|
-
// that breaks out of the switch even if the default doesn't have a break
|
|
272
|
-
// The browser works correctly.
|
|
273
|
-
// So, we're just using a defined case in the middle to simulate default.
|
|
274
|
-
case 'x':
|
|
275
|
-
<div>{' Default Case for ' + value}</div>
|
|
276
|
-
case 'b':
|
|
277
|
-
<div>{' Case B'}</div>
|
|
278
|
-
break;
|
|
279
|
-
case 'c':
|
|
280
|
-
<div>{' Case C'}</div>
|
|
274
|
+
it('renders a middle switch case without falling through to later cases', () => {
|
|
275
|
+
function App() @{
|
|
276
|
+
let &[value] = track('x');
|
|
277
|
+
<>
|
|
278
|
+
<button onClick={() => (value = 'a')}>{'Set A'}</button>
|
|
279
|
+
<button onClick={() => (value = 'b')}>{'Set B'}</button>
|
|
280
|
+
<button onClick={() => (value = 'c')}>{'Set C'}</button>
|
|
281
|
+
<button onClick={() => (value = 'x')}>{'Set X'}</button>
|
|
282
|
+
<div>
|
|
283
|
+
@switch (value) {
|
|
284
|
+
@case 'a': {
|
|
285
|
+
<div>{' Case A'}</div>
|
|
281
286
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
287
|
+
@case 'x': {
|
|
288
|
+
<div>
|
|
289
|
+
{' Default Case for ' + value}
|
|
290
|
+
</div>
|
|
291
|
+
}
|
|
292
|
+
@case 'b': {
|
|
293
|
+
<div>{' Case B'}</div>
|
|
294
|
+
}
|
|
295
|
+
@case 'c': {
|
|
296
|
+
<div>{' Case C'}</div>
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
</div>
|
|
300
|
+
</>
|
|
301
|
+
}
|
|
285
302
|
|
|
286
|
-
|
|
287
|
-
|
|
303
|
+
render(App);
|
|
304
|
+
const [buttonA, buttonB, buttonC, buttonX] = container.querySelectorAll('button');
|
|
288
305
|
|
|
289
|
-
|
|
290
|
-
|
|
306
|
+
expect(container.querySelector('div').textContent).toBe(' Default Case for x');
|
|
307
|
+
expect(container.querySelector('div').querySelectorAll('div').length).toBe(1);
|
|
291
308
|
|
|
292
|
-
|
|
293
|
-
|
|
309
|
+
buttonA.click();
|
|
310
|
+
flushSync();
|
|
294
311
|
|
|
295
|
-
|
|
296
|
-
|
|
312
|
+
expect(container.querySelector('div').textContent).toBe(' Case A');
|
|
313
|
+
expect(container.querySelector('div').querySelectorAll('div').length).toBe(1);
|
|
297
314
|
|
|
298
|
-
|
|
299
|
-
|
|
315
|
+
buttonC.click();
|
|
316
|
+
flushSync();
|
|
300
317
|
|
|
301
|
-
|
|
302
|
-
|
|
318
|
+
expect(container.querySelector('div').textContent).toBe(' Case C');
|
|
319
|
+
expect(container.querySelector('div').querySelectorAll('div').length).toBe(1);
|
|
303
320
|
|
|
304
|
-
|
|
305
|
-
|
|
321
|
+
buttonB.click();
|
|
322
|
+
flushSync();
|
|
306
323
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
324
|
+
const bDiv = container.querySelector('div').querySelectorAll('div')[0];
|
|
325
|
+
expect(bDiv.textContent).toBe(' Case B');
|
|
326
|
+
bDiv.id = 'b';
|
|
310
327
|
|
|
311
|
-
|
|
312
|
-
|
|
328
|
+
buttonX.click();
|
|
329
|
+
flushSync();
|
|
313
330
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
expect(container.querySelector('div').querySelectorAll('div')[1].id).toBe('b');
|
|
319
|
-
},
|
|
320
|
-
);
|
|
331
|
+
expect(container.querySelector('div').textContent).toBe(' Default Case for x');
|
|
332
|
+
expect(container.querySelector('div').querySelectorAll('div').length).toBe(1);
|
|
333
|
+
expect(container.querySelector('#b')).toBeNull();
|
|
334
|
+
});
|
|
321
335
|
|
|
322
|
-
it('renders bare text nodes in switch
|
|
323
|
-
function App() {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
<
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
{'Case A'}
|
|
331
|
-
case 'b':
|
|
332
|
-
{'Case B'}
|
|
336
|
+
it('renders bare text nodes in switch cases without falling through', () => {
|
|
337
|
+
function App() @{
|
|
338
|
+
let value = 'a';
|
|
339
|
+
<div>
|
|
340
|
+
<span>{'before'}</span>
|
|
341
|
+
@switch (value) {
|
|
342
|
+
@case 'a': {
|
|
343
|
+
<>Case A</>
|
|
333
344
|
}
|
|
334
|
-
|
|
335
|
-
|
|
345
|
+
@case 'b': {
|
|
346
|
+
<>Case B</>
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
</div>
|
|
336
350
|
}
|
|
337
351
|
|
|
338
352
|
render(App);
|
|
339
|
-
expect(container.querySelector('div').textContent).toBe('beforeCase
|
|
353
|
+
expect(container.querySelector('div').textContent).toBe('beforeCase A');
|
|
340
354
|
});
|
|
341
355
|
|
|
342
356
|
it('renders bare text nodes in switch cases without element wrappers', () => {
|
|
343
|
-
function App() {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
<
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
{'Case A'}
|
|
351
|
-
break;
|
|
352
|
-
case 'b':
|
|
353
|
-
{'Case B'}
|
|
354
|
-
break;
|
|
357
|
+
function App() @{
|
|
358
|
+
let value = 'a';
|
|
359
|
+
<div>
|
|
360
|
+
<span>{'before'}</span>
|
|
361
|
+
@switch (value) {
|
|
362
|
+
@case 'a': {
|
|
363
|
+
<>Case A</>
|
|
355
364
|
}
|
|
356
|
-
|
|
357
|
-
|
|
365
|
+
@case 'b': {
|
|
366
|
+
<>Case B</>
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
</div>
|
|
358
370
|
}
|
|
359
371
|
|
|
360
372
|
render(App);
|
|
361
373
|
expect(container.querySelector('div').textContent).toBe('beforeCase A');
|
|
362
374
|
});
|
|
363
375
|
|
|
364
|
-
it('renders switch with block-scoped cases
|
|
365
|
-
function App() {
|
|
366
|
-
|
|
367
|
-
|
|
376
|
+
it('renders switch with isolated block-scoped cases', () => {
|
|
377
|
+
function App() @{
|
|
378
|
+
let &[level] = track(1);
|
|
379
|
+
<>
|
|
368
380
|
<button
|
|
369
381
|
onClick={() => {
|
|
370
382
|
if (level === 1) level = 2;
|
|
371
383
|
else if (level === 2) level = 3;
|
|
372
384
|
else level = 1;
|
|
373
385
|
}}
|
|
374
|
-
>
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
switch (level) {
|
|
378
|
-
case 1:
|
|
386
|
+
>{'Toggle'}</button>
|
|
387
|
+
@switch (level) {
|
|
388
|
+
@case 1: {
|
|
379
389
|
<div class="level">{'Level 1'}</div>
|
|
380
|
-
|
|
381
|
-
case 2:
|
|
390
|
+
}
|
|
391
|
+
@case 2: {
|
|
382
392
|
<div class="level">{'Level 2'}</div>
|
|
383
|
-
|
|
384
|
-
case 3:
|
|
393
|
+
}
|
|
394
|
+
@case 3: {
|
|
385
395
|
<div class="level">{'Level 3'}</div>
|
|
386
|
-
|
|
396
|
+
}
|
|
387
397
|
}
|
|
388
|
-
|
|
398
|
+
</>
|
|
389
399
|
}
|
|
390
400
|
|
|
391
401
|
render(App);
|
|
@@ -5,15 +5,13 @@ describe('trackAsync hydration from serialized data (client)', () => {
|
|
|
5
5
|
// This test verifies the client runtime can parse the serialized script tags
|
|
6
6
|
// The full hydration round-trip is tested in hydration tests
|
|
7
7
|
|
|
8
|
-
function App() {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
</>;
|
|
8
|
+
function App() @{
|
|
9
|
+
@try {
|
|
10
|
+
let &[data] = trackAsync(() => Promise.resolve('fallback'));
|
|
11
|
+
<p class="result">{data}</p>
|
|
12
|
+
} @pending {
|
|
13
|
+
<p class="loading">{'loading...'}</p>
|
|
14
|
+
}
|
|
17
15
|
}
|
|
18
16
|
|
|
19
17
|
render(App);
|
|
@@ -31,15 +29,13 @@ describe('trackAsync hydration from serialized data (client)', () => {
|
|
|
31
29
|
let resolve_fn: (value: number) => void;
|
|
32
30
|
const promise = new Promise<number>((r) => (resolve_fn = r));
|
|
33
31
|
|
|
34
|
-
function App() {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
</>;
|
|
32
|
+
function App() @{
|
|
33
|
+
@try {
|
|
34
|
+
let &[value] = trackAsync(() => promise);
|
|
35
|
+
<span class="value">{value}</span>
|
|
36
|
+
} @pending {
|
|
37
|
+
<span class="pending">{'waiting'}</span>
|
|
38
|
+
}
|
|
43
39
|
}
|
|
44
40
|
|
|
45
41
|
render(App);
|
|
@@ -15,11 +15,9 @@ describe('client tracked numeric access', () => {
|
|
|
15
15
|
it('throws when tracked values are accessed through numeric properties', () => {
|
|
16
16
|
let value: any;
|
|
17
17
|
|
|
18
|
-
function Test() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<div />
|
|
22
|
-
</>;
|
|
18
|
+
function Test() @{
|
|
19
|
+
value = track(0);
|
|
20
|
+
<div />
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
render(Test);
|
|
@@ -34,11 +32,9 @@ describe('client tracked numeric access', () => {
|
|
|
34
32
|
it('throws when derived values are accessed through numeric properties', () => {
|
|
35
33
|
let value: any;
|
|
36
34
|
|
|
37
|
-
function Test() {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
<div />
|
|
41
|
-
</>;
|
|
35
|
+
function Test() @{
|
|
36
|
+
value = track(() => 1);
|
|
37
|
+
<div />
|
|
42
38
|
}
|
|
43
39
|
|
|
44
40
|
render(Test);
|
|
@@ -54,12 +50,10 @@ describe('client tracked numeric access', () => {
|
|
|
54
50
|
let value: any;
|
|
55
51
|
let next: any;
|
|
56
52
|
|
|
57
|
-
function Test() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<div />
|
|
62
|
-
</>;
|
|
53
|
+
function Test() @{
|
|
54
|
+
value = track(0);
|
|
55
|
+
next = track(1);
|
|
56
|
+
<div />
|
|
63
57
|
}
|
|
64
58
|
|
|
65
59
|
render(Test);
|
|
@@ -78,12 +72,10 @@ describe('client tracked numeric access', () => {
|
|
|
78
72
|
let value: any;
|
|
79
73
|
let derived: any;
|
|
80
74
|
|
|
81
|
-
function Test() {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<div />
|
|
86
|
-
</>;
|
|
75
|
+
function Test() @{
|
|
76
|
+
value = track(0);
|
|
77
|
+
derived = track(() => value.value + 1);
|
|
78
|
+
<div />
|
|
87
79
|
}
|
|
88
80
|
|
|
89
81
|
render(Test);
|
|
@@ -100,12 +92,10 @@ describe('client tracked numeric access', () => {
|
|
|
100
92
|
let value: any;
|
|
101
93
|
let derived: any;
|
|
102
94
|
|
|
103
|
-
function Test() {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
<div />
|
|
108
|
-
</>;
|
|
95
|
+
function Test() @{
|
|
96
|
+
value = track(0);
|
|
97
|
+
derived = track(() => value.value + 1);
|
|
98
|
+
<div />
|
|
109
99
|
}
|
|
110
100
|
|
|
111
101
|
render(Test);
|