xmllite/writer: Implement WriteCharEntity().
[wine.git] / dlls / xmllite / tests / writer.c
blob661b83799092a0a14af352d14adbf98ec79efc11
1 /*
2 * XMLLite IXmlWriter tests
4 * Copyright 2011 (C) Alistair Leslie-Hughes
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.
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.
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
20 #define COBJMACROS
22 #include <stdarg.h>
23 #include <stdio.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "ole2.h"
28 #include "xmllite.h"
29 #include "wine/test.h"
31 #include "initguid.h"
32 DEFINE_GUID(IID_IXmlWriterOutput, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
34 static void check_output(IStream *stream, const char *expected, BOOL todo, int line)
36 HGLOBAL hglobal;
37 int len = strlen(expected), size;
38 char *ptr;
39 HRESULT hr;
41 hr = GetHGlobalFromStream(stream, &hglobal);
42 ok_(__FILE__, line)(hr == S_OK, "got 0x%08x\n", hr);
44 size = GlobalSize(hglobal);
45 ptr = GlobalLock(hglobal);
46 todo_wine_if(todo)
48 if (size != len)
50 ok_(__FILE__, line)(0, "data size mismatch, expected %u, got %u\n", len, size);
51 ok_(__FILE__, line)(0, "got %s, expected %s\n", ptr, expected);
53 else
54 ok_(__FILE__, line)(!strncmp(ptr, expected, len), "got %s, expected %s\n", ptr, expected);
56 GlobalUnlock(hglobal);
58 #define CHECK_OUTPUT(stream, expected) check_output(stream, expected, FALSE, __LINE__)
59 #define CHECK_OUTPUT_TODO(stream, expected) check_output(stream, expected, TRUE, __LINE__)
61 /* used to test all Write* methods for consistent error state */
62 static void check_writer_state(IXmlWriter *writer, HRESULT exp_hr)
64 static const WCHAR aW[] = {'a',0};
65 HRESULT hr;
67 /* FIXME: add WriteAttributes */
69 hr = IXmlWriter_WriteAttributeString(writer, NULL, aW, NULL, aW);
70 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
72 hr = IXmlWriter_WriteCData(writer, aW);
73 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
75 hr = IXmlWriter_WriteCharEntity(writer, aW[0]);
76 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
78 hr = IXmlWriter_WriteChars(writer, aW, 1);
79 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
81 hr = IXmlWriter_WriteComment(writer, aW);
82 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
84 /* FIXME: add WriteDocType */
86 hr = IXmlWriter_WriteElementString(writer, NULL, aW, NULL, aW);
87 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
89 hr = IXmlWriter_WriteEndDocument(writer);
90 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
92 hr = IXmlWriter_WriteEndElement(writer);
93 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
95 hr = IXmlWriter_WriteEntityRef(writer, aW);
96 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
98 hr = IXmlWriter_WriteFullEndElement(writer);
99 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
101 hr = IXmlWriter_WriteName(writer, aW);
102 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
104 hr = IXmlWriter_WriteNmToken(writer, aW);
105 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
107 /* FIXME: add WriteNode */
108 /* FIXME: add WriteNodeShallow */
110 hr = IXmlWriter_WriteProcessingInstruction(writer, aW, aW);
111 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
113 hr = IXmlWriter_WriteQualifiedName(writer, aW, NULL);
114 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
116 hr = IXmlWriter_WriteRaw(writer, aW);
117 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
119 hr = IXmlWriter_WriteRawChars(writer, aW, 1);
120 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
122 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
123 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
125 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
126 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
128 hr = IXmlWriter_WriteString(writer, aW);
129 ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
131 /* FIXME: add WriteSurrogateCharEntity */
132 /* FIXME: add WriteWhitespace */
135 static IStream *writer_set_output(IXmlWriter *writer)
137 IStream *stream;
138 HRESULT hr;
140 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
141 ok(hr == S_OK, "got 0x%08x\n", hr);
143 hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
144 ok(hr == S_OK, "got 0x%08x\n", hr);
146 return stream;
149 static HRESULT WINAPI testoutput_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
151 if (IsEqualGUID(riid, &IID_IUnknown)) {
152 *obj = iface;
153 return S_OK;
155 else {
156 ok(0, "unknown riid=%s\n", wine_dbgstr_guid(riid));
157 return E_NOINTERFACE;
161 static ULONG WINAPI testoutput_AddRef(IUnknown *iface)
163 return 2;
166 static ULONG WINAPI testoutput_Release(IUnknown *iface)
168 return 1;
171 static const IUnknownVtbl testoutputvtbl = {
172 testoutput_QueryInterface,
173 testoutput_AddRef,
174 testoutput_Release
177 static IUnknown testoutput = { &testoutputvtbl };
179 static HRESULT WINAPI teststream_QueryInterface(ISequentialStream *iface, REFIID riid, void **obj)
181 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ISequentialStream))
183 *obj = iface;
184 return S_OK;
187 *obj = NULL;
188 return E_NOINTERFACE;
191 static ULONG WINAPI teststream_AddRef(ISequentialStream *iface)
193 return 2;
196 static ULONG WINAPI teststream_Release(ISequentialStream *iface)
198 return 1;
201 static HRESULT WINAPI teststream_Read(ISequentialStream *iface, void *pv, ULONG cb, ULONG *pread)
203 ok(0, "unexpected call\n");
204 return E_NOTIMPL;
207 static ULONG g_write_len;
208 static HRESULT WINAPI teststream_Write(ISequentialStream *iface, const void *pv, ULONG cb, ULONG *written)
210 g_write_len = cb;
211 *written = cb;
212 return S_OK;
215 static const ISequentialStreamVtbl teststreamvtbl =
217 teststream_QueryInterface,
218 teststream_AddRef,
219 teststream_Release,
220 teststream_Read,
221 teststream_Write
224 static ISequentialStream teststream = { &teststreamvtbl };
226 static void test_writer_create(void)
228 HRESULT hr;
229 IXmlWriter *writer;
230 LONG_PTR value;
232 /* crashes native */
233 if (0)
235 CreateXmlWriter(&IID_IXmlWriter, NULL, NULL);
236 CreateXmlWriter(NULL, (void**)&writer, NULL);
239 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
240 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
242 /* check default properties values */
243 value = 0;
244 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_ByteOrderMark, &value);
245 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
246 ok(value == TRUE, "got %ld\n", value);
248 value = TRUE;
249 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_Indent, &value);
250 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
251 ok(value == FALSE, "got %ld\n", value);
253 value = TRUE;
254 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, &value);
255 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
256 ok(value == FALSE, "got %ld\n", value);
258 value = XmlConformanceLevel_Auto;
259 hr = IXmlWriter_GetProperty(writer, XmlWriterProperty_ConformanceLevel, &value);
260 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
261 ok(value == XmlConformanceLevel_Document, "got %ld\n", value);
263 IXmlWriter_Release(writer);
266 static void test_writeroutput(void)
268 static const WCHAR utf16W[] = {'u','t','f','-','1','6',0};
269 IXmlWriterOutput *output;
270 IUnknown *unk;
271 HRESULT hr;
273 output = NULL;
274 hr = CreateXmlWriterOutputWithEncodingName(&testoutput, NULL, NULL, &output);
275 ok(hr == S_OK, "got %08x\n", hr);
276 IUnknown_Release(output);
278 hr = CreateXmlWriterOutputWithEncodingName(&testoutput, NULL, utf16W, &output);
279 ok(hr == S_OK, "got %08x\n", hr);
280 unk = NULL;
281 hr = IUnknown_QueryInterface(output, &IID_IXmlWriterOutput, (void**)&unk);
282 ok(hr == S_OK, "got %08x\n", hr);
283 ok(unk != NULL, "got %p\n", unk);
284 /* releasing 'unk' crashes on native */
285 IUnknown_Release(output);
287 output = NULL;
288 hr = CreateXmlWriterOutputWithEncodingCodePage(&testoutput, NULL, ~0u, &output);
289 ok(hr == S_OK, "got %08x\n", hr);
290 IUnknown_Release(output);
292 hr = CreateXmlWriterOutputWithEncodingCodePage(&testoutput, NULL, CP_UTF8, &output);
293 ok(hr == S_OK, "got %08x\n", hr);
294 unk = NULL;
295 hr = IUnknown_QueryInterface(output, &IID_IXmlWriterOutput, (void**)&unk);
296 ok(hr == S_OK, "got %08x\n", hr);
297 ok(unk != NULL, "got %p\n", unk);
298 /* releasing 'unk' crashes on native */
299 IUnknown_Release(output);
302 static void test_writestartdocument(void)
304 static const char fullprolog[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
305 static const char prologversion[] = "<?xml version=\"1.0\"?>";
306 static const WCHAR versionW[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
307 static const WCHAR xmlW[] = {'x','m','l',0};
308 IXmlWriter *writer;
309 IStream *stream;
310 HRESULT hr;
312 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
313 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
315 /* output not set */
316 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
317 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
319 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
320 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
322 hr = IXmlWriter_Flush(writer);
323 ok(hr == S_OK, "got 0x%08x\n", hr);
325 stream = writer_set_output(writer);
327 /* nothing written yet */
328 hr = IXmlWriter_Flush(writer);
329 ok(hr == S_OK, "got 0x%08x\n", hr);
331 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
332 ok(hr == S_OK, "got 0x%08x\n", hr);
334 hr = IXmlWriter_Flush(writer);
335 ok(hr == S_OK, "got 0x%08x\n", hr);
337 CHECK_OUTPUT(stream, fullprolog);
339 /* one more time */
340 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
341 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
342 IStream_Release(stream);
344 /* now add PI manually, and try to start a document */
345 stream = writer_set_output(writer);
347 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
348 ok(hr == S_OK, "got 0x%08x\n", hr);
350 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
351 ok(hr == S_OK, "got 0x%08x\n", hr);
353 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
354 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
356 /* another attempt to add 'xml' PI */
357 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
358 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
360 hr = IXmlWriter_Flush(writer);
361 ok(hr == S_OK, "got 0x%08x\n", hr);
363 CHECK_OUTPUT(stream, prologversion);
365 IStream_Release(stream);
366 IXmlWriter_Release(writer);
369 static void test_flush(void)
371 IXmlWriter *writer;
372 HRESULT hr;
374 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
375 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
377 hr = IXmlWriter_SetOutput(writer, (IUnknown*)&teststream);
378 ok(hr == S_OK, "got 0x%08x\n", hr);
380 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
381 ok(hr == S_OK, "got 0x%08x\n", hr);
383 g_write_len = 0;
384 hr = IXmlWriter_Flush(writer);
385 ok(hr == S_OK, "got 0x%08x\n", hr);
386 ok(g_write_len > 0, "got %d\n", g_write_len);
388 g_write_len = 1;
389 hr = IXmlWriter_Flush(writer);
390 ok(hr == S_OK, "got 0x%08x\n", hr);
391 ok(g_write_len == 0, "got %d\n", g_write_len);
393 /* Release() flushes too */
394 g_write_len = 1;
395 IXmlWriter_Release(writer);
396 ok(g_write_len == 0, "got %d\n", g_write_len);
399 static void test_omitxmldeclaration(void)
401 static const char prologversion[] = "<?xml version=\"1.0\"?>";
402 static const WCHAR versionW[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
403 static const WCHAR xmlW[] = {'x','m','l',0};
404 IXmlWriter *writer;
405 HGLOBAL hglobal;
406 IStream *stream;
407 HRESULT hr;
408 char *ptr;
410 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
411 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
413 stream = writer_set_output(writer);
415 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
416 ok(hr == S_OK, "got 0x%08x\n", hr);
418 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
419 ok(hr == S_OK, "got 0x%08x\n", hr);
421 hr = IXmlWriter_Flush(writer);
422 ok(hr == S_OK, "got 0x%08x\n", hr);
424 hr = GetHGlobalFromStream(stream, &hglobal);
425 ok(hr == S_OK, "got 0x%08x\n", hr);
427 ptr = GlobalLock(hglobal);
428 ok(!ptr, "got %p\n", ptr);
429 GlobalUnlock(hglobal);
431 /* one more time */
432 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
433 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
435 IStream_Release(stream);
437 /* now add PI manually, and try to start a document */
438 stream = writer_set_output(writer);
440 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
441 ok(hr == S_OK, "got 0x%08x\n", hr);
443 hr = IXmlWriter_Flush(writer);
444 ok(hr == S_OK, "got 0x%08x\n", hr);
446 CHECK_OUTPUT(stream, prologversion);
448 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
449 ok(hr == S_OK, "got 0x%08x\n", hr);
451 hr = IXmlWriter_Flush(writer);
452 ok(hr == S_OK, "got 0x%08x\n", hr);
454 CHECK_OUTPUT(stream, prologversion);
456 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
457 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
459 hr = IXmlWriter_Flush(writer);
460 ok(hr == S_OK, "got 0x%08x\n", hr);
462 CHECK_OUTPUT(stream, prologversion);
464 /* another attempt to add 'xml' PI */
465 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
466 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
468 hr = IXmlWriter_Flush(writer);
469 ok(hr == S_OK, "got 0x%08x\n", hr);
471 IStream_Release(stream);
472 IXmlWriter_Release(writer);
475 static void test_bom(void)
477 static const WCHAR versionW[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0};
478 static const WCHAR utf16W[] = {'u','t','f','-','1','6',0};
479 static const WCHAR xmlW[] = {'x','m','l',0};
480 static const WCHAR aW[] = {'a',0};
481 IXmlWriterOutput *output;
482 unsigned char *ptr;
483 IXmlWriter *writer;
484 IStream *stream;
485 HGLOBAL hglobal;
486 HRESULT hr;
488 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
489 ok(hr == S_OK, "got 0x%08x\n", hr);
491 hr = CreateXmlWriterOutputWithEncodingName((IUnknown*)stream, NULL, utf16W, &output);
492 ok(hr == S_OK, "got %08x\n", hr);
494 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
495 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
497 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
498 ok(hr == S_OK, "got 0x%08x\n", hr);
500 hr = IXmlWriter_SetOutput(writer, output);
501 ok(hr == S_OK, "got 0x%08x\n", hr);
503 /* BOM is on by default */
504 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
505 ok(hr == S_OK, "got 0x%08x\n", hr);
507 hr = IXmlWriter_Flush(writer);
508 ok(hr == S_OK, "got 0x%08x\n", hr);
510 hr = GetHGlobalFromStream(stream, &hglobal);
511 ok(hr == S_OK, "got 0x%08x\n", hr);
513 ptr = GlobalLock(hglobal);
514 ok(ptr[0] == 0xff && ptr[1] == 0xfe, "got %x,%x\n", ptr[0], ptr[1]);
515 GlobalUnlock(hglobal);
517 IStream_Release(stream);
518 IUnknown_Release(output);
520 /* start with PI */
521 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
522 ok(hr == S_OK, "got 0x%08x\n", hr);
524 hr = CreateXmlWriterOutputWithEncodingName((IUnknown*)stream, NULL, utf16W, &output);
525 ok(hr == S_OK, "got %08x\n", hr);
527 hr = IXmlWriter_SetOutput(writer, output);
528 ok(hr == S_OK, "got 0x%08x\n", hr);
530 hr = IXmlWriter_WriteProcessingInstruction(writer, xmlW, versionW);
531 ok(hr == S_OK, "got 0x%08x\n", hr);
533 hr = IXmlWriter_Flush(writer);
534 ok(hr == S_OK, "got 0x%08x\n", hr);
536 hr = GetHGlobalFromStream(stream, &hglobal);
537 ok(hr == S_OK, "got 0x%08x\n", hr);
539 ptr = GlobalLock(hglobal);
540 ok(ptr[0] == 0xff && ptr[1] == 0xfe, "got %x,%x\n", ptr[0], ptr[1]);
541 GlobalUnlock(hglobal);
543 IUnknown_Release(output);
544 IStream_Release(stream);
546 /* start with element */
547 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
548 ok(hr == S_OK, "got 0x%08x\n", hr);
550 hr = CreateXmlWriterOutputWithEncodingName((IUnknown*)stream, NULL, utf16W, &output);
551 ok(hr == S_OK, "got %08x\n", hr);
553 hr = IXmlWriter_SetOutput(writer, output);
554 ok(hr == S_OK, "got 0x%08x\n", hr);
556 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
557 ok(hr == S_OK, "got 0x%08x\n", hr);
559 hr = IXmlWriter_Flush(writer);
560 ok(hr == S_OK, "got 0x%08x\n", hr);
562 hr = GetHGlobalFromStream(stream, &hglobal);
563 ok(hr == S_OK, "got 0x%08x\n", hr);
565 ptr = GlobalLock(hglobal);
566 ok(ptr[0] == 0xff && ptr[1] == 0xfe, "got %x,%x\n", ptr[0], ptr[1]);
567 GlobalUnlock(hglobal);
569 IUnknown_Release(output);
570 IStream_Release(stream);
572 /* WriteElementString */
573 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
574 ok(hr == S_OK, "got 0x%08x\n", hr);
576 hr = CreateXmlWriterOutputWithEncodingName((IUnknown*)stream, NULL, utf16W, &output);
577 ok(hr == S_OK, "got %08x\n", hr);
579 hr = IXmlWriter_SetOutput(writer, output);
580 ok(hr == S_OK, "got 0x%08x\n", hr);
582 hr = IXmlWriter_WriteElementString(writer, NULL, aW, NULL, NULL);
583 ok(hr == S_OK, "got 0x%08x\n", hr);
585 hr = IXmlWriter_Flush(writer);
586 ok(hr == S_OK, "got 0x%08x\n", hr);
588 hr = GetHGlobalFromStream(stream, &hglobal);
589 ok(hr == S_OK, "got 0x%08x\n", hr);
591 ptr = GlobalLock(hglobal);
592 ok(ptr[0] == 0xff && ptr[1] == 0xfe, "got %x,%x\n", ptr[0], ptr[1]);
593 GlobalUnlock(hglobal);
595 IUnknown_Release(output);
596 IStream_Release(stream);
598 IXmlWriter_Release(writer);
601 static void test_writestartelement(void)
603 static const WCHAR valueW[] = {'v','a','l','u','e',0};
604 static const char *str = "<a><b>value</b>";
605 static const WCHAR aW[] = {'a',0};
606 static const WCHAR bW[] = {'b',0};
607 IXmlWriter *writer;
608 IStream *stream;
609 HRESULT hr;
611 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
612 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
614 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
615 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
617 stream = writer_set_output(writer);
619 hr = IXmlWriter_WriteStartElement(writer, aW, NULL, NULL);
620 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
622 hr = IXmlWriter_WriteStartElement(writer, NULL, NULL, NULL);
623 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
625 hr = IXmlWriter_WriteStartElement(writer, NULL, NULL, aW);
626 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
628 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
629 ok(hr == S_OK, "got 0x%08x\n", hr);
631 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
632 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
634 hr = IXmlWriter_Flush(writer);
635 ok(hr == S_OK, "got 0x%08x\n", hr);
637 CHECK_OUTPUT(stream, "<a");
639 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
640 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
642 hr = IXmlWriter_WriteStartElement(writer, NULL, NULL, NULL);
643 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
645 hr = IXmlWriter_WriteProcessingInstruction(writer, aW, aW);
646 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
648 IStream_Release(stream);
649 IXmlWriter_Release(writer);
651 /* WriteElementString */
652 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
653 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
655 hr = IXmlWriter_WriteElementString(writer, NULL, bW, NULL, valueW);
656 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
658 stream = writer_set_output(writer);
660 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
661 ok(hr == S_OK, "got 0x%08x\n", hr);
663 hr = IXmlWriter_WriteElementString(writer, NULL, bW, NULL, valueW);
664 ok(hr == S_OK, "got 0x%08x\n", hr);
666 hr = IXmlWriter_Flush(writer);
667 ok(hr == S_OK, "got 0x%08x\n", hr);
669 CHECK_OUTPUT(stream, str);
671 IStream_Release(stream);
672 IXmlWriter_Release(writer);
675 static void test_writeendelement(void)
677 static const WCHAR aW[] = {'a',0};
678 static const WCHAR bW[] = {'b',0};
679 IXmlWriter *writer;
680 IStream *stream;
681 HRESULT hr;
683 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
684 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
686 stream = writer_set_output(writer);
688 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
689 ok(hr == S_OK, "got 0x%08x\n", hr);
691 hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
692 ok(hr == S_OK, "got 0x%08x\n", hr);
694 hr = IXmlWriter_WriteEndElement(writer);
695 ok(hr == S_OK, "got 0x%08x\n", hr);
697 hr = IXmlWriter_WriteEndElement(writer);
698 ok(hr == S_OK, "got 0x%08x\n", hr);
700 hr = IXmlWriter_Flush(writer);
701 ok(hr == S_OK, "got 0x%08x\n", hr);
703 CHECK_OUTPUT(stream, "<a><b /></a>");
705 IXmlWriter_Release(writer);
706 IStream_Release(stream);
709 static void test_writeenddocument(void)
711 static const WCHAR aW[] = {'a',0};
712 static const WCHAR bW[] = {'b',0};
713 IXmlWriter *writer;
714 IStream *stream;
715 HGLOBAL hglobal;
716 HRESULT hr;
717 char *ptr;
719 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
720 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
722 hr = IXmlWriter_WriteEndDocument(writer);
723 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
725 stream = writer_set_output(writer);
727 /* WriteEndDocument resets it to initial state */
728 hr = IXmlWriter_WriteEndDocument(writer);
729 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
731 hr = IXmlWriter_WriteEndDocument(writer);
732 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
734 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
735 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
737 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
738 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
740 hr = IXmlWriter_SetOutput(writer, (IUnknown*)stream);
741 ok(hr == S_OK, "got 0x%08x\n", hr);
743 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
744 ok(hr == S_OK, "got 0x%08x\n", hr);
746 hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
747 ok(hr == S_OK, "got 0x%08x\n", hr);
749 hr = IXmlWriter_WriteEndDocument(writer);
750 ok(hr == S_OK, "got 0x%08x\n", hr);
752 hr = GetHGlobalFromStream(stream, &hglobal);
753 ok(hr == S_OK, "got 0x%08x\n", hr);
755 ptr = GlobalLock(hglobal);
756 ok(ptr == NULL, "got %p\n", ptr);
758 /* we still need to flush manually, WriteEndDocument doesn't do that */
759 hr = IXmlWriter_Flush(writer);
760 ok(hr == S_OK, "got 0x%08x\n", hr);
762 CHECK_OUTPUT(stream, "<a><b /></a>");
764 IXmlWriter_Release(writer);
765 IStream_Release(stream);
768 static void test_WriteComment(void)
770 static const WCHAR closeW[] = {'-','-','>',0};
771 static const WCHAR aW[] = {'a',0};
772 static const WCHAR bW[] = {'b',0};
773 IXmlWriter *writer;
774 IStream *stream;
775 HRESULT hr;
777 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
778 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
780 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
781 ok(hr == S_OK, "got 0x%08x\n", hr);
783 hr = IXmlWriter_WriteComment(writer, aW);
784 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
786 stream = writer_set_output(writer);
788 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
789 ok(hr == S_OK, "got 0x%08x\n", hr);
791 hr = IXmlWriter_WriteComment(writer, aW);
792 ok(hr == S_OK, "got 0x%08x\n", hr);
794 hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
795 ok(hr == S_OK, "got 0x%08x\n", hr);
797 hr = IXmlWriter_WriteComment(writer, aW);
798 ok(hr == S_OK, "got 0x%08x\n", hr);
800 hr = IXmlWriter_WriteComment(writer, NULL);
801 ok(hr == S_OK, "got 0x%08x\n", hr);
803 hr = IXmlWriter_WriteComment(writer, closeW);
804 ok(hr == S_OK, "got 0x%08x\n", hr);
806 hr = IXmlWriter_Flush(writer);
807 ok(hr == S_OK, "got 0x%08x\n", hr);
809 CHECK_OUTPUT(stream, "<!--a--><b><!--a--><!----><!--- ->-->");
811 IXmlWriter_Release(writer);
812 IStream_Release(stream);
815 static void test_WriteCData(void)
817 static const WCHAR closeW[] = {']',']','>',0};
818 static const WCHAR close2W[] = {'a',']',']','>','b',0};
819 static const WCHAR aW[] = {'a',0};
820 static const WCHAR bW[] = {'b',0};
821 IXmlWriter *writer;
822 IStream *stream;
823 HRESULT hr;
825 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
826 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
828 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
829 ok(hr == S_OK, "got 0x%08x\n", hr);
831 hr = IXmlWriter_WriteCData(writer, aW);
832 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
834 stream = writer_set_output(writer);
836 hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
837 ok(hr == S_OK, "got 0x%08x\n", hr);
839 hr = IXmlWriter_WriteCData(writer, aW);
840 ok(hr == S_OK, "got 0x%08x\n", hr);
842 hr = IXmlWriter_WriteCData(writer, NULL);
843 ok(hr == S_OK, "got 0x%08x\n", hr);
845 hr = IXmlWriter_WriteCData(writer, closeW);
846 ok(hr == S_OK, "got 0x%08x\n", hr);
848 hr = IXmlWriter_WriteCData(writer, close2W);
849 ok(hr == S_OK, "got 0x%08x\n", hr);
851 hr = IXmlWriter_Flush(writer);
852 ok(hr == S_OK, "got 0x%08x\n", hr);
854 CHECK_OUTPUT(stream,
855 "<b>"
856 "<![CDATA[a]]>"
857 "<![CDATA[]]>"
858 "<![CDATA[]]]]>"
859 "<![CDATA[>]]>"
860 "<![CDATA[a]]]]>"
861 "<![CDATA[>b]]>");
863 IXmlWriter_Release(writer);
864 IStream_Release(stream);
867 static void test_WriteRaw(void)
869 static const WCHAR rawW[] = {'a','<',':',0};
870 static const WCHAR aW[] = {'a',0};
871 IXmlWriter *writer;
872 IStream *stream;
873 HRESULT hr;
875 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
876 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
878 hr = IXmlWriter_WriteRaw(writer, NULL);
879 ok(hr == S_OK, "got 0x%08x\n", hr);
881 hr = IXmlWriter_WriteRaw(writer, rawW);
882 ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
884 stream = writer_set_output(writer);
886 hr = IXmlWriter_WriteRaw(writer, NULL);
887 ok(hr == S_OK, "got 0x%08x\n", hr);
889 hr = IXmlWriter_WriteRaw(writer, rawW);
890 ok(hr == S_OK, "got 0x%08x\n", hr);
892 hr = IXmlWriter_WriteRaw(writer, rawW);
893 ok(hr == S_OK, "got 0x%08x\n", hr);
895 hr = IXmlWriter_WriteComment(writer, rawW);
896 ok(hr == S_OK, "got 0x%08x\n", hr);
898 hr = IXmlWriter_WriteRaw(writer, rawW);
899 ok(hr == S_OK, "got 0x%08x\n", hr);
901 hr = IXmlWriter_WriteElementString(writer, NULL, aW, NULL, aW);
902 ok(hr == S_OK, "got 0x%08x\n", hr);
904 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes);
905 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
907 hr = IXmlWriter_WriteComment(writer, rawW);
908 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
910 hr = IXmlWriter_WriteEndDocument(writer);
911 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
913 hr = IXmlWriter_WriteRaw(writer, rawW);
914 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
916 hr = IXmlWriter_Flush(writer);
917 ok(hr == S_OK, "got 0x%08x\n", hr);
919 CHECK_OUTPUT(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>a<:a<:<!--a<:-->a<:<a>a</a>");
921 IXmlWriter_Release(writer);
922 IStream_Release(stream);
925 static void test_writer_state(void)
927 static const WCHAR aW[] = {'a',0};
928 IXmlWriter *writer;
929 IStream *stream;
930 HRESULT hr;
932 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
933 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
935 /* initial state */
936 check_writer_state(writer, E_UNEXPECTED);
938 /* set output and call 'wrong' method, WriteEndElement */
939 stream = writer_set_output(writer);
941 hr = IXmlWriter_WriteEndElement(writer);
942 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
944 check_writer_state(writer, WR_E_INVALIDACTION);
945 IStream_Release(stream);
947 /* WriteAttributeString */
948 stream = writer_set_output(writer);
950 hr = IXmlWriter_WriteAttributeString(writer, NULL, aW, NULL, aW);
951 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
953 check_writer_state(writer, WR_E_INVALIDACTION);
954 IStream_Release(stream);
956 /* WriteEndDocument */
957 stream = writer_set_output(writer);
959 hr = IXmlWriter_WriteEndDocument(writer);
960 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
962 check_writer_state(writer, WR_E_INVALIDACTION);
963 IStream_Release(stream);
965 /* WriteFullEndElement */
966 stream = writer_set_output(writer);
968 hr = IXmlWriter_WriteFullEndElement(writer);
969 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
971 check_writer_state(writer, WR_E_INVALIDACTION);
972 IStream_Release(stream);
974 /* WriteCData */
975 stream = writer_set_output(writer);
977 hr = IXmlWriter_WriteCData(writer, aW);
978 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
980 check_writer_state(writer, WR_E_INVALIDACTION);
981 IStream_Release(stream);
983 /* WriteName */
984 stream = writer_set_output(writer);
986 hr = IXmlWriter_WriteName(writer, aW);
987 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
989 check_writer_state(writer, WR_E_INVALIDACTION);
990 IStream_Release(stream);
992 /* WriteNmToken */
993 stream = writer_set_output(writer);
995 hr = IXmlWriter_WriteNmToken(writer, aW);
996 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
998 check_writer_state(writer, WR_E_INVALIDACTION);
999 IStream_Release(stream);
1001 /* WriteString */
1002 stream = writer_set_output(writer);
1004 hr = IXmlWriter_WriteString(writer, aW);
1005 ok(hr == WR_E_INVALIDACTION, "got 0x%08x\n", hr);
1007 check_writer_state(writer, WR_E_INVALIDACTION);
1008 IStream_Release(stream);
1010 IXmlWriter_Release(writer);
1013 static void test_indentation(void)
1015 static const WCHAR commentW[] = {'c','o','m','m','e','n','t',0};
1016 static const WCHAR aW[] = {'a',0};
1017 static const WCHAR bW[] = {'b',0};
1018 IXmlWriter *writer;
1019 IStream *stream;
1020 HRESULT hr;
1022 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1023 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1025 stream = writer_set_output(writer);
1027 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
1028 ok(hr == S_OK, "got 0x%08x\n", hr);
1030 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_Indent, TRUE);
1031 ok(hr == S_OK, "got 0x%08x\n", hr);
1033 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1034 ok(hr == S_OK, "got 0x%08x\n", hr);
1036 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1037 ok(hr == S_OK, "got 0x%08x\n", hr);
1039 hr = IXmlWriter_WriteComment(writer, commentW);
1040 ok(hr == S_OK, "got 0x%08x\n", hr);
1042 hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL);
1043 ok(hr == S_OK, "got 0x%08x\n", hr);
1045 hr = IXmlWriter_WriteEndDocument(writer);
1046 ok(hr == S_OK, "got 0x%08x\n", hr);
1048 hr = IXmlWriter_Flush(writer);
1049 ok(hr == S_OK, "got 0x%08x\n", hr);
1051 CHECK_OUTPUT(stream,
1052 "<a>\r\n"
1053 " <!--comment-->\r\n"
1054 " <b />\r\n"
1055 "</a>");
1057 IXmlWriter_Release(writer);
1058 IStream_Release(stream);
1061 static void test_WriteAttributeString(void)
1063 static const WCHAR prefixW[] = {'p','r','e','f','i','x',0};
1064 static const WCHAR localW[] = {'l','o','c','a','l',0};
1065 static const WCHAR uriW[] = {'u','r','i',0};
1066 static const WCHAR uri2W[] = {'u','r','i','2',0};
1067 static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
1068 static const WCHAR aW[] = {'a',0};
1069 static const WCHAR bW[] = {'b',0};
1070 IXmlWriter *writer;
1071 IStream *stream;
1072 HRESULT hr;
1074 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1075 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1077 stream = writer_set_output(writer);
1079 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
1080 ok(hr == S_OK, "got 0x%08x\n", hr);
1082 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1083 ok(hr == S_OK, "got 0x%08x\n", hr);
1085 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1086 ok(hr == S_OK, "got 0x%08x\n", hr);
1088 hr = IXmlWriter_WriteAttributeString(writer, NULL, aW, NULL, bW);
1089 ok(hr == S_OK, "got 0x%08x\n", hr);
1091 hr = IXmlWriter_WriteEndDocument(writer);
1092 ok(hr == S_OK, "got 0x%08x\n", hr);
1094 hr = IXmlWriter_Flush(writer);
1095 ok(hr == S_OK, "got 0x%08x\n", hr);
1097 CHECK_OUTPUT(stream,
1098 "<a a=\"b\" />");
1099 IStream_Release(stream);
1101 /* with namespaces */
1102 stream = writer_set_output(writer);
1104 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1105 ok(hr == S_OK, "got 0x%08x\n", hr);
1107 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1108 ok(hr == S_OK, "got 0x%08x\n", hr);
1110 hr = IXmlWriter_WriteAttributeString(writer, aW, NULL, NULL, bW);
1111 todo_wine
1112 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1114 hr = IXmlWriter_WriteAttributeString(writer, prefixW, localW, uriW, bW);
1115 todo_wine
1116 ok(hr == S_OK, "got 0x%08x\n", hr);
1118 hr = IXmlWriter_WriteAttributeString(writer, NULL, aW, NULL, bW);
1119 ok(hr == S_OK, "got 0x%08x\n", hr);
1121 hr = IXmlWriter_WriteAttributeString(writer, NULL, xmlnsW, uri2W, NULL);
1122 todo_wine
1123 ok(hr == WR_E_XMLNSPREFIXDECLARATION, "got 0x%08x\n", hr);
1125 hr = IXmlWriter_WriteAttributeString(writer, NULL, xmlnsW, NULL, uri2W);
1126 todo_wine
1127 ok(hr == WR_E_NSPREFIXDECLARED, "got 0x%08x\n", hr);
1129 hr = IXmlWriter_WriteAttributeString(writer, prefixW, localW, NULL, bW);
1130 todo_wine
1131 ok(hr == WR_E_DUPLICATEATTRIBUTE, "got 0x%08x\n", hr);
1133 hr = IXmlWriter_WriteEndDocument(writer);
1134 ok(hr == S_OK, "got 0x%08x\n", hr);
1136 hr = IXmlWriter_Flush(writer);
1137 ok(hr == S_OK, "got 0x%08x\n", hr);
1139 CHECK_OUTPUT_TODO(stream,
1140 "<a prefix:local=\"b\" a=\"b\" xmlns:prefix=\"uri\" />");
1142 IXmlWriter_Release(writer);
1143 IStream_Release(stream);
1146 static void test_WriteFullEndElement(void)
1148 static const WCHAR aW[] = {'a',0};
1149 IXmlWriter *writer;
1150 IStream *stream;
1151 HRESULT hr;
1153 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1154 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1156 /* standalone element */
1157 stream = writer_set_output(writer);
1159 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
1160 ok(hr == S_OK, "got 0x%08x\n", hr);
1162 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_Indent, TRUE);
1163 ok(hr == S_OK, "got 0x%08x\n", hr);
1165 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1166 ok(hr == S_OK, "got 0x%08x\n", hr);
1168 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1169 ok(hr == S_OK, "got 0x%08x\n", hr);
1171 hr = IXmlWriter_WriteFullEndElement(writer);
1172 ok(hr == S_OK, "got 0x%08x\n", hr);
1174 hr = IXmlWriter_WriteEndDocument(writer);
1175 ok(hr == S_OK, "got 0x%08x\n", hr);
1177 hr = IXmlWriter_Flush(writer);
1178 ok(hr == S_OK, "got 0x%08x\n", hr);
1180 CHECK_OUTPUT(stream,
1181 "<a></a>");
1182 IStream_Release(stream);
1184 /* nested elements */
1185 stream = writer_set_output(writer);
1187 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
1188 ok(hr == S_OK, "got 0x%08x\n", hr);
1190 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_Indent, TRUE);
1191 ok(hr == S_OK, "got 0x%08x\n", hr);
1193 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1194 ok(hr == S_OK, "got 0x%08x\n", hr);
1196 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1197 ok(hr == S_OK, "got 0x%08x\n", hr);
1199 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1200 ok(hr == S_OK, "got 0x%08x\n", hr);
1202 hr = IXmlWriter_WriteFullEndElement(writer);
1203 ok(hr == S_OK, "got 0x%08x\n", hr);
1205 hr = IXmlWriter_WriteEndDocument(writer);
1206 ok(hr == S_OK, "got 0x%08x\n", hr);
1208 hr = IXmlWriter_Flush(writer);
1209 ok(hr == S_OK, "got 0x%08x\n", hr);
1211 CHECK_OUTPUT(stream,
1212 "<a>\r\n"
1213 " <a></a>\r\n"
1214 "</a>");
1216 IXmlWriter_Release(writer);
1217 IStream_Release(stream);
1220 static void test_WriteCharEntity(void)
1222 static const WCHAR aW[] = {'a',0};
1223 IXmlWriter *writer;
1224 IStream *stream;
1225 HRESULT hr;
1227 hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL);
1228 ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
1230 /* without indentation */
1231 stream = writer_set_output(writer);
1233 hr = IXmlWriter_SetProperty(writer, XmlWriterProperty_OmitXmlDeclaration, TRUE);
1234 ok(hr == S_OK, "got 0x%08x\n", hr);
1236 hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit);
1237 ok(hr == S_OK, "got 0x%08x\n", hr);
1239 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1240 ok(hr == S_OK, "got 0x%08x\n", hr);
1242 hr = IXmlWriter_WriteCharEntity(writer, 0x100);
1243 ok(hr == S_OK, "got 0x%08x\n", hr);
1245 hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL);
1246 ok(hr == S_OK, "got 0x%08x\n", hr);
1248 hr = IXmlWriter_WriteEndDocument(writer);
1249 ok(hr == S_OK, "got 0x%08x\n", hr);
1251 hr = IXmlWriter_Flush(writer);
1252 ok(hr == S_OK, "got 0x%08x\n", hr);
1254 CHECK_OUTPUT(stream,
1255 "<a>&#x100;<a /></a>");
1257 IXmlWriter_Release(writer);
1258 IStream_Release(stream);
1261 START_TEST(writer)
1263 test_writer_create();
1264 test_writer_state();
1265 test_writeroutput();
1266 test_writestartdocument();
1267 test_writestartelement();
1268 test_writeendelement();
1269 test_flush();
1270 test_omitxmldeclaration();
1271 test_bom();
1272 test_writeenddocument();
1273 test_WriteComment();
1274 test_WriteCData();
1275 test_WriteRaw();
1276 test_indentation();
1277 test_WriteAttributeString();
1278 test_WriteFullEndElement();
1279 test_WriteCharEntity();