msi: Set all folders' source paths to the root directory if the source type is compre...
[wine] / dlls / msxml3 / tests / saxreader.c
1 /*
2  * XML test
3  *
4  * Copyright 2008 Piotr Caban
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #define COBJMACROS
22 #define CONST_VTABLE
23
24 #include <stdio.h>
25 #include "windows.h"
26 #include "ole2.h"
27 #include "msxml2.h"
28 #include "ocidl.h"
29
30 #include "wine/test.h"
31
32 typedef enum _CH {
33     CH_ENDTEST,
34     CH_PUTDOCUMENTLOCATOR,
35     CH_STARTDOCUMENT,
36     CH_ENDDOCUMENT,
37     CH_STARTPREFIXMAPPING,
38     CH_ENDPREFIXMAPPING,
39     CH_STARTELEMENT,
40     CH_ENDELEMENT,
41     CH_CHARACTERS,
42     CH_IGNORABLEWHITESPACE,
43     CH_PROCESSINGINSTRUCTION,
44     CH_SKIPPEDENTITY
45 } CH;
46
47 static const WCHAR szSimpleXML[] = {
48 '<','?','x','m','l',' ','v','e','r','s','i','o','n','=','\"','1','.','0','\"',' ','?','>','\n',
49 '<','B','a','n','k','A','c','c','o','u','n','t','>','\n',
50 ' ',' ',' ','<','N','u','m','b','e','r','>','1','2','3','4','<','/','N','u','m','b','e','r','>','\n',
51 ' ',' ',' ','<','N','a','m','e','>','C','a','p','t','a','i','n',' ','A','h','a','b','<','/','N','a','m','e','>','\n',
52 '<','/','B','a','n','k','A','c','c','o','u','n','t','>','\n','\0'
53 };
54
55 static CHAR szTestXML[] =
56 "<?xml version=\"1.0\" ?>\n"
57 "<BankAccount>\n"
58 "   <Number>1234</Number>\n"
59 "   <Name>Captain Ahab</Name>\n"
60 "</BankAccount>\n";
61
62 typedef struct _contenthandlercheck {
63     CH id;
64     int line;
65     int column;
66     const char *arg1;
67     const char *arg2;
68     const char *arg3;
69 } content_handler_test;
70
71 static content_handler_test contentHandlerTest1[] = {
72     { CH_PUTDOCUMENTLOCATOR, 0, 0 },
73     { CH_STARTDOCUMENT, 0, 0 },
74     { CH_STARTELEMENT, 2, 14, "", "BankAccount", "BankAccount" },
75     { CH_CHARACTERS, 2, 14, "\n   " },
76     { CH_STARTELEMENT, 3, 12, "", "Number", "Number" },
77     { CH_CHARACTERS, 3, 12, "1234" },
78     { CH_ENDELEMENT, 3, 18, "", "Number", "Number" },
79     { CH_CHARACTERS, 3, 25, "\n   " },
80     { CH_STARTELEMENT, 4, 10, "", "Name", "Name" },
81     { CH_CHARACTERS, 4, 10, "Captain Ahab" },
82     { CH_ENDELEMENT, 4, 24, "", "Name", "Name" },
83     { CH_CHARACTERS, 4, 29, "\n" },
84     { CH_ENDELEMENT, 5, 3, "", "BankAccount", "BankAccount" },
85     { CH_ENDDOCUMENT, 0, 0 },
86     { CH_ENDTEST }
87 };
88
89 static content_handler_test *expectCall;
90 static ISAXLocator *locator;
91
92 static const char *debugstr_wn(const WCHAR *szStr, int len)
93 {
94     static char buf[1024];
95     WideCharToMultiByte(CP_ACP, 0, szStr, len, buf, sizeof(buf), NULL, NULL);
96     return buf;
97 }
98
99 static void test_saxstr(unsigned line, const WCHAR *szStr, int nStr, const char *szTest)
100 {
101     WCHAR buf[1024];
102     int len;
103
104     if(!szTest) {
105         ok_(__FILE__,line) (szStr == NULL, "szStr != NULL\n");
106         ok_(__FILE__,line) (nStr == 0, "nStr = %d, expected 0\n", nStr);
107         return;
108     }
109
110     len = strlen(szTest);
111     ok_(__FILE__,line) (len == nStr, "nStr = %d, expected %d (%s)\n", nStr, len, szTest);
112     if(len != nStr)
113         return;
114
115     MultiByteToWideChar(CP_ACP, 0, szTest, -1, buf, sizeof(buf));
116     ok_(__FILE__,line) (!memcmp(szStr, buf, len*sizeof(WCHAR)), "unexpected szStr %s, expected %s\n",
117                         debugstr_wn(szStr, nStr), szTest);
118 }
119
120 static BOOL test_expect_call(CH id)
121 {
122     ok(expectCall->id == id, "unexpected call %d, expected %d\n", id, expectCall->id);
123     return expectCall->id == id;
124 }
125
126 static void test_locator(unsigned line, int loc_line, int loc_column)
127 {
128     int rcolumn, rline;
129     ISAXLocator_getLineNumber(locator, &rline);
130     ISAXLocator_getColumnNumber(locator, &rcolumn);
131
132     ok_(__FILE__,line) (rline == loc_line,
133             "unexpected line %d, expected %d\n", rline, loc_line);
134     ok_(__FILE__,line) (rcolumn == loc_column,
135             "unexpected column %d, expected %d\n", rcolumn, loc_column);
136 }
137
138 static HRESULT WINAPI contentHandler_QueryInterface(
139         ISAXContentHandler* iface,
140         REFIID riid,
141         void **ppvObject)
142 {
143     *ppvObject = NULL;
144
145     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ISAXContentHandler))
146     {
147         *ppvObject = iface;
148     }
149     else
150     {
151         return E_NOINTERFACE;
152     }
153
154     return S_OK;
155 }
156
157 static ULONG WINAPI contentHandler_AddRef(
158         ISAXContentHandler* iface)
159 {
160     return 2;
161 }
162
163 static ULONG WINAPI contentHandler_Release(
164         ISAXContentHandler* iface)
165 {
166     return 1;
167 }
168
169 static HRESULT WINAPI contentHandler_putDocumentLocator(
170         ISAXContentHandler* iface,
171         ISAXLocator *pLocator)
172 {
173     if(!test_expect_call(CH_PUTDOCUMENTLOCATOR))
174         return E_FAIL;
175
176     locator = pLocator;
177     test_locator(__LINE__, expectCall->line, expectCall->column);
178
179     expectCall++;
180     return S_OK;
181 }
182
183 static HRESULT WINAPI contentHandler_startDocument(
184         ISAXContentHandler* iface)
185 {
186     if(!test_expect_call(CH_STARTDOCUMENT))
187         return E_FAIL;
188
189     test_locator(__LINE__, expectCall->line, expectCall->column);
190
191     expectCall++;
192     return S_OK;
193 }
194
195 static HRESULT WINAPI contentHandler_endDocument(
196         ISAXContentHandler* iface)
197 {
198     if(!test_expect_call(CH_ENDDOCUMENT))
199         return E_FAIL;
200
201     test_locator(__LINE__, expectCall->line, expectCall->column);
202
203     expectCall++;
204     return S_OK;
205 }
206
207 static HRESULT WINAPI contentHandler_startPrefixMapping(
208         ISAXContentHandler* iface,
209         const WCHAR *pPrefix,
210         int nPrefix,
211         const WCHAR *pUri,
212         int nUri)
213 {
214     if(!test_expect_call(CH_ENDDOCUMENT))
215         return E_FAIL;
216
217     test_saxstr(__LINE__, pPrefix, nPrefix, expectCall->arg1);
218     test_saxstr(__LINE__, pUri, nUri, expectCall->arg2);
219     test_locator(__LINE__, expectCall->line, expectCall->column);
220
221     expectCall++;
222     return S_OK;
223 }
224
225 static HRESULT WINAPI contentHandler_endPrefixMapping(
226         ISAXContentHandler* iface,
227         const WCHAR *pPrefix,
228         int nPrefix)
229 {
230     if(!test_expect_call(CH_ENDPREFIXMAPPING))
231         return E_FAIL;
232
233     test_saxstr(__LINE__, pPrefix, nPrefix, expectCall->arg1);
234     test_locator(__LINE__, expectCall->line, expectCall->column);
235
236     expectCall++;
237     return S_OK;
238 }
239
240 static HRESULT WINAPI contentHandler_startElement(
241         ISAXContentHandler* iface,
242         const WCHAR *pNamespaceUri,
243         int nNamespaceUri,
244         const WCHAR *pLocalName,
245         int nLocalName,
246         const WCHAR *pQName,
247         int nQName,
248         ISAXAttributes *pAttr)
249 {
250     if(!test_expect_call(CH_STARTELEMENT))
251         return E_FAIL;
252
253     test_saxstr(__LINE__, pNamespaceUri, nNamespaceUri, expectCall->arg1);
254     test_saxstr(__LINE__, pLocalName, nLocalName, expectCall->arg2);
255     test_saxstr(__LINE__, pQName, nQName, expectCall->arg3);
256     test_locator(__LINE__, expectCall->line, expectCall->column);
257
258     expectCall++;
259     return S_OK;
260 }
261
262 static HRESULT WINAPI contentHandler_endElement(
263         ISAXContentHandler* iface,
264         const WCHAR *pNamespaceUri,
265         int nNamespaceUri,
266         const WCHAR *pLocalName,
267         int nLocalName,
268         const WCHAR *pQName,
269         int nQName)
270 {
271     if(!test_expect_call(CH_ENDELEMENT))
272         return E_FAIL;
273
274     test_saxstr(__LINE__, pNamespaceUri, nNamespaceUri, expectCall->arg1);
275     test_saxstr(__LINE__, pLocalName, nLocalName, expectCall->arg2);
276     test_saxstr(__LINE__, pQName, nQName, expectCall->arg3);
277     test_locator(__LINE__, expectCall->line, expectCall->column);
278
279     expectCall++;
280     return S_OK;
281 }
282
283 static HRESULT WINAPI contentHandler_characters(
284         ISAXContentHandler* iface,
285         const WCHAR *pChars,
286         int nChars)
287 {
288     if(!test_expect_call(CH_CHARACTERS))
289         return E_FAIL;
290
291     test_saxstr(__LINE__, pChars, nChars, expectCall->arg1);
292     test_locator(__LINE__, expectCall->line, expectCall->column);
293
294     expectCall++;
295     return S_OK;
296 }
297
298 static HRESULT WINAPI contentHandler_ignorableWhitespace(
299         ISAXContentHandler* iface,
300         const WCHAR *pChars,
301         int nChars)
302 {
303     if(!test_expect_call(CH_IGNORABLEWHITESPACE))
304         return E_FAIL;
305
306     test_saxstr(__LINE__, pChars, nChars, expectCall->arg1);
307     test_locator(__LINE__, expectCall->line, expectCall->column);
308
309     expectCall++;
310     return S_OK;
311 }
312
313 static HRESULT WINAPI contentHandler_processingInstruction(
314         ISAXContentHandler* iface,
315         const WCHAR *pTarget,
316         int nTarget,
317         const WCHAR *pData,
318         int nData)
319 {
320     if(!test_expect_call(CH_PROCESSINGINSTRUCTION))
321         return E_FAIL;
322
323     test_saxstr(__LINE__, pTarget, nTarget, expectCall->arg1);
324     test_saxstr(__LINE__, pData, nData, expectCall->arg2);
325     test_locator(__LINE__, expectCall->line, expectCall->column);
326
327     expectCall++;
328     return S_OK;
329 }
330
331 static HRESULT WINAPI contentHandler_skippedEntity(
332         ISAXContentHandler* iface,
333         const WCHAR *pName,
334         int nName)
335 {
336     if(!test_expect_call(CH_SKIPPEDENTITY))
337         return E_FAIL;
338
339     test_saxstr(__LINE__, pName, nName, expectCall->arg1);
340     test_locator(__LINE__, expectCall->line, expectCall->column);
341
342     expectCall++;
343     return S_OK;
344 }
345
346
347 static const ISAXContentHandlerVtbl contentHandlerVtbl =
348 {
349     contentHandler_QueryInterface,
350     contentHandler_AddRef,
351     contentHandler_Release,
352     contentHandler_putDocumentLocator,
353     contentHandler_startDocument,
354     contentHandler_endDocument,
355     contentHandler_startPrefixMapping,
356     contentHandler_endPrefixMapping,
357     contentHandler_startElement,
358     contentHandler_endElement,
359     contentHandler_characters,
360     contentHandler_ignorableWhitespace,
361     contentHandler_processingInstruction,
362     contentHandler_skippedEntity
363 };
364
365 static ISAXContentHandler contentHandler = { &contentHandlerVtbl };
366
367 static HRESULT WINAPI isaxerrorHandler_QueryInterface(
368         ISAXErrorHandler* iface,
369         REFIID riid,
370         void **ppvObject)
371 {
372     *ppvObject = NULL;
373
374     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ISAXErrorHandler))
375     {
376         *ppvObject = iface;
377     }
378     else
379     {
380         return E_NOINTERFACE;
381     }
382
383     return S_OK;
384 }
385
386 static ULONG WINAPI isaxerrorHandler_AddRef(
387         ISAXErrorHandler* iface)
388 {
389     return 2;
390 }
391
392 static ULONG WINAPI isaxerrorHandler_Release(
393         ISAXErrorHandler* iface)
394 {
395     return 1;
396 }
397
398 static HRESULT WINAPI isaxerrorHandler_error(
399         ISAXErrorHandler* iface,
400         ISAXLocator *pLocator,
401         const WCHAR *pErrorMessage,
402         HRESULT hrErrorCode)
403 {
404     return S_OK;
405 }
406
407 static HRESULT WINAPI isaxerrorHandler_fatalError(
408         ISAXErrorHandler* iface,
409         ISAXLocator *pLocator,
410         const WCHAR *pErrorMessage,
411         HRESULT hrErrorCode)
412 {
413     return S_OK;
414 }
415
416 static HRESULT WINAPI isaxerrorHanddler_ignorableWarning(
417         ISAXErrorHandler* iface,
418         ISAXLocator *pLocator,
419         const WCHAR *pErrorMessage,
420         HRESULT hrErrorCode)
421 {
422     return S_OK;
423 }
424
425 static const ISAXErrorHandlerVtbl errorHandlerVtbl =
426 {
427     isaxerrorHandler_QueryInterface,
428     isaxerrorHandler_AddRef,
429     isaxerrorHandler_Release,
430     isaxerrorHandler_error,
431     isaxerrorHandler_fatalError,
432     isaxerrorHanddler_ignorableWarning
433 };
434
435 static ISAXErrorHandler errorHandler = { &errorHandlerVtbl };
436
437 static void test_saxreader(void)
438 {
439     HRESULT hr;
440     ISAXXMLReader *reader = NULL;
441     VARIANT var;
442     ISAXContentHandler *lpContentHandler;
443     ISAXErrorHandler *lpErrorHandler;
444     SAFEARRAY *pSA;
445     SAFEARRAYBOUND SADim[1];
446     char *pSAData = NULL;
447
448     hr = CoCreateInstance(&CLSID_SAXXMLReader, NULL, CLSCTX_INPROC_SERVER,
449             &IID_ISAXXMLReader, (LPVOID*)&reader);
450
451     if(FAILED(hr))
452     {
453         skip("Failed to create SAXXMLReader instance\n");
454         return;
455     }
456
457     hr = ISAXXMLReader_getContentHandler(reader, NULL);
458     ok(hr == E_POINTER, "Expected E_POINTER, got %08x\n", hr);
459
460     hr = ISAXXMLReader_getErrorHandler(reader, NULL);
461     ok(hr == E_POINTER, "Expected E_POINTER, got %08x\n", hr);
462
463     hr = ISAXXMLReader_getContentHandler(reader, &lpContentHandler);
464     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
465     ok(lpContentHandler == NULL, "Expected %p, got %p\n", NULL, lpContentHandler);
466
467     hr = ISAXXMLReader_getErrorHandler(reader, &lpErrorHandler);
468     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
469     ok(lpErrorHandler == NULL, "Expected %p, got %p\n", NULL, lpErrorHandler);
470
471     hr = ISAXXMLReader_putContentHandler(reader, NULL);
472     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
473
474     hr = ISAXXMLReader_putContentHandler(reader, &contentHandler);
475     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
476
477     hr = ISAXXMLReader_putErrorHandler(reader, &errorHandler);
478     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
479
480     hr = ISAXXMLReader_getContentHandler(reader, &lpContentHandler);
481     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
482     ok(lpContentHandler == &contentHandler, "Expected %p, got %p\n", &contentHandler, lpContentHandler);
483
484     V_VT(&var) = VT_BSTR;
485     V_BSTR(&var) = SysAllocString(szSimpleXML);
486
487     expectCall = contentHandlerTest1;
488     hr = ISAXXMLReader_parse(reader, var);
489     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
490     test_expect_call(CH_ENDTEST);
491
492     SADim[0].lLbound= 0;
493     SADim[0].cElements= sizeof(szTestXML)-1;
494     pSA = SafeArrayCreate(VT_UI1, 1, SADim);
495     SafeArrayAccessData(pSA, (void**)&pSAData);
496     memcpy(pSAData, szTestXML, sizeof(szTestXML)-1);
497     SafeArrayUnaccessData(pSA);
498     V_VT(&var) = VT_ARRAY|VT_UI1;
499     V_ARRAY(&var) = pSA;
500
501     expectCall = contentHandlerTest1;
502     hr = ISAXXMLReader_parse(reader, var);
503     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
504     test_expect_call(CH_ENDTEST);
505
506     SafeArrayDestroy(pSA);
507
508     ISAXXMLReader_Release(reader);
509 }
510
511 START_TEST(saxreader)
512 {
513     HRESULT hr;
514
515     hr = CoInitialize(NULL);
516     ok(hr == S_OK, "failed to init com\n");
517
518     test_saxreader();
519
520     CoUninitialize();
521 }