2 #ifndef SEEN_ATTRIBUTES_TEST_H
3 #define SEEN_ATTRIBUTES_TEST_H
5 #include <cxxtest/TestSuite.h>
7 #include <vector>
8 #include <glib.h>
9 #include <glib/gprintf.h>
10 #include "attributes.h"
11 #include "streq.h"
13 class AttributesTest : public CxxTest::TestSuite
14 {
15 public:
17 AttributesTest()
18 {
19 }
20 virtual ~AttributesTest() {}
22 // createSuite and destroySuite get us per-suite setup and teardown
23 // without us having to worry about static initialization order, etc.
24 static AttributesTest *createSuite() { return new AttributesTest(); }
25 static void destroySuite( AttributesTest *suite ) { delete suite; }
28 void testAttributes()
29 {
30 /* Extracted mechanically from http://www.w3.org/TR/SVG11/attindex.html:
32 tidy -wrap 999 -asxml < attindex.html 2>/dev/null |
33 tr -d \\n |
34 sed 's,<tr>,@,g' |
35 tr @ \\n |
36 sed 's,</td>.*,,;s,^<td>,,;1,/^%/d;/^%/d;s,^, {",;s/$/", false},/' |
37 uniq
39 attindex.html lacks attributeName, begin, additive, font, marker;
40 I've added these manually.
41 */
42 struct {char const *attr; bool supported;} const all_attrs[] = {
43 {"attributeName", true},
44 {"begin", true},
45 {"additive", true},
46 {"font", true},
47 {"marker", true},
48 {"line-height", true},
50 {"accent-height", false},
51 {"accumulate", true},
52 {"alignment-baseline", true},
53 {"alphabetic", false},
54 {"amplitude", true},
55 {"animate", false},
56 {"arabic-form", false},
57 {"ascent", false},
58 {"attributeType", true},
59 {"azimuth", true},
60 {"baseFrequency", true},
61 {"baseline-shift", true},
62 {"baseProfile", false},
63 {"bbox", false},
64 {"bias", true},
65 {"block-progression", true},
66 {"by", true},
67 {"calcMode", true},
68 {"cap-height", false},
69 {"class", false},
70 {"clip", true},
71 {"clip-path", true},
72 {"clip-rule", true},
73 {"clipPathUnits", true},
74 {"color", true},
75 {"color-interpolation", true},
76 {"color-interpolation-filters", true},
77 {"color-profile", true},
78 {"color-rendering", true},
79 {"contentScriptType", false},
80 {"contentStyleType", false},
81 {"cursor", true},
82 {"cx", true},
83 {"cy", true},
84 {"d", true},
85 {"descent", false},
86 {"diffuseConstant", true},
87 {"direction", true},
88 {"display", true},
89 {"divisor", true},
90 {"dominant-baseline", true},
91 {"dur", true},
92 {"dx", true},
93 {"dy", true},
94 {"edgeMode", true},
95 {"elevation", true},
96 {"enable-background", true},
97 {"end", true},
98 {"exponent", true},
99 {"externalResourcesRequired", false},
100 {"feBlend", false},
101 {"feColorMatrix", false},
102 {"feComponentTransfer", false},
103 {"feComposite", false},
104 {"feConvolveMatrix", false},
105 {"feDiffuseLighting", false},
106 {"feDisplacementMap", false},
107 {"feFlood", false},
108 {"feGaussianBlur", false},
109 {"feImage", false},
110 {"feMerge", false},
111 {"feMorphology", false},
112 {"feOffset", false},
113 {"feSpecularLighting", false},
114 {"feTile", false},
115 {"fill", true},
116 {"fill-opacity", true},
117 {"fill-rule", true},
118 {"filter", true},
119 {"filterRes", true},
120 {"filterUnits", true},
121 {"flood-color", true},
122 {"flood-opacity", true},
123 {"font-family", true},
124 {"font-size", true},
125 {"font-size-adjust", true},
126 {"font-stretch", true},
127 {"font-style", true},
128 {"font-variant", true},
129 {"font-weight", true},
130 {"format", false},
131 {"from", true},
132 {"fx", true},
133 {"fy", true},
134 {"g1", false},
135 {"g2", false},
136 {"glyph-name", false},
137 {"glyph-orientation-horizontal", true},
138 {"glyph-orientation-vertical", true},
139 {"glyphRef", false},
140 {"gradientTransform", true},
141 {"gradientUnits", true},
142 {"hanging", false},
143 {"height", true},
144 {"horiz-adv-x", false},
145 {"horiz-origin-x", false},
146 {"horiz-origin-y", false},
147 {"ideographic", false},
148 {"image-rendering", true},
149 {"in", true},
150 {"in2", true},
151 {"intercept", true},
152 {"k", false},
153 {"k1", true},
154 {"k2", true},
155 {"k3", true},
156 {"k4", true},
157 {"kernelMatrix", true},
158 {"kernelUnitLength", true},
159 {"kerning", true},
160 {"keyPoints", false},
161 {"keySplines", true},
162 {"keyTimes", true},
163 {"lang", false},
164 {"lengthAdjust", false},
165 {"letter-spacing", true},
166 {"lighting-color", true},
167 {"limitingConeAngle", true},
168 {"local", true},
169 {"marker-end", true},
170 {"marker-mid", true},
171 {"marker-start", true},
172 {"markerHeight", true},
173 {"markerUnits", true},
174 {"markerWidth", true},
175 {"mask", true},
176 {"maskContentUnits", true},
177 {"maskUnits", true},
178 {"mathematical", false},
179 {"max", true},
180 {"media", false},
181 {"method", false},
182 {"min", true},
183 {"mode", true},
184 {"name", true},
185 {"numOctaves", true},
186 {"offset", true},
187 {"onabort", false},
188 {"onactivate", false},
189 {"onbegin", false},
190 {"onclick", false},
191 {"onend", false},
192 {"onerror", false},
193 {"onfocusin", false},
194 {"onfocusout", false},
195 {"onload", false},
196 {"onmousedown", false},
197 {"onmousemove", false},
198 {"onmouseout", false},
199 {"onmouseover", false},
200 {"onmouseup", false},
201 {"onrepeat", false},
202 {"onresize", false},
203 {"onscroll", false},
204 {"onunload", false},
205 {"onzoom", false},
206 {"opacity", true},
207 {"operator", true},
208 {"order", true},
209 {"orient", true},
210 {"orientation", true},
211 {"origin", false},
212 {"overflow", true},
213 {"overline-position", false},
214 {"overline-thickness", false},
215 {"panose-1", false},
216 {"path", false},
217 {"pathLength", false},
218 {"patternContentUnits", true},
219 {"patternTransform", true},
220 {"patternUnits", true},
221 {"pointer-events", true},
222 {"points", true},
223 {"pointsAtX", true},
224 {"pointsAtY", true},
225 {"pointsAtZ", true},
226 {"preserveAlpha", true},
227 {"preserveAspectRatio", true},
228 {"primitiveUnits", true},
229 {"r", true},
230 {"radius", true},
231 {"refX", true},
232 {"refY", true},
233 {"rendering-intent", true},
234 {"repeatCount", true},
235 {"repeatDur", true},
236 {"requiredFeatures", true},
237 {"requiredExtensions", true},
238 {"restart", true},
239 {"result", true},
240 {"rotate", true},
241 {"rx", true},
242 {"ry", true},
243 {"scale", true},
244 {"seed", true},
245 {"shape-rendering", true},
246 {"slope", true},
247 {"spacing", false},
248 {"specularConstant", true},
249 {"specularExponent", true},
250 {"spreadMethod", true},
251 {"startOffset", true},
252 {"stdDeviation", true},
253 {"stemh", false},
254 {"stemv", false},
255 {"stitchTiles", true},
256 {"stop-color", true},
257 {"stop-opacity", true},
258 {"strikethrough-position", false},
259 {"strikethrough-thickness", false},
260 {"stroke", true},
261 {"stroke-dasharray", true},
262 {"stroke-dashoffset", true},
263 {"stroke-linecap", true},
264 {"stroke-linejoin", true},
265 {"stroke-miterlimit", true},
266 {"stroke-opacity", true},
267 {"stroke-width", true},
268 {"style", true},
269 {"surfaceScale", true},
270 {"systemLanguage", true},
271 {"tableValues", true},
272 {"target", true},
273 {"targetX", true},
274 {"targetY", true},
275 {"text-align", true},
276 {"text-anchor", true},
277 {"text-decoration", true},
278 {"text-indent", true},
279 {"text-rendering", true},
280 {"text-transform", true},
281 {"textLength", false},
282 {"title", false},
283 {"to", true},
284 {"transform", true},
285 {"type", true},
286 {"u1", false},
287 {"u2", false},
288 {"underline-position", false},
289 {"underline-thickness", false},
290 {"unicode", false},
291 {"unicode-bidi", true},
292 {"unicode-range", false},
293 {"units-per-em", false},
294 {"v-alphabetic", false},
295 {"v-hanging", false},
296 {"v-ideographic", false},
297 {"v-mathematical", false},
298 {"values", true},
299 {"version", true},
300 {"vert-adv-y", false},
301 {"vert-origin-x", false},
302 {"vert-origin-y", false},
303 {"viewBox", true},
304 {"viewTarget", false},
305 {"visibility", true},
306 {"width", true},
307 {"widths", false},
308 {"word-spacing", true},
309 {"writing-mode", true},
310 {"x", true},
311 {"x-height", false},
312 {"x1", true},
313 {"x2", true},
314 {"xChannelSelector", true},
315 {"xlink:actuate", true},
316 {"xlink:arcrole", true},
317 {"xlink:href", true},
318 {"xlink:role", true},
319 {"xlink:show", true},
320 {"xlink:title", true},
321 {"xlink:type", true},
322 {"xml:base", false},
323 {"xml:space", true},
324 {"xmlns", false},
325 {"xmlns:xlink", false},
326 {"y", true},
327 {"y1", true},
328 {"y2", true},
329 {"yChannelSelector", true},
330 {"z", true},
331 {"zoomAndPan", false},
333 /* Extra attributes. */
334 {"id", true},
335 {"inkscape:collect", true},
336 {"inkscape:document-units", true},
337 {"inkscape:label", true},
338 {"sodipodi:insensitive", true},
339 {"sodipodi:nonprintable", true},
340 {"inkscape:groupmode", true},
341 {"sodipodi:version", true},
342 {"inkscape:version", true},
343 {"inkscape:object-paths", true},
344 {"inkscape:object-nodes", true},
345 {"inkscape:bbox-paths", true},
346 {"inkscape:bbox-nodes", true},
347 {"inkscape:snap-page", true},
348 {"inkscape:snap-global", true},
349 {"inkscape:snap-bbox", true},
350 {"inkscape:snap-nodes", true},
351 {"inkscape:snap-from-guide", true},
352 {"inkscape:snap-center", true},
353 {"inkscape:snap-smooth-nodes", true},
354 {"inkscape:snap-midpoints", true},
355 {"inkscape:snap-object-midpoints", true},
356 {"inkscape:snap-bbox-edge-midpoints", true},
357 {"inkscape:snap-bbox-midpoints", true},
358 //{"inkscape:snap-intersection-grid-guide", true},
359 {"inkscape:snap-grids", true},
360 {"inkscape:snap-to-guides", true},
361 {"inkscape:snap-intersection-paths", true},
362 {"inkscape:pageopacity", true},
363 {"inkscape:pageshadow", true},
364 {"inkscape:transform-center-x", true},
365 {"inkscape:transform-center-y", true},
366 {"inkscape:zoom", true},
367 {"inkscape:cx", true},
368 {"inkscape:cy", true},
369 {"inkscape:window-width", true},
370 {"inkscape:window-height", true},
371 {"inkscape:window-x", true},
372 {"inkscape:window-y", true},
373 {"inkscape:current-layer", true},
374 {"inkscape:connector-type", true},
375 {"inkscape:connection-start", true},
376 {"inkscape:connection-end", true},
377 {"inkscape:connector-avoid", true},
378 {"inkscape:connector-spacing", true},
379 {"sodipodi:cx", true},
380 {"sodipodi:cy", true},
381 {"sodipodi:rx", true},
382 {"sodipodi:ry", true},
383 {"inkscape:perspectiveID", true},
384 {"inkscape:corner0", true},
385 {"inkscape:corner7", true},
386 {"inkscape:box3dsidetype", true},
387 {"inkscape:persp3d", true},
388 {"inkscape:vp_x", true},
389 {"inkscape:vp_y", true},
390 {"inkscape:vp_z", true},
391 {"inkscape:persp3d-origin", true},
392 {"sodipodi:start", true},
393 {"sodipodi:end", true},
394 {"sodipodi:open", true},
395 {"sodipodi:sides", true},
396 {"sodipodi:r1", true},
397 {"sodipodi:r2", true},
398 {"sodipodi:arg1", true},
399 {"sodipodi:arg2", true},
400 {"inkscape:flatsided", true},
401 {"inkscape:rounded", true},
402 {"inkscape:randomized", true},
403 {"sodipodi:expansion", true},
404 {"sodipodi:revolution", true},
405 {"sodipodi:radius", true},
406 {"sodipodi:argument", true},
407 {"sodipodi:t0", true},
408 {"sodipodi:original", true},
409 {"inkscape:original", true},
410 {"inkscape:href", true},
411 {"inkscape:radius", true},
412 {"sodipodi:role", true},
413 {"sodipodi:linespacing", true},
414 {"inkscape:srcNoMarkup", true},
415 {"inkscape:srcPango", true},
416 {"inkscape:dstShape", true},
417 {"inkscape:dstPath", true},
418 {"inkscape:dstBox", true},
419 {"inkscape:dstColumn", true},
420 {"inkscape:excludeShape", true},
421 {"inkscape:layoutOptions", true},
423 /* SPNamedView */
424 {"viewonly", true},
425 {"showgrid", true},
426 // {"gridtype", true},
427 {"showguides", true},
428 {"gridtolerance", true},
429 {"guidetolerance", true},
430 {"objecttolerance", true},
431 /* {"gridoriginx", true},
432 {"gridoriginy", true},
433 {"gridspacingx", true},
434 {"gridspacingy", true},
435 {"gridanglex", true},
436 {"gridanglez", true},
437 {"gridcolor", true},
438 {"gridopacity", true},
439 {"gridempcolor", true},
440 {"gridempopacity", true},
441 {"gridempspacing", true}, */
442 {"guidecolor", true},
443 {"guideopacity", true},
444 {"guidehicolor", true},
445 {"guidehiopacity", true},
446 {"showborder", true},
447 {"inkscape:showpageshadow", true},
448 {"borderlayer", true},
449 {"bordercolor", true},
450 {"borderopacity", true},
451 {"pagecolor", true},
453 /* SPGuide */
454 {"position", true}
456 };
460 std::vector<bool> ids;
461 ids.reserve(256);
463 for (unsigned i = 0; i < G_N_ELEMENTS(all_attrs); ++i) {
464 char const *const attr_str = all_attrs[i].attr;
465 unsigned const id = sp_attribute_lookup(attr_str);
466 bool const recognized(id);
467 TSM_ASSERT_EQUALS( std::string(all_attrs[i].attr), recognized, all_attrs[i].supported );
468 if (recognized) {
469 if (ids.size() <= id) {
470 ids.resize(id + 1);
471 }
472 TS_ASSERT(!ids[id]);
473 ids[id] = true;
475 unsigned char const *reverse_ustr = sp_attribute_name(id);
476 char const *reverse_str = reinterpret_cast<char const *>(reverse_ustr);
477 TS_ASSERT(streq(reverse_str, attr_str));
478 }
479 }
481 /* Test for any attributes that this test program doesn't know about.
482 *
483 * If any are found, then:
484 *
485 * If it is in the `inkscape:' namespace then simply add it to all_attrs with
486 * `true' as the second field (`supported').
487 *
488 * If it is in the `sodipodi:' namespace then check the spelling against sodipodi
489 * sources. If you don't have sodipodi sources, then don't add it: leave to someone
490 * else.
491 *
492 * Otherwise, it's probably a bug: ~all SVG 1.1 attributes should already be
493 * in the all_attrs table. However, the comment above all_attrs does mention
494 * some things missing from attindex.html, so there may be more. Check the SVG
495 * spec. Another possibility is that the attribute is new in SVG 1.2. In this case,
496 * check the spelling against the [draft] SVG 1.2 spec before adding to all_attrs.
497 * (If you can't be bothered checking the spec, then don't update all_attrs.)
498 *
499 * If the attribute isn't in either SVG 1.1 or 1.2 then it's probably a mistake
500 * for it not to be in the inkscape namespace. (Not sure about attributes used only
501 * on elements in the inkscape namespace though.)
502 *
503 * In any case, make sure that the attribute's source is documented accordingly.
504 */
505 bool found = false;
506 unsigned const n_ids = ids.size();
507 for (unsigned id = 1; id < n_ids; ++id) {
508 if (!ids[id]) {
509 gchar* tmp = g_strdup_printf( "Attribute string with enum %d {%s} not handled", id, sp_attribute_name(id) );
510 TS_WARN( std::string((const char*)tmp) );
511 g_free( tmp );
512 found = true;
513 }
514 }
515 TS_ASSERT(!found);
517 for ( unsigned int index = 1; index < n_ids; index++ ) {
518 guchar const* name = sp_attribute_name(index);
519 unsigned int postLookup = sp_attribute_lookup( reinterpret_cast<gchar const*>(name) );
520 TSM_ASSERT_EQUALS( std::string("Enum round-trip through string {") + (char const*)name + "} failed.", index, postLookup );
521 }
523 }
524 };
526 #endif // SEEN_ATTRIBUTES_TEST_H
528 /*
529 Local Variables:
530 mode:c++
531 c-file-style:"stroustrup"
532 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
533 indent-tabs-mode:nil
534 fill-column:99
535 End:
536 */
537 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :