Reactos
at master 490 lines 15 kB view raw
1/* 2 * Schema test 3 * 4 * Copyright 2007 Huw Davies 5 * Copyright 2010 Adam Martinson for CodeWeavers 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22#include <stdio.h> 23#include <assert.h> 24#define COBJMACROS 25 26#include "ole2.h" 27#include "msxml2.h" 28 29#include "wine/test.h" 30 31static const WCHAR xsd_schema1_uri[] = L"x-schema:test1.xsd"; 32static const WCHAR xsd_schema1_xml[] = 33L"<?xml version='1.0'?>" 34"<schema xmlns='http://www.w3.org/2001/XMLSchema'" 35" targetNamespace='x-schema:test1.xsd'>" 36" <element name='root'>" 37" <complexType>" 38" <sequence maxOccurs='unbounded'>" 39" <any/>" 40" </sequence>" 41" </complexType>" 42" </element>" 43"</schema>"; 44 45static const WCHAR xsd_schema2_uri[] = L"x-schema:test2.xsd"; 46static const WCHAR xsd_schema2_xml[] = 47L"<?xml version='1.0'?>" 48"<schema xmlns='http://www.w3.org/2001/XMLSchema'" 49" targetNamespace='x-schema:test2.xsd'>" 50" <element name='root'>" 51" <complexType>" 52" <sequence maxOccurs='unbounded'>" 53" <any/>" 54" </sequence>" 55" </complexType>" 56" </element>" 57"</schema>"; 58 59static const WCHAR xsd_schema3_uri[] = L"x-schema:test3.xsd"; 60static const WCHAR xsd_schema3_xml[] = 61L"<?xml version='1.0'?>" 62"<schema xmlns='http://www.w3.org/2001/XMLSchema'" 63" targetNamespace='x-schema:test3.xsd'>" 64" <element name='root'>" 65" <complexType>" 66" <sequence maxOccurs='unbounded'>" 67" <any/>" 68" </sequence>" 69" </complexType>" 70" </element>" 71"</schema>"; 72 73static const WCHAR xdr_schema1_uri[] = L"x-schema:test1.xdr"; 74static const WCHAR xdr_schema1_xml[] = 75L"<?xml version='1.0'?>" 76"<Schema xmlns='urn:schemas-microsoft-com:xml-data'" 77" xmlns:dt='urn:schemas-microsoft-com:datatypes'" 78" name='test1.xdr'>" 79" <ElementType name='x' dt:type='boolean'/>" 80" <ElementType name='y'>" 81" <datatype dt:type='int'/>" 82" </ElementType>" 83" <ElementType name='z'/>" 84" <ElementType name='root' content='eltOnly' model='open' order='seq'>" 85" <element type='x'/>" 86" <element type='y'/>" 87" <element type='z'/>" 88" </ElementType>" 89"</Schema>"; 90 91static const WCHAR xdr_schema2_uri[] = L"x-schema:test2.xdr"; 92static const WCHAR xdr_schema2_xml[] = 93L"<?xml version='1.0'?>" 94"<Schema xmlns='urn:schemas-microsoft-com:xml-data'" 95" xmlns:dt='urn:schemas-microsoft-com:datatypes'" 96" name='test2.xdr'>" 97" <ElementType name='x' dt:type='bin.base64'/>" 98" <ElementType name='y' dt:type='uuid'/>" 99" <ElementType name='z'/>" 100" <ElementType name='root' content='eltOnly' model='closed' order='one'>" 101" <element type='x'/>" 102" <element type='y'/>" 103" <element type='z'/>" 104" </ElementType>" 105"</Schema>"; 106 107static BSTR alloced_bstrs[256]; 108static int alloced_bstrs_count; 109 110static BSTR _bstr_(const WCHAR *str) 111{ 112 assert(alloced_bstrs_count < ARRAY_SIZE(alloced_bstrs)); 113 alloced_bstrs[alloced_bstrs_count] = SysAllocString(str); 114 return alloced_bstrs[alloced_bstrs_count++]; 115} 116 117static void free_bstrs(void) 118{ 119 int i; 120 for (i = 0; i < alloced_bstrs_count; i++) 121 SysFreeString(alloced_bstrs[i]); 122 alloced_bstrs_count = 0; 123} 124 125static VARIANT _variantdoc_(void* doc) 126{ 127 VARIANT v; 128 V_VT(&v) = VT_DISPATCH; 129 V_DISPATCH(&v) = (IDispatch*)doc; 130 return v; 131} 132 133static IXMLDOMDocument2 *create_document(void) 134{ 135 IXMLDOMDocument2 *obj = NULL; 136 HRESULT hr; 137 138 hr = CoCreateInstance(&CLSID_DOMDocument40, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void **)&obj); 139 ok(hr == S_OK, "Failed to create a document object, hr %#lx.\n", hr); 140 141 return obj; 142} 143 144static void *create_cache(REFIID riid) 145{ 146 void *obj = NULL; 147 HRESULT hr; 148 149 hr = CoCreateInstance(&CLSID_XMLSchemaCache40, NULL, CLSCTX_INPROC_SERVER, riid, &obj); 150 ok(hr == S_OK, "Failed to create a document object, hr %#lx.\n", hr); 151 152 return obj; 153} 154 155static HRESULT validate_regex_document(IXMLDOMDocument2 *doc, IXMLDOMDocument2 *schema, IXMLDOMSchemaCollection* cache, 156 const WCHAR *regex, const WCHAR *input) 157{ 158 static const WCHAR regex_doc[] = 159L"" 160"<?xml version='1.0'?>" 161"<root xmlns='urn:test'>%s</root>"; 162 163 static const WCHAR regex_schema[] = 164L"<?xml version='1.0'?>" 165"<schema xmlns='http://www.w3.org/2001/XMLSchema'" 166" targetNamespace='urn:test'>" 167" <element name='root'>" 168" <simpleType>" 169" <restriction base='string'>" 170" <pattern value='%s'/>" 171" </restriction>" 172" </simpleType>" 173" </element>" 174"</schema>"; 175 176 WCHAR buffer[1024]; 177 IXMLDOMParseError* err; 178 BSTR namespace, bstr; 179 VARIANT_BOOL b; 180 HRESULT hr; 181 VARIANT v; 182 183 VariantInit(&v); 184 185 swprintf(buffer, ARRAY_SIZE(buffer), regex_doc, input); 186 bstr = SysAllocString(buffer); 187 hr = IXMLDOMDocument2_loadXML(doc, bstr, &b); 188 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 189 ok(b == VARIANT_TRUE, "failed to load XML\n"); 190 SysFreeString(bstr); 191 192 swprintf(buffer, ARRAY_SIZE(buffer), regex_schema, regex); 193 bstr = SysAllocString(buffer); 194 hr = IXMLDOMDocument2_loadXML(schema, bstr, &b); 195 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 196 ok(b == VARIANT_TRUE, "failed to load XML\n"); 197 SysFreeString(bstr); 198 199 /* add the schema to the cache */ 200 V_VT(&v) = VT_DISPATCH; 201 V_DISPATCH(&v) = NULL; 202 hr = IXMLDOMDocument2_QueryInterface(schema, &IID_IDispatch, (void**)&V_DISPATCH(&v)); 203 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 204 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 205 namespace = SysAllocString(L"urn:test"); 206 hr = IXMLDOMSchemaCollection_add(cache, namespace, v); 207 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 208 SysFreeString(namespace); 209 VariantClear(&v); 210/* 211 if (FAILED(hr)) 212 return hr; 213*/ 214 /* associate the cache to the doc */ 215 V_VT(&v) = VT_DISPATCH; 216 V_DISPATCH(&v) = NULL; 217 hr = IXMLDOMSchemaCollection_QueryInterface(cache, &IID_IDispatch, (void**)&V_DISPATCH(&v)); 218 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 219 ok(V_DISPATCH(&v) != NULL, "failed to get IDispatch interface\n"); 220 hr = IXMLDOMDocument2_putref_schemas(doc, v); 221 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 222 VariantClear(&v); 223 224 /* validate the doc 225 * only declared elements in the declared order 226 * this is fine */ 227 err = NULL; 228 bstr = NULL; 229 hr = IXMLDOMDocument2_validate(doc, &err); 230 ok(err != NULL, "domdoc_validate() should always set err\n"); 231 if (IXMLDOMParseError_get_reason(err, &bstr) != S_FALSE) 232 trace("got error: %s\n", wine_dbgstr_w(bstr)); 233 SysFreeString(bstr); 234 IXMLDOMParseError_Release(err); 235 236 return hr; 237} 238 239static void test_regex(void) 240{ 241 static const struct regex_test 242 { 243 const WCHAR *regex; 244 const WCHAR *input; 245 } 246 tests[] = 247 { 248 { L"\\!", L"!" }, 249 { L"\\\"", L"\"" }, 250 { L"\\#", L"#" }, 251 { L"\\$", L"$" }, 252 { L"\\%", L"%" }, 253 { L"\\,", L"," }, 254 { L"\\/", L"/" }, 255 { L"\\:", L":" }, 256 { L"\\;", L";" }, 257 { L"\\=", L"=" }, 258 { L"\\>", L">" }, 259 { L"\\@", L"@" }, 260 { L"\\`", L"`" }, 261 { L"\\~", L"~" }, 262 { L"\\uCAFE", L"\xCAFE" }, 263 /* non-BMP character in surrogate pairs: */ 264 { L"\\uD83D\\uDE00", L"\xD83D\xDE00" }, 265 /* "x{,2}" is non-standard and only works on libxml2 <= v2.9.10 */ 266 { L"x{0,2}", L"x" } 267 }; 268 unsigned int i; 269 270 for (i = 0; i < ARRAY_SIZE(tests); ++i) 271 { 272 const struct regex_test *test = &tests[i]; 273 IXMLDOMDocument2 *doc, *schema; 274 IXMLDOMSchemaCollection *cache; 275 HRESULT hr; 276 277 winetest_push_context("Test %s", wine_dbgstr_w(test->regex)); 278 279 doc = create_document(); 280 schema = create_document(); 281 cache = create_cache(&IID_IXMLDOMSchemaCollection); 282 283 hr = validate_regex_document(doc, schema, cache, tests->regex, tests->input); 284 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 285 286 if (doc) 287 IXMLDOMDocument2_Release(doc); 288 if (schema) 289 IXMLDOMDocument2_Release(schema); 290 if (cache) 291 IXMLDOMSchemaCollection_Release(cache); 292 293 winetest_pop_context(); 294 } 295} 296 297static void test_get(void) 298{ 299 IXMLDOMSchemaCollection2 *cache; 300 IXMLDOMNode *node; 301 HRESULT hr; 302 303 cache = create_cache(&IID_IXMLDOMSchemaCollection2); 304 305 hr = IXMLDOMSchemaCollection2_get(cache, NULL, NULL); 306 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); 307 308 hr = IXMLDOMSchemaCollection2_get(cache, _bstr_(L"uri"), &node); 309 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 310 311 IXMLDOMSchemaCollection2_Release(cache); 312 free_bstrs(); 313} 314 315static void test_remove(void) 316{ 317 IXMLDOMSchemaCollection2 *cache; 318 IXMLDOMDocument2 *doc; 319 VARIANT_BOOL b; 320 HRESULT hr; 321 VARIANT v; 322 LONG len; 323 324 /* ::remove() works for version 4 */ 325 cache = create_cache(&IID_IXMLDOMSchemaCollection2); 326 327 doc = create_document(); 328 ok(doc != NULL, "got %p\n", doc); 329 330 hr = IXMLDOMDocument2_loadXML(doc, _bstr_(xsd_schema1_xml), &b); 331 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 332 333 V_VT(&v) = VT_DISPATCH; 334 V_DISPATCH(&v) = (IDispatch*)doc; 335 hr = IXMLDOMSchemaCollection2_add(cache, _bstr_(xsd_schema1_uri), v); 336 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 337 338 len = -1; 339 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 340 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 341 ok(len == 1, "Unexpected length %ld.\n", len); 342 343 hr = IXMLDOMSchemaCollection2_remove(cache, NULL); 344 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 345 346 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_(L"invaliduri")); 347 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 348 349 len = -1; 350 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 351 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 352 ok(len == 1, "Unexpected length %ld.\n", len); 353 354 hr = IXMLDOMSchemaCollection2_remove(cache, _bstr_(xsd_schema1_uri)); 355 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 356 357 len = -1; 358 hr = IXMLDOMSchemaCollection2_get_length(cache, &len); 359 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 360 ok(len == 0, "Unexpected length %ld.\n", len); 361 362 IXMLDOMDocument2_Release(doc); 363 IXMLDOMSchemaCollection2_Release(cache); 364 365 free_bstrs(); 366} 367 368static void test_validate_on_load(void) 369{ 370 IXMLDOMSchemaCollection2 *cache; 371 VARIANT_BOOL b; 372 HRESULT hr; 373 374 cache = create_cache(&IID_IXMLDOMSchemaCollection2); 375 376 hr = IXMLDOMSchemaCollection2_get_validateOnLoad(cache, NULL); 377 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); 378 379 b = VARIANT_FALSE; 380 hr = IXMLDOMSchemaCollection2_get_validateOnLoad(cache, &b); 381 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 382 ok(b == VARIANT_TRUE, "got %d\n", b); 383 384 IXMLDOMSchemaCollection2_Release(cache); 385} 386 387static void test_collection_content(void) 388{ 389 IXMLDOMDocument2 *schema1, *schema2, *schema3, *schema4, *schema5; 390 IXMLDOMSchemaCollection *cache; 391 BSTR content[5] = { 0 }; 392 VARIANT_BOOL b; 393 LONG length; 394 HRESULT hr; 395 BSTR bstr; 396 int i, j; 397 398 schema1 = create_document(); 399 schema2 = create_document(); 400 schema3 = create_document(); 401 schema4 = create_document(); 402 schema5 = create_document(); 403 cache = create_cache(&IID_IXMLDOMSchemaCollection); 404 405 hr = IXMLDOMDocument2_loadXML(schema1, _bstr_(xdr_schema1_xml), &b); 406 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 407 ok(b == VARIANT_TRUE, "failed to load XML\n"); 408 hr = IXMLDOMDocument2_loadXML(schema2, _bstr_(xdr_schema2_xml), &b); 409 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 410 ok(b == VARIANT_TRUE, "failed to load XML\n"); 411 hr = IXMLDOMDocument2_loadXML(schema3, _bstr_(xsd_schema1_xml), &b); 412 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 413 ok(b == VARIANT_TRUE, "failed to load XML\n"); 414 hr = IXMLDOMDocument2_loadXML(schema4, _bstr_(xsd_schema2_xml), &b); 415 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 416 ok(b == VARIANT_TRUE, "failed to load XML\n"); 417 hr = IXMLDOMDocument2_loadXML(schema5, _bstr_(xsd_schema3_xml), &b); 418 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 419 ok(b == VARIANT_TRUE, "failed to load XML\n"); 420 421 /* combining XDR and XSD schemas in the same cache is fine */ 422 hr = IXMLDOMSchemaCollection_add(cache, _bstr_(xdr_schema1_uri), _variantdoc_(schema1)); 423 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 424 hr = IXMLDOMSchemaCollection_add(cache, _bstr_(xdr_schema2_uri), _variantdoc_(schema2)); 425 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 426 hr = IXMLDOMSchemaCollection_add(cache, _bstr_(xsd_schema1_uri), _variantdoc_(schema3)); 427 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 428 hr = IXMLDOMSchemaCollection_add(cache, _bstr_(xsd_schema2_uri), _variantdoc_(schema4)); 429 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 430 hr = IXMLDOMSchemaCollection_add(cache, _bstr_(xsd_schema3_uri), _variantdoc_(schema5)); 431 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 432 433 length = -1; 434 hr = IXMLDOMSchemaCollection_get_length(cache, &length); 435 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 436 ok(length == 5, "Unexpected length %ld.\n", length); 437 438 for (i = 0; i < 5; ++i) 439 { 440 bstr = NULL; 441 hr = IXMLDOMSchemaCollection_get_namespaceURI(cache, i, &bstr); 442 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 443 ok(bstr != NULL && *bstr, "expected non-empty string\n"); 444 445 for (j = 0; j < i; ++j) 446 ok(wcscmp(content[j], bstr), "got duplicate entry\n"); 447 content[i] = bstr; 448 } 449 450 for (i = 0; i < 5; ++i) 451 { 452 SysFreeString(content[i]); 453 content[i] = NULL; 454 } 455 456 IXMLDOMDocument2_Release(schema1); 457 IXMLDOMDocument2_Release(schema2); 458 IXMLDOMDocument2_Release(schema3); 459 IXMLDOMDocument2_Release(schema4); 460 IXMLDOMDocument2_Release(schema5); 461 462 IXMLDOMSchemaCollection_Release(cache); 463 free_bstrs(); 464} 465 466START_TEST(schema) 467{ 468 IUnknown *obj; 469 HRESULT hr; 470 471 hr = CoInitialize(NULL); 472 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); 473 474 hr = CoCreateInstance(&CLSID_DOMDocument40, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument2, (void **)&obj); 475 if (FAILED(hr)) 476 { 477 win_skip("DOMDocument40 is not supported.\n"); 478 CoUninitialize(); 479 return; 480 } 481 IUnknown_Release(obj); 482 483 test_regex(); 484 test_get(); 485 test_remove(); 486 test_validate_on_load(); 487 test_collection_content(); 488 489 CoUninitialize(); 490}