ripple 0.2.68 → 0.2.69

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.
@@ -0,0 +1,282 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { mount, flushSync } from 'ripple';
3
+
4
+ describe('SVG namespace handling', () => {
5
+ let container;
6
+
7
+ function render(component) {
8
+ mount(component, {
9
+ target: container
10
+ });
11
+ }
12
+
13
+ beforeEach(() => {
14
+ container = document.createElement('div');
15
+ document.body.appendChild(container);
16
+ });
17
+
18
+ afterEach(() => {
19
+ document.body.removeChild(container);
20
+ container = null;
21
+ });
22
+
23
+ it('should render static SVG elements with correct namespace', () => {
24
+ component App() {
25
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor">
26
+ <path d="m14 12 4 4 4-4" />
27
+ <circle cx="12" cy="12" r="4" />
28
+ <rect x="4" y="4" width="16" height="16" />
29
+ </svg>
30
+ }
31
+
32
+ render(App);
33
+
34
+ const svg = container.querySelector('svg');
35
+ const path = container.querySelector('path');
36
+ const circle = container.querySelector('circle');
37
+ const rect = container.querySelector('rect');
38
+
39
+ // Verify SVG namespace
40
+ expect(svg).toBeTruthy();
41
+ expect(svg.namespaceURI).toBe('http://www.w3.org/2000/svg');
42
+
43
+ // Verify child elements have SVG namespace
44
+ expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
45
+ expect(circle.namespaceURI).toBe('http://www.w3.org/2000/svg');
46
+ expect(rect.namespaceURI).toBe('http://www.w3.org/2000/svg');
47
+
48
+ // Verify attributes are set correctly
49
+ expect(path.getAttribute('d')).toBe('m14 12 4 4 4-4');
50
+ expect(circle.getAttribute('cx')).toBe('12');
51
+ expect(rect.getAttribute('width')).toBe('16');
52
+ });
53
+
54
+ it('should render dynamic SVG paths with for loop (original issue)', () => {
55
+ component App() {
56
+ const d = ["m14 12 4 4 4-4", "M18 16V7", "m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16", "M3.304 13h6.392"];
57
+
58
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor">
59
+ for (const pathData of d) {
60
+ <path d={pathData} />
61
+ }
62
+ </svg>
63
+ }
64
+
65
+ render(App);
66
+
67
+ const svg = container.querySelector('svg');
68
+ const paths = container.querySelectorAll('path');
69
+
70
+ // Verify SVG container
71
+ expect(svg).toBeTruthy();
72
+ expect(svg.namespaceURI).toBe('http://www.w3.org/2000/svg');
73
+
74
+ // Critical test: dynamic paths should have correct SVG namespace
75
+ expect(paths.length).toBe(4);
76
+ const expectedPaths = ["m14 12 4 4 4-4", "M18 16V7", "m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16", "M3.304 13h6.392"];
77
+ paths.forEach((path, i) => {
78
+ expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
79
+ expect(path.getAttribute('d')).toBe(expectedPaths[i]);
80
+ });
81
+
82
+ // Verify paths are actually SVG elements (should have getBBox method)
83
+ // Note: getBBox might not work in test environment, so just check namespace
84
+ paths.forEach(path => {
85
+ expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
86
+ expect(path.tagName.toLowerCase()).toBe('path');
87
+ });
88
+ });
89
+
90
+ it('should handle mixed static and dynamic SVG elements', () => {
91
+ component App() {
92
+ const dynamicPaths = ["M12 2L2 7v10c0 5.55 3.84 10 9 11 5.16-1 9-5.45 9-11V7l-10-5z"];
93
+
94
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor">
95
+ <circle cx="12" cy="12" r="10" />
96
+ for (const pathData of dynamicPaths) {
97
+ <path d={pathData} />
98
+ }
99
+ <rect x="4" y="4" width="16" height="16" />
100
+ </svg>
101
+ }
102
+
103
+ render(App);
104
+
105
+ const svg = container.querySelector('svg');
106
+ const circle = container.querySelector('circle');
107
+ const path = container.querySelector('path');
108
+ const rect = container.querySelector('rect');
109
+
110
+ // All elements should have SVG namespace
111
+ expect(svg.namespaceURI).toBe('http://www.w3.org/2000/svg');
112
+ expect(circle.namespaceURI).toBe('http://www.w3.org/2000/svg');
113
+ expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
114
+ expect(rect.namespaceURI).toBe('http://www.w3.org/2000/svg');
115
+
116
+ // Verify content
117
+ expect(path.getAttribute('d')).toBe('M12 2L2 7v10c0 5.55 3.84 10 9 11 5.16-1 9-5.45 9-11V7l-10-5z');
118
+ });
119
+
120
+ it('should handle nested SVG groups with for loops', () => {
121
+ component App() {
122
+ const items = [
123
+ { x: "10", y: "10", width: "20", height: "20" },
124
+ { x: "40", y: "40", width: "20", height: "20" }
125
+ ];
126
+
127
+ <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
128
+ <g fill="blue">
129
+ for (const item of items) {
130
+ <rect x={item.x} y={item.y} width={item.width} height={item.height} />
131
+ }
132
+ </g>
133
+ </svg>
134
+ }
135
+
136
+ render(App);
137
+
138
+ const svg = container.querySelector('svg');
139
+ const g = container.querySelector('g');
140
+ const rects = container.querySelectorAll('rect');
141
+
142
+ // Verify namespaces
143
+ expect(svg.namespaceURI).toBe('http://www.w3.org/2000/svg');
144
+ expect(g.namespaceURI).toBe('http://www.w3.org/2000/svg');
145
+ expect(rects.length).toBe(2);
146
+
147
+ rects.forEach(rect => {
148
+ expect(rect.namespaceURI).toBe('http://www.w3.org/2000/svg');
149
+ });
150
+
151
+ // Verify attributes
152
+ expect(rects[0].getAttribute('x')).toBe('10');
153
+ expect(rects[0].getAttribute('y')).toBe('10');
154
+ expect(rects[1].getAttribute('x')).toBe('40');
155
+ expect(rects[1].getAttribute('y')).toBe('40');
156
+ });
157
+
158
+ it('should handle SVG class attributes correctly', () => {
159
+ component App() {
160
+ let className = 'svg-element';
161
+ const paths = ['M10 10 L20 20'];
162
+
163
+ <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" class={className}>
164
+ for (const pathData of paths) {
165
+ <path d={pathData} class="dynamic-path" />
166
+ }
167
+ <circle cx="50" cy="50" r="10" class={className} />
168
+ </svg>
169
+ }
170
+
171
+ render(App);
172
+
173
+ const svg = container.querySelector('svg');
174
+ const path = container.querySelector('path');
175
+ const circle = container.querySelector('circle');
176
+
177
+ // Verify namespaces
178
+ expect(svg.namespaceURI).toBe('http://www.w3.org/2000/svg');
179
+ expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
180
+ expect(circle.namespaceURI).toBe('http://www.w3.org/2000/svg');
181
+
182
+ // Verify class attributes work with SVG elements
183
+ expect(svg.getAttribute('class')).toBe('svg-element');
184
+ expect(path.getAttribute('class')).toBe('dynamic-path');
185
+ expect(circle.getAttribute('class')).toBe('svg-element');
186
+
187
+ // SVG elements should NOT have className property set
188
+ expect(svg.className).not.toBe('svg-element'); // className is different for SVG
189
+ expect(path.className).not.toBe('dynamic-path');
190
+ });
191
+
192
+ it('should handle namespace transitions with foreignObject', () => {
193
+ component App() {
194
+ <svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
195
+ <rect x="10" y="10" width="50" height="50" fill="red" />
196
+ <foreignObject x="100" y="100" width="80" height="80">
197
+ <div class="html-content">{'HTML inside SVG'}</div>
198
+ </foreignObject>
199
+ <circle cx="50" cy="150" r="20" fill="blue" />
200
+ </svg>
201
+ }
202
+
203
+ render(App);
204
+
205
+ const svg = container.querySelector('svg');
206
+ const rect = container.querySelector('rect');
207
+ const foreignObject = container.querySelector('foreignObject');
208
+ const div = container.querySelector('div');
209
+ const circle = container.querySelector('circle');
210
+
211
+ // SVG elements should have SVG namespace
212
+ expect(svg.namespaceURI).toBe('http://www.w3.org/2000/svg');
213
+ expect(rect.namespaceURI).toBe('http://www.w3.org/2000/svg');
214
+ expect(foreignObject.namespaceURI).toBe('http://www.w3.org/2000/svg');
215
+ expect(circle.namespaceURI).toBe('http://www.w3.org/2000/svg');
216
+
217
+ // HTML content inside foreignObject should have HTML namespace
218
+ expect(div.namespaceURI).toBe('http://www.w3.org/1999/xhtml');
219
+ expect(div.textContent).toBe('HTML inside SVG');
220
+ });
221
+
222
+ it('should compare static vs dynamic SVG rendering (original problem case)', () => {
223
+ component App() {
224
+ const d = ["m14 12 4 4 4-4", "M18 16V7", "m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16", "M3.304 13h6.392"];
225
+
226
+ <div class="container">
227
+ {/* Dynamic SVG - the original problem case */}
228
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" class="dynamic-svg">
229
+ for (const path of d) {
230
+ <path d={path} />
231
+ }
232
+ </svg>
233
+
234
+ {/* Static SVG - always worked */}
235
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" class="static-svg">
236
+ <path d="m14 12 4 4 4-4"></path>
237
+ <path d="M18 16V7"></path>
238
+ <path d="m2 16 4.039-9.69a.5.5 0 0 1 .923 0L11 16"></path>
239
+ <path d="M3.304 13h6.392"></path>
240
+ </svg>
241
+ </div>
242
+ }
243
+
244
+ render(App);
245
+
246
+ const dynamicSvg = container.querySelector('.dynamic-svg');
247
+ const staticSvg = container.querySelector('.static-svg');
248
+ const dynamicPaths = dynamicSvg.querySelectorAll('path');
249
+ const staticPaths = staticSvg.querySelectorAll('path');
250
+
251
+ // Both SVGs should have correct namespace
252
+ expect(dynamicSvg.namespaceURI).toBe('http://www.w3.org/2000/svg');
253
+ expect(staticSvg.namespaceURI).toBe('http://www.w3.org/2000/svg');
254
+
255
+ // Both should have same number of paths
256
+ expect(dynamicPaths.length).toBe(4);
257
+ expect(staticPaths.length).toBe(4);
258
+
259
+ // All paths should have SVG namespace
260
+ dynamicPaths.forEach(path => {
261
+ expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
262
+ });
263
+ staticPaths.forEach(path => {
264
+ expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
265
+ });
266
+
267
+ // Dynamic and static should have identical path data
268
+ dynamicPaths.forEach((path, i) => {
269
+ expect(path.getAttribute('d')).toBe(staticPaths[i].getAttribute('d'));
270
+ });
271
+
272
+ // Critical test: all paths should be proper SVG elements
273
+ dynamicPaths.forEach(path => {
274
+ expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
275
+ expect(path.tagName.toLowerCase()).toBe('path');
276
+ });
277
+ staticPaths.forEach(path => {
278
+ expect(path.namespaceURI).toBe('http://www.w3.org/2000/svg');
279
+ expect(path.tagName.toLowerCase()).toBe('path');
280
+ });
281
+ });
282
+ });