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
30 #include "wine/test.h"
33 DEFINE_GUID(IID_IXmlWriterOutput
, 0xc1131708, 0x0f59, 0x477f, 0x93, 0x59, 0x7d, 0x33, 0x24, 0x51, 0xbc, 0x1a);
35 static IStream
*create_stream_on_data(const void *data
, unsigned int size
)
37 IStream
*stream
= NULL
;
42 hglobal
= GlobalAlloc(GHND
, size
);
43 ptr
= GlobalLock(hglobal
);
45 memcpy(ptr
, data
, size
);
47 hr
= CreateStreamOnHGlobal(hglobal
, TRUE
, &stream
);
48 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
49 ok(stream
!= NULL
, "Expected non-NULL stream\n");
51 GlobalUnlock(hglobal
);
56 #define reader_set_input(a, b) _reader_set_input(__LINE__, a, b)
57 static void _reader_set_input(unsigned line
, IXmlReader
*reader
, const char *xml
)
62 stream
= create_stream_on_data(xml
, strlen(xml
));
64 hr
= IXmlReader_SetInput(reader
, (IUnknown
*)stream
);
65 ok_(__FILE__
,line
)(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
67 IStream_Release(stream
);
70 #define EXPECT_REF(obj, ref) _expect_ref((IUnknown *)obj, ref, __LINE__)
71 static void _expect_ref(IUnknown
*obj
, ULONG ref
, int line
)
75 refcount
= IUnknown_Release(obj
);
76 ok_(__FILE__
, line
)(refcount
== ref
, "expected refcount %lu, got %lu.\n", ref
, refcount
);
79 static void check_output_raw(IStream
*stream
, const void *expected
, SIZE_T size
, int line
)
86 hr
= GetHGlobalFromStream(stream
, &hglobal
);
87 ok_(__FILE__
, line
)(hr
== S_OK
, "Failed to get the stream handle, hr %#lx.\n", hr
);
89 content_size
= GlobalSize(hglobal
);
90 ok_(__FILE__
, line
)(size
== content_size
, "Unexpected test output size %Id.\n", content_size
);
91 ptr
= GlobalLock(hglobal
);
92 if (size
<= content_size
)
93 ok_(__FILE__
, line
)(!memcmp(expected
, ptr
, size
), "Unexpected output content.\n");
94 if (size
!= content_size
&& *ptr
== 0xfeff)
95 ok_(__FILE__
, line
)(0, "Content: %s.\n", wine_dbgstr_wn(ptr
, content_size
/ sizeof(WCHAR
)));
97 GlobalUnlock(hglobal
);
100 static void check_output(IStream
*stream
, const char *expected
, BOOL todo
, int line
)
102 int len
= strlen(expected
), size
;
107 hr
= GetHGlobalFromStream(stream
, &hglobal
);
108 ok_(__FILE__
, line
)(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
110 size
= GlobalSize(hglobal
);
111 ptr
= GlobalLock(hglobal
);
116 ok_(__FILE__
, line
)(0, "data size mismatch, expected %u, got %u\n", len
, size
);
117 ok_(__FILE__
, line
)(0, "got |%s|, expected |%s|\n", ptr
, expected
);
120 ok_(__FILE__
, line
)(!strncmp(ptr
, expected
, len
), "got |%s|, expected |%s|\n", ptr
, expected
);
122 GlobalUnlock(hglobal
);
124 #define CHECK_OUTPUT(stream, expected) check_output(stream, expected, FALSE, __LINE__)
125 #define CHECK_OUTPUT_TODO(stream, expected) check_output(stream, expected, TRUE, __LINE__)
126 #define CHECK_OUTPUT_RAW(stream, expected, size) check_output_raw(stream, expected, size, __LINE__)
128 static void writer_set_property(IXmlWriter
*writer
, XmlWriterProperty property
)
132 hr
= IXmlWriter_SetProperty(writer
, property
, TRUE
);
133 ok(hr
== S_OK
, "Failed to set writer property, hr %#lx.\n", hr
);
136 /* used to test all Write* methods for consistent error state */
137 static void check_writer_state(IXmlWriter
*writer
, HRESULT exp_hr
)
141 /* FIXME: add WriteAttributes */
143 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"a", NULL
, L
"a");
144 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
146 hr
= IXmlWriter_WriteCData(writer
, L
"a");
147 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
149 hr
= IXmlWriter_WriteCharEntity(writer
, 'a');
150 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
152 hr
= IXmlWriter_WriteChars(writer
, L
"a", 1);
153 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
155 hr
= IXmlWriter_WriteComment(writer
, L
"a");
156 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
158 hr
= IXmlWriter_WriteDocType(writer
, L
"a", NULL
, NULL
, NULL
);
159 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
161 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"a", NULL
, L
"a");
162 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
164 hr
= IXmlWriter_WriteEndDocument(writer
);
165 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
167 hr
= IXmlWriter_WriteEndElement(writer
);
168 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
170 hr
= IXmlWriter_WriteEntityRef(writer
, L
"a");
171 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
173 hr
= IXmlWriter_WriteFullEndElement(writer
);
174 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
176 hr
= IXmlWriter_WriteName(writer
, L
"a");
177 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
179 hr
= IXmlWriter_WriteNmToken(writer
, L
"a");
180 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
182 /* FIXME: add WriteNode */
183 /* FIXME: add WriteNodeShallow */
185 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"a", L
"a");
186 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
188 hr
= IXmlWriter_WriteQualifiedName(writer
, L
"a", NULL
);
189 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
191 hr
= IXmlWriter_WriteRaw(writer
, L
"a");
192 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
194 hr
= IXmlWriter_WriteRawChars(writer
, L
"a", 1);
195 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
197 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
198 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
200 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
201 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
203 hr
= IXmlWriter_WriteString(writer
, L
"a");
204 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
206 /* FIXME: add WriteSurrogateCharEntity */
208 hr
= IXmlWriter_WriteWhitespace(writer
, L
" ");
209 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
212 static IStream
*writer_set_output(IXmlWriter
*writer
)
217 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
218 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
220 hr
= IXmlWriter_SetOutput(writer
, (IUnknown
*)stream
);
221 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
226 static HRESULT WINAPI
testoutput_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
228 if (IsEqualGUID(riid
, &IID_IUnknown
)) {
233 ok(0, "unknown riid=%s\n", wine_dbgstr_guid(riid
));
234 return E_NOINTERFACE
;
238 static ULONG WINAPI
testoutput_AddRef(IUnknown
*iface
)
243 static ULONG WINAPI
testoutput_Release(IUnknown
*iface
)
248 static const IUnknownVtbl testoutputvtbl
= {
249 testoutput_QueryInterface
,
254 static IUnknown testoutput
= { &testoutputvtbl
};
256 static HRESULT WINAPI
teststream_QueryInterface(ISequentialStream
*iface
, REFIID riid
, void **obj
)
258 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_ISequentialStream
))
265 return E_NOINTERFACE
;
268 static ULONG WINAPI
teststream_AddRef(ISequentialStream
*iface
)
273 static ULONG WINAPI
teststream_Release(ISequentialStream
*iface
)
278 static HRESULT WINAPI
teststream_Read(ISequentialStream
*iface
, void *pv
, ULONG cb
, ULONG
*pread
)
280 ok(0, "unexpected call\n");
284 static ULONG g_write_len
;
285 static HRESULT WINAPI
teststream_Write(ISequentialStream
*iface
, const void *pv
, ULONG cb
, ULONG
*written
)
292 static const ISequentialStreamVtbl teststreamvtbl
=
294 teststream_QueryInterface
,
301 static ISequentialStream teststream
= { &teststreamvtbl
};
303 static void test_writer_create(void)
313 CreateXmlWriter(&IID_IXmlWriter
, NULL
, NULL
);
314 CreateXmlWriter(NULL
, (void**)&writer
, NULL
);
317 hr
= CreateXmlWriter(&IID_IStream
, (void **)&unk
, NULL
);
318 ok(hr
== E_NOINTERFACE
, "Unexpected hr %#lx.\n", hr
);
320 hr
= CreateXmlWriter(&IID_IUnknown
, (void **)&unk
, NULL
);
321 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
322 hr
= IUnknown_QueryInterface(unk
, &IID_IXmlWriter
, (void **)&writer
);
323 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
324 ok(unk
== (IUnknown
*)writer
, "unexpected interface pointer\n");
325 IUnknown_Release(unk
);
326 IXmlWriter_Release(writer
);
328 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
329 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
331 /* check default properties values */
333 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_ByteOrderMark
, &value
);
334 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
335 ok(value
== TRUE
, "got %Id.\n", value
);
338 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_Indent
, &value
);
339 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
340 ok(value
== FALSE
, "got %Id.\n", value
);
343 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_OmitXmlDeclaration
, &value
);
344 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
345 ok(value
== FALSE
, "got %Id.\n", value
);
347 value
= XmlConformanceLevel_Auto
;
348 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_ConformanceLevel
, &value
);
349 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
350 ok(value
== XmlConformanceLevel_Document
, "got %Id.\n", value
);
352 IXmlWriter_Release(writer
);
355 static void test_invalid_output_encoding(IXmlWriter
*writer
, IUnknown
*output
)
359 hr
= IXmlWriter_SetOutput(writer
, output
);
360 ok(hr
== S_OK
, "Failed to set output, hr %#lx.\n", hr
);
362 /* TODO: WriteAttributes */
364 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"a", NULL
, L
"a");
365 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
367 hr
= IXmlWriter_WriteCData(writer
, L
"a");
368 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
370 hr
= IXmlWriter_WriteCharEntity(writer
, 0x100);
371 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
373 hr
= IXmlWriter_WriteChars(writer
, L
"a", 1);
374 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
376 hr
= IXmlWriter_WriteComment(writer
, L
"a");
377 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
379 hr
= IXmlWriter_WriteDocType(writer
, L
"a", NULL
, NULL
, NULL
);
380 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
382 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"a", NULL
, NULL
);
383 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
385 hr
= IXmlWriter_WriteEndDocument(writer
);
386 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
388 hr
= IXmlWriter_WriteEndElement(writer
);
389 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
391 hr
= IXmlWriter_WriteEntityRef(writer
, L
"a");
392 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
394 hr
= IXmlWriter_WriteFullEndElement(writer
);
395 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
397 hr
= IXmlWriter_WriteName(writer
, L
"a");
398 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
400 hr
= IXmlWriter_WriteNmToken(writer
, L
"a");
401 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
403 /* TODO: WriteNode */
404 /* TODO: WriteNodeShallow */
406 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"a", L
"a");
407 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
409 hr
= IXmlWriter_WriteQualifiedName(writer
, L
"a", NULL
);
410 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
412 hr
= IXmlWriter_WriteRaw(writer
, L
"a");
413 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
415 hr
= IXmlWriter_WriteRawChars(writer
, L
"a", 1);
416 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
418 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
419 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
421 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
422 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
424 hr
= IXmlWriter_WriteString(writer
, L
"a");
425 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
427 /* TODO: WriteSurrogateCharEntity */
429 hr
= IXmlWriter_WriteWhitespace(writer
, L
" ");
430 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
432 hr
= IXmlWriter_Flush(writer
);
433 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
436 static void test_writeroutput(void)
438 static const WCHAR utf16_outputW
[] = {0xfeff,'<','a'};
439 IXmlWriterOutput
*output
;
446 hr
= CreateXmlWriterOutputWithEncodingName(&testoutput
, NULL
, NULL
, &output
);
447 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
448 EXPECT_REF(output
, 1);
449 IUnknown_Release(output
);
451 hr
= CreateXmlWriterOutputWithEncodingName(&testoutput
, NULL
, L
"utf-16", &output
);
452 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
454 hr
= IUnknown_QueryInterface(output
, &IID_IXmlWriterOutput
, (void**)&unk
);
455 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
457 ok(unk
!= NULL
&& unk
!= output
, "got %p, output %p\n", unk
, output
);
458 EXPECT_REF(output
, 2);
459 /* releasing 'unk' crashes on native */
460 IUnknown_Release(output
);
461 EXPECT_REF(output
, 1);
462 IUnknown_Release(output
);
465 hr
= CreateXmlWriterOutputWithEncodingCodePage(&testoutput
, NULL
, ~0u, &output
);
466 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
467 IUnknown_Release(output
);
469 hr
= CreateXmlWriterOutputWithEncodingCodePage(&testoutput
, NULL
, CP_UTF8
, &output
);
470 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
472 hr
= IUnknown_QueryInterface(output
, &IID_IXmlWriterOutput
, (void**)&unk
);
473 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
474 ok(unk
!= NULL
, "got %p\n", unk
);
475 /* releasing 'unk' crashes on native */
476 IUnknown_Release(output
);
477 IUnknown_Release(output
);
479 /* create with us-ascii */
481 hr
= CreateXmlWriterOutputWithEncodingName(&testoutput
, NULL
, L
"us-ascii", &output
);
482 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
483 IUnknown_Release(output
);
485 /* Output with codepage 1200. */
486 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
487 ok(hr
== S_OK
, "Failed to create writer, hr %#lx.\n", hr
);
489 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
490 ok(hr
== S_OK
, "Failed to create stream, hr %#lx.\n", hr
);
492 hr
= CreateXmlWriterOutputWithEncodingCodePage((IUnknown
*)stream
, NULL
, 1200, &output
);
493 ok(hr
== S_OK
, "Failed to create writer output, hr %#lx.\n", hr
);
495 hr
= IXmlWriter_SetOutput(writer
, output
);
496 ok(hr
== S_OK
, "Failed to set writer output, hr %#lx.\n", hr
);
498 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
499 ok(hr
== S_OK
, "Write failed, hr %#lx.\n", hr
);
501 hr
= IXmlWriter_Flush(writer
);
502 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
504 CHECK_OUTPUT_RAW(stream
, utf16_outputW
, sizeof(utf16_outputW
));
506 IStream_Release(stream
);
507 IUnknown_Release(output
);
509 /* Create output with meaningless code page value. */
510 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
511 ok(hr
== S_OK
, "Failed to create stream, hr %#lx.\n", hr
);
514 hr
= CreateXmlWriterOutputWithEncodingCodePage((IUnknown
*)stream
, NULL
, ~0u, &output
);
515 ok(hr
== S_OK
, "Failed to create writer output, hr %#lx.\n", hr
);
517 test_invalid_output_encoding(writer
, output
);
518 CHECK_OUTPUT(stream
, "");
520 IStream_Release(stream
);
521 IUnknown_Release(output
);
523 /* Same, with invalid encoding name. */
524 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
525 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
528 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"dummy", &output
);
529 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
531 test_invalid_output_encoding(writer
, output
);
532 CHECK_OUTPUT(stream
, "");
534 IStream_Release(stream
);
535 IUnknown_Release(output
);
537 IXmlWriter_Release(writer
);
540 static void test_writestartdocument(void)
542 static const char fullprolog
[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
543 static const char *prologversion2
= "<?xml version=\"1.0\" encoding=\"uS-asCii\"?>";
544 static const char prologversion
[] = "<?xml version=\"1.0\"?>";
545 IXmlWriterOutput
*output
;
550 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
551 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
554 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
555 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
557 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
558 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
560 hr
= IXmlWriter_Flush(writer
);
561 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
563 stream
= writer_set_output(writer
);
565 /* nothing written yet */
566 hr
= IXmlWriter_Flush(writer
);
567 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
569 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
570 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
572 hr
= IXmlWriter_Flush(writer
);
573 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
575 CHECK_OUTPUT(stream
, fullprolog
);
578 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
579 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
580 IStream_Release(stream
);
582 /* now add PI manually, and try to start a document */
583 stream
= writer_set_output(writer
);
585 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
586 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
588 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
589 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
591 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
592 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
594 /* another attempt to add 'xml' PI */
595 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
596 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
598 hr
= IXmlWriter_Flush(writer
);
599 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
601 CHECK_OUTPUT(stream
, prologversion
);
603 IStream_Release(stream
);
604 IXmlWriter_Release(writer
);
606 /* create with us-ascii */
607 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
608 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
611 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"uS-asCii", &output
);
612 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
614 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
615 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
617 hr
= IXmlWriter_SetOutput(writer
, output
);
618 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
620 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
621 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
623 hr
= IXmlWriter_Flush(writer
);
624 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
626 CHECK_OUTPUT(stream
, prologversion2
);
628 IStream_Release(stream
);
629 IXmlWriter_Release(writer
);
630 IUnknown_Release(output
);
633 static void test_flush(void)
638 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
639 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
641 hr
= IXmlWriter_SetOutput(writer
, (IUnknown
*)&teststream
);
642 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
644 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
645 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
648 hr
= IXmlWriter_Flush(writer
);
649 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
650 ok(g_write_len
> 0, "Unexpected length %lu.\n", g_write_len
);
653 hr
= IXmlWriter_Flush(writer
);
654 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
655 ok(g_write_len
== 0, "Unexpected length %lu.\n", g_write_len
);
657 /* Release() flushes too */
659 IXmlWriter_Release(writer
);
660 ok(g_write_len
== 0, "Unexpected length %lu.\n", g_write_len
);
663 static void test_omitxmldeclaration(void)
665 static const char prologversion
[] = "<?xml version=\"1.0\"?>";
672 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
673 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
675 stream
= writer_set_output(writer
);
677 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
679 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
680 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
682 hr
= IXmlWriter_Flush(writer
);
683 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
685 hr
= GetHGlobalFromStream(stream
, &hglobal
);
686 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
688 ptr
= GlobalLock(hglobal
);
689 ok(!ptr
, "got %p\n", ptr
);
690 GlobalUnlock(hglobal
);
693 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
694 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
696 IStream_Release(stream
);
698 /* now add PI manually, and try to start a document */
699 stream
= writer_set_output(writer
);
701 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
702 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
704 hr
= IXmlWriter_Flush(writer
);
705 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
707 CHECK_OUTPUT(stream
, prologversion
);
709 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
710 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
712 hr
= IXmlWriter_Flush(writer
);
713 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
715 CHECK_OUTPUT(stream
, prologversion
);
717 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
718 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
720 hr
= IXmlWriter_Flush(writer
);
721 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
723 CHECK_OUTPUT(stream
, prologversion
);
725 /* another attempt to add 'xml' PI */
726 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
727 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
729 hr
= IXmlWriter_Flush(writer
);
730 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
732 IStream_Release(stream
);
733 IXmlWriter_Release(writer
);
736 static void test_bom(void)
738 static const WCHAR piW
[] = {0xfeff,'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"','?','>'};
739 static const WCHAR aopenW
[] = {0xfeff,'<','a'};
740 static const WCHAR afullW
[] = {0xfeff,'<','a',' ','/','>'};
741 static const WCHAR bomW
[] = {0xfeff};
742 IXmlWriterOutput
*output
;
748 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
749 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
751 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"utf-16", &output
);
752 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
754 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
755 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
757 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
759 hr
= IXmlWriter_SetOutput(writer
, output
);
760 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
762 /* BOM is on by default */
763 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
764 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
766 hr
= IXmlWriter_Flush(writer
);
767 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
769 CHECK_OUTPUT_RAW(stream
, bomW
, sizeof(bomW
));
771 IStream_Release(stream
);
772 IUnknown_Release(output
);
775 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
776 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
778 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"utf-16", &output
);
779 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
781 hr
= IXmlWriter_SetOutput(writer
, output
);
782 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
784 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
785 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
787 hr
= IXmlWriter_Flush(writer
);
788 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
790 CHECK_OUTPUT_RAW(stream
, piW
, sizeof(piW
));
792 IUnknown_Release(output
);
793 IStream_Release(stream
);
795 /* start with element */
796 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
797 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
799 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"utf-16", &output
);
800 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
802 hr
= IXmlWriter_SetOutput(writer
, output
);
803 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
805 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
806 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
808 hr
= IXmlWriter_Flush(writer
);
809 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
811 CHECK_OUTPUT_RAW(stream
, aopenW
, sizeof(aopenW
));
813 IUnknown_Release(output
);
814 IStream_Release(stream
);
816 /* WriteElementString */
817 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
818 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
820 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"utf-16", &output
);
821 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
823 hr
= IXmlWriter_SetOutput(writer
, output
);
824 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
826 writer_set_property(writer
, XmlWriterProperty_Indent
);
828 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"a", NULL
, NULL
);
829 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
831 hr
= IXmlWriter_Flush(writer
);
832 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
834 hr
= GetHGlobalFromStream(stream
, &hglobal
);
835 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
837 CHECK_OUTPUT_RAW(stream
, afullW
, sizeof(afullW
));
839 IUnknown_Release(output
);
840 IStream_Release(stream
);
842 IXmlWriter_Release(writer
);
845 static void test_WriteStartElement(void)
853 const char *output_partial
;
858 start_element_tests
[] =
860 { L
"prefix", L
"local", L
"uri", "<prefix:local xmlns:prefix=\"uri\" />", "<prefix:local" },
861 { NULL
, L
"local", L
"uri", "<local xmlns=\"uri\" />", "<local" },
862 { L
"", L
"local", L
"uri", "<local xmlns=\"uri\" />", "<local" },
863 { L
"", L
"local", L
"uri", "<local xmlns=\"uri\" />", "<local" },
864 { NULL
, L
"local", NULL
, "<local />", "<local" },
865 { NULL
, L
"local", L
"", "<local />", "<local" },
867 { L
"prefix", NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
868 { NULL
, NULL
, L
"uri", NULL
, NULL
, E_INVALIDARG
},
869 { NULL
, NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
870 { NULL
, L
"prefix:local", L
"uri", NULL
, NULL
, WC_E_NAMECHARACTER
},
871 { L
"pre:fix", L
"local", L
"uri", NULL
, NULL
, WC_E_NAMECHARACTER
},
872 { NULL
, L
":local", L
"uri", NULL
, NULL
, WC_E_NAMECHARACTER
},
873 { L
":", L
"local", L
"uri", NULL
, NULL
, WC_E_NAMECHARACTER
},
874 { NULL
, L
"local", L
"http://www.w3.org/2000/xmlns/", NULL
, NULL
, WR_E_XMLNSPREFIXDECLARATION
},
875 { L
"prefix", L
"local", L
"http://www.w3.org/2000/xmlns/", NULL
, NULL
, WR_E_XMLNSURIDECLARATION
},
882 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
883 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
885 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
886 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
888 stream
= writer_set_output(writer
);
890 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
891 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
893 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
894 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
896 hr
= IXmlWriter_Flush(writer
);
897 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
899 CHECK_OUTPUT(stream
, "<a");
901 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
902 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
904 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, NULL
, NULL
);
905 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
907 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"a", L
"a");
908 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
910 IStream_Release(stream
);
911 IXmlWriter_Release(writer
);
913 /* WriteElementString */
914 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
915 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
917 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, L
"value");
918 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
920 stream
= writer_set_output(writer
);
922 hr
= IXmlWriter_WriteStartElement(writer
, L
"prefix", L
"a", L
"uri");
923 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
925 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, L
"value");
926 ok(hr
== S_OK
, "Failed to write element string, hr %#lx.\n", hr
);
928 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"c", NULL
, NULL
);
929 ok(hr
== S_OK
, "Failed to write element string, hr %#lx.\n", hr
);
931 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"d", L
"uri");
932 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
934 hr
= IXmlWriter_WriteStartElement(writer
, L
"", L
"e", L
"uri");
935 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
937 hr
= IXmlWriter_WriteStartElement(writer
, L
"prefix2", L
"f", L
"uri");
938 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
940 hr
= IXmlWriter_Flush(writer
);
941 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
944 "<prefix:a xmlns:prefix=\"uri\">"
951 IStream_Release(stream
);
953 /* WriteStartElement */
954 for (i
= 0; i
< ARRAY_SIZE(start_element_tests
); ++i
)
956 stream
= writer_set_output(writer
);
958 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
960 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
961 ok(hr
== S_OK
, "Failed to start document, hr %#lx.\n", hr
);
963 hr
= IXmlWriter_WriteStartElement(writer
, start_element_tests
[i
].prefix
, start_element_tests
[i
].local
,
964 start_element_tests
[i
].uri
);
965 ok(hr
== start_element_tests
[i
].hr
, "%u: unexpected hr %#lx.\n", i
, hr
);
967 if (SUCCEEDED(start_element_tests
[i
].hr
))
969 hr
= IXmlWriter_Flush(writer
);
970 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
972 check_output(stream
, start_element_tests
[i
].output_partial
, start_element_tests
[i
].todo_partial
, __LINE__
);
974 hr
= IXmlWriter_WriteEndDocument(writer
);
975 ok(hr
== S_OK
, "Failed to end document, hr %#lx.\n", hr
);
977 hr
= IXmlWriter_Flush(writer
);
978 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
980 check_output(stream
, start_element_tests
[i
].output
, start_element_tests
[i
].todo
, __LINE__
);
983 IStream_Release(stream
);
986 IXmlWriter_Release(writer
);
989 static void test_WriteElementString(void)
1001 element_string_tests
[] =
1003 { L
"prefix", L
"local", L
"uri", L
"value", "<prefix:local xmlns:prefix=\"uri\">value</prefix:local>" },
1004 { NULL
, L
"local", L
"uri", L
"value", "<local xmlns=\"uri\">value</local>" },
1005 { L
"", L
"local", L
"uri", L
"value", "<local xmlns=\"uri\">value</local>" },
1006 { L
"prefix", L
"local", L
"uri", NULL
, "<prefix:local xmlns:prefix=\"uri\" />" },
1007 { NULL
, L
"local", L
"uri", NULL
, "<local xmlns=\"uri\" />" },
1008 { L
"", L
"local", L
"uri", NULL
, "<local xmlns=\"uri\" />" },
1009 { NULL
, L
"local", NULL
, NULL
, "<local />" },
1010 { L
"prefix", L
"local", L
"uri", L
"", "<prefix:local xmlns:prefix=\"uri\"></prefix:local>" },
1011 { NULL
, L
"local", L
"uri", L
"", "<local xmlns=\"uri\"></local>" },
1012 { L
"", L
"local", L
"uri", L
"", "<local xmlns=\"uri\"></local>" },
1013 { NULL
, L
"local", NULL
, L
"", "<local></local>" },
1014 { L
"", L
"local", L
"http://www.w3.org/2000/xmlns/", NULL
, "<local xmlns=\"http://www.w3.org/2000/xmlns/\" />" },
1016 { L
"prefix", NULL
, NULL
, L
"value", NULL
, E_INVALIDARG
},
1017 { NULL
, NULL
, L
"uri", L
"value", NULL
, E_INVALIDARG
},
1018 { NULL
, NULL
, NULL
, L
"value", NULL
, E_INVALIDARG
},
1019 { NULL
, L
"prefix:local", L
"uri", L
"value", NULL
, WC_E_NAMECHARACTER
},
1020 { NULL
, L
":local", L
"uri", L
"value", NULL
, WC_E_NAMECHARACTER
},
1021 { L
":", L
"local", L
"uri", L
"value", NULL
, WC_E_NAMECHARACTER
},
1022 { L
"prefix", L
"local", NULL
, L
"value", NULL
, WR_E_NSPREFIXWITHEMPTYNSURI
},
1023 { L
"prefix", L
"local", L
"", L
"value", NULL
, WR_E_NSPREFIXWITHEMPTYNSURI
},
1024 { NULL
, L
"local", L
"http://www.w3.org/2000/xmlns/", L
"value", NULL
, WR_E_XMLNSPREFIXDECLARATION
},
1025 { L
"prefix", L
"local", L
"http://www.w3.org/2000/xmlns/", L
"value", NULL
, WR_E_XMLNSURIDECLARATION
},
1032 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1033 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1035 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, L
"value");
1036 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1038 stream
= writer_set_output(writer
);
1040 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1041 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1043 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, L
"value");
1044 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1046 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, NULL
);
1047 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1049 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix", L
"b", L
"uri", NULL
);
1050 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1052 hr
= IXmlWriter_WriteStartElement(writer
, L
"prefix", L
"c", L
"uri");
1053 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1055 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix", L
"d", NULL
, NULL
);
1056 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1058 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix2", L
"d", L
"uri", NULL
);
1059 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1061 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"e", L
"uri", NULL
);
1062 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1064 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix", L
"f", L
"uri2", NULL
);
1065 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1067 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"g", L
"uri3", NULL
);
1068 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1070 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix", L
"h", NULL
, NULL
);
1071 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1073 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix_i", L
"i", NULL
, NULL
);
1074 ok(hr
== WR_E_NSPREFIXWITHEMPTYNSURI
, "Failed to write element, hr %#lx.\n", hr
);
1076 hr
= IXmlWriter_WriteElementString(writer
, L
"", L
"j", L
"uri", NULL
);
1077 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1079 hr
= IXmlWriter_Flush(writer
);
1080 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1082 CHECK_OUTPUT(stream
,
1083 "<a><b>value</b><b />"
1084 "<prefix:b xmlns:prefix=\"uri\" />"
1085 "<prefix:c xmlns:prefix=\"uri\">"
1087 "<prefix2:d xmlns:prefix2=\"uri\" />"
1089 "<prefix:f xmlns:prefix=\"uri2\" />"
1090 "<g xmlns=\"uri3\" />"
1092 "<j xmlns=\"uri\" />");
1094 IStream_Release(stream
);
1096 for (i
= 0; i
< ARRAY_SIZE(element_string_tests
); ++i
)
1098 stream
= writer_set_output(writer
);
1100 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1102 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1103 ok(hr
== S_OK
, "Failed to start document, hr %#lx.\n", hr
);
1105 hr
= IXmlWriter_WriteElementString(writer
, element_string_tests
[i
].prefix
, element_string_tests
[i
].local
,
1106 element_string_tests
[i
].uri
, element_string_tests
[i
].value
);
1107 ok(hr
== element_string_tests
[i
].hr
, "%u: unexpected hr %#lx.\n", i
, hr
);
1109 if (SUCCEEDED(element_string_tests
[i
].hr
))
1111 hr
= IXmlWriter_Flush(writer
);
1112 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1114 check_output(stream
, element_string_tests
[i
].output
, element_string_tests
[i
].todo
, __LINE__
);
1116 hr
= IXmlWriter_WriteEndDocument(writer
);
1117 ok(hr
== S_OK
, "Failed to end document, hr %#lx.\n", hr
);
1119 hr
= IXmlWriter_Flush(writer
);
1120 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1122 check_output(stream
, element_string_tests
[i
].output
, element_string_tests
[i
].todo
, __LINE__
);
1125 IStream_Release(stream
);
1128 IXmlWriter_Release(writer
);
1131 static void test_WriteEndElement(void)
1137 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1138 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1140 stream
= writer_set_output(writer
);
1142 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1143 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1145 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1146 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1148 hr
= IXmlWriter_WriteEndElement(writer
);
1149 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1151 hr
= IXmlWriter_WriteEndElement(writer
);
1152 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1154 hr
= IXmlWriter_Flush(writer
);
1155 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1157 CHECK_OUTPUT(stream
, "<a><b /></a>");
1159 IXmlWriter_Release(writer
);
1160 IStream_Release(stream
);
1163 static void test_writeenddocument(void)
1171 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1172 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1174 hr
= IXmlWriter_WriteEndDocument(writer
);
1175 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1177 stream
= writer_set_output(writer
);
1179 /* WriteEndDocument resets it to initial state */
1180 hr
= IXmlWriter_WriteEndDocument(writer
);
1181 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1183 hr
= IXmlWriter_WriteEndDocument(writer
);
1184 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1186 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1187 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1189 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1190 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1192 hr
= IXmlWriter_SetOutput(writer
, (IUnknown
*)stream
);
1193 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1195 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1196 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1198 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1199 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1201 hr
= IXmlWriter_WriteEndDocument(writer
);
1202 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1204 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1205 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1207 ptr
= GlobalLock(hglobal
);
1208 ok(ptr
== NULL
, "got %p\n", ptr
);
1210 /* we still need to flush manually, WriteEndDocument doesn't do that */
1211 hr
= IXmlWriter_Flush(writer
);
1212 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1214 CHECK_OUTPUT(stream
, "<a><b /></a>");
1216 IXmlWriter_Release(writer
);
1217 IStream_Release(stream
);
1220 static void test_WriteComment(void)
1226 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1227 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1229 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1231 hr
= IXmlWriter_WriteComment(writer
, L
"a");
1232 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1234 stream
= writer_set_output(writer
);
1236 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1237 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1239 hr
= IXmlWriter_WriteComment(writer
, L
"a");
1240 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1242 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1243 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1245 hr
= IXmlWriter_WriteComment(writer
, L
"a");
1246 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1248 hr
= IXmlWriter_WriteComment(writer
, NULL
);
1249 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1251 hr
= IXmlWriter_WriteComment(writer
, L
"-->");
1252 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1254 hr
= IXmlWriter_Flush(writer
);
1255 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1257 CHECK_OUTPUT(stream
, "<!--a--><b><!--a--><!----><!--- ->-->");
1259 IXmlWriter_Release(writer
);
1260 IStream_Release(stream
);
1263 static void test_WriteCData(void)
1269 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1270 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1272 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1274 hr
= IXmlWriter_WriteCData(writer
, L
"a");
1275 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1277 stream
= writer_set_output(writer
);
1279 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1280 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1282 hr
= IXmlWriter_WriteCData(writer
, L
"a");
1283 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1285 hr
= IXmlWriter_WriteCData(writer
, NULL
);
1286 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1288 hr
= IXmlWriter_WriteCData(writer
, L
"]]>");
1289 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1291 hr
= IXmlWriter_WriteCData(writer
, L
"a]]>b");
1292 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1294 hr
= IXmlWriter_Flush(writer
);
1295 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1297 CHECK_OUTPUT(stream
,
1306 IXmlWriter_Release(writer
);
1307 IStream_Release(stream
);
1310 static void test_WriteRaw(void)
1312 static const WCHAR rawW
[] = L
"a<:";
1317 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1318 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1320 hr
= IXmlWriter_WriteRaw(writer
, NULL
);
1321 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1323 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1324 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1326 stream
= writer_set_output(writer
);
1328 hr
= IXmlWriter_WriteRaw(writer
, NULL
);
1329 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1331 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1332 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1334 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1335 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1337 hr
= IXmlWriter_WriteComment(writer
, rawW
);
1338 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1340 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1341 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1343 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"a", NULL
, L
"a");
1344 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1346 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
1347 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1349 hr
= IXmlWriter_WriteComment(writer
, rawW
);
1350 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1352 hr
= IXmlWriter_WriteEndDocument(writer
);
1353 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1355 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1356 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1358 hr
= IXmlWriter_Flush(writer
);
1359 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1360 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>a<:a<:<!--a<:-->a<:<a>a</a>");
1361 IStream_Release(stream
);
1363 /* With open element. */
1364 stream
= writer_set_output(writer
);
1366 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
1367 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1368 hr
= IXmlWriter_WriteRaw(writer
, L
"text");
1369 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1371 hr
= IXmlWriter_Flush(writer
);
1372 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1373 CHECK_OUTPUT(stream
, "<w>text");
1374 IStream_Release(stream
);
1376 IXmlWriter_Release(writer
);
1379 static void test_writer_state(void)
1385 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1386 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1389 check_writer_state(writer
, E_UNEXPECTED
);
1391 /* set output and call 'wrong' method, WriteEndElement */
1392 stream
= writer_set_output(writer
);
1394 hr
= IXmlWriter_WriteEndElement(writer
);
1395 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1397 check_writer_state(writer
, WR_E_INVALIDACTION
);
1398 IStream_Release(stream
);
1400 /* WriteAttributeString */
1401 stream
= writer_set_output(writer
);
1403 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"a", NULL
, L
"a");
1404 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1406 check_writer_state(writer
, WR_E_INVALIDACTION
);
1407 IStream_Release(stream
);
1409 /* WriteEndDocument */
1410 stream
= writer_set_output(writer
);
1412 hr
= IXmlWriter_WriteEndDocument(writer
);
1413 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1415 check_writer_state(writer
, WR_E_INVALIDACTION
);
1416 IStream_Release(stream
);
1418 /* WriteFullEndElement */
1419 stream
= writer_set_output(writer
);
1421 hr
= IXmlWriter_WriteFullEndElement(writer
);
1422 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1424 check_writer_state(writer
, WR_E_INVALIDACTION
);
1425 IStream_Release(stream
);
1428 stream
= writer_set_output(writer
);
1430 hr
= IXmlWriter_WriteCData(writer
, L
"a");
1431 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1433 check_writer_state(writer
, WR_E_INVALIDACTION
);
1434 IStream_Release(stream
);
1437 stream
= writer_set_output(writer
);
1439 hr
= IXmlWriter_WriteName(writer
, L
"a");
1440 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1442 check_writer_state(writer
, WR_E_INVALIDACTION
);
1443 IStream_Release(stream
);
1446 stream
= writer_set_output(writer
);
1448 hr
= IXmlWriter_WriteNmToken(writer
, L
"a");
1449 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1451 check_writer_state(writer
, WR_E_INVALIDACTION
);
1452 IStream_Release(stream
);
1455 stream
= writer_set_output(writer
);
1457 hr
= IXmlWriter_WriteString(writer
, L
"a");
1458 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1460 check_writer_state(writer
, WR_E_INVALIDACTION
);
1461 IStream_Release(stream
);
1463 IXmlWriter_Release(writer
);
1466 static void test_indentation(void)
1472 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1473 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1475 stream
= writer_set_output(writer
);
1477 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1478 writer_set_property(writer
, XmlWriterProperty_Indent
);
1480 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1481 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1483 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1484 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1486 hr
= IXmlWriter_WriteComment(writer
, L
"comment");
1487 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1489 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1490 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1492 hr
= IXmlWriter_WriteEndDocument(writer
);
1493 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1495 hr
= IXmlWriter_Flush(writer
);
1496 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1498 CHECK_OUTPUT(stream
,
1500 " <!--comment-->\r\n"
1504 IStream_Release(stream
);
1506 /* WriteElementString */
1507 stream
= writer_set_output(writer
);
1509 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1510 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1512 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, NULL
);
1513 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1515 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, NULL
);
1516 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1518 hr
= IXmlWriter_WriteEndElement(writer
);
1519 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1521 hr
= IXmlWriter_Flush(writer
);
1522 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1524 CHECK_OUTPUT(stream
,
1530 IStream_Release(stream
);
1532 IXmlWriter_Release(writer
);
1535 static void test_WriteAttributeString(void)
1539 const WCHAR
*prefix
;
1544 const char *output_partial
;
1552 { NULL
, L
"a", NULL
, L
"b", "<e a=\"b\" />", "<e a=\"b\"" },
1553 { L
"", L
"a", NULL
, L
"b", "<e a=\"b\" />", "<e a=\"b\"" },
1554 { NULL
, L
"a", L
"", L
"b", "<e a=\"b\" />", "<e a=\"b\"" },
1555 { L
"", L
"a", L
"", L
"b", "<e a=\"b\" />", "<e a=\"b\"" },
1556 { L
"prefix", L
"local", L
"uri", L
"b", "<e prefix:local=\"b\" xmlns:prefix=\"uri\" />", "<e prefix:local=\"b\"" },
1557 { NULL
, L
"a", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e xmlns:a=\"defuri\" />", "<e xmlns:a=\"defuri\"" },
1558 { L
"xmlns", L
"a", NULL
, L
"uri", "<e xmlns:a=\"uri\" />", "<e xmlns:a=\"uri\"" },
1559 { L
"xmlns", L
"a", L
"", L
"uri", "<e xmlns:a=\"uri\" />", "<e xmlns:a=\"uri\"" },
1560 { L
"prefix", L
"xmlns", L
"uri", L
"value", "<e prefix:xmlns=\"value\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"value\"" },
1561 { L
"prefix", L
"xmlns", L
"uri", NULL
, "<e prefix:xmlns=\"\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"\"" },
1562 { L
"prefix", L
"xmlns", L
"uri", L
"", "<e prefix:xmlns=\"\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"\"" },
1563 { L
"prefix", L
"xmlns", NULL
, L
"uri", "<e xmlns=\"uri\" />", "<e xmlns=\"uri\"" },
1564 { L
"prefix", L
"xmlns", L
"", L
"uri", "<e xmlns=\"uri\" />", "<e xmlns=\"uri\"" },
1565 { L
"xml", L
"space", NULL
, L
"preserve", "<e xml:space=\"preserve\" />", "<e xml:space=\"preserve\"" },
1566 { L
"xml", L
"space", L
"", L
"preserve", "<e xml:space=\"preserve\" />", "<e xml:space=\"preserve\"" },
1567 { L
"xml", L
"space", NULL
, L
"default", "<e xml:space=\"default\" />", "<e xml:space=\"default\"" },
1568 { L
"xml", L
"space", L
"", L
"default", "<e xml:space=\"default\" />", "<e xml:space=\"default\"" },
1569 { L
"xml", L
"a", NULL
, L
"value", "<e xml:a=\"value\" />", "<e xml:a=\"value\"" },
1570 { L
"xml", L
"a", L
"", L
"value", "<e xml:a=\"value\" />", "<e xml:a=\"value\"" },
1572 /* Autogenerated prefix names. */
1573 { NULL
, L
"a", L
"defuri", NULL
, "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK
, 1, 1, 1 },
1574 { NULL
, L
"a", L
"defuri", L
"b", "<e p1:a=\"b\" xmlns:p1=\"defuri\" />", "<e p1:a=\"b\"", S_OK
, 1, 1, 1 },
1575 { L
"", L
"a", L
"defuri", NULL
, "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK
, 1, 1, 1 },
1576 { NULL
, L
"a", L
"defuri", L
"", "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK
, 1, 1, 1 },
1577 { L
"", L
"a", L
"defuri", L
"b", "<e p1:a=\"b\" xmlns:p1=\"defuri\" />", "<e p1:a=\"b\"", S_OK
, 1, 1, 1 },
1579 /* Failing cases. */
1580 { NULL
, NULL
, L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1581 { L
"", L
"a", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
, 1, 1, 1 },
1582 { L
"", NULL
, L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1583 { L
"", L
"", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1584 { NULL
, L
"", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1585 { L
"prefix", L
"a", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", WR_E_XMLNSURIDECLARATION
, 1, 1, 1 },
1586 { L
"prefix", NULL
, L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1587 { L
"prefix", NULL
, NULL
, L
"b", "<e />", "<e", E_INVALIDARG
},
1588 { L
"prefix", NULL
, L
"uri", NULL
, "<e />", "<e", E_INVALIDARG
},
1589 { L
"xml", NULL
, NULL
, L
"value", "<e />", "<e", E_INVALIDARG
},
1590 { L
"xmlns", L
"a", L
"defuri", NULL
, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
},
1591 { L
"xmlns", L
"a", L
"b", L
"uri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
},
1592 { NULL
, L
"xmlns", L
"uri", NULL
, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
, 0, 0, 1 },
1593 { L
"xmlns", NULL
, L
"uri", NULL
, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
, 0, 0, 1 },
1594 { L
"pre:fix", L
"local", L
"uri", L
"b", "<e />", "<e", WC_E_NAMECHARACTER
},
1595 { L
"pre:fix", NULL
, L
"uri", L
"b", "<e />", "<e", E_INVALIDARG
},
1596 { L
"prefix", L
"lo:cal", L
"uri", L
"b", "<e />", "<e", WC_E_NAMECHARACTER
},
1597 { L
"xmlns", NULL
, NULL
, L
"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED
},
1598 { L
"xmlns", NULL
, L
"", L
"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED
},
1599 { L
"xmlns", L
"", NULL
, L
"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED
},
1600 { L
"xmlns", L
"", L
"", L
"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED
},
1601 { L
"xml", L
"space", L
"", L
"value", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1602 { L
"xml", L
"space", NULL
, L
"value", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1603 { L
"xml", L
"a", L
"uri", L
"value", "<e />", "<e", WR_E_XMLPREFIXDECLARATION
},
1604 { L
"xml", L
"space", NULL
, L
"preServe", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1605 { L
"xml", L
"space", NULL
, L
"defAult", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1606 { L
"xml", L
"space", NULL
, NULL
, "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1607 { L
"xml", L
"space", NULL
, L
"", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1615 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1616 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1618 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1620 for (i
= 0; i
< ARRAY_SIZE(attribute_tests
); ++i
)
1622 winetest_push_context("Test %u", i
);
1624 stream
= writer_set_output(writer
);
1626 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1627 ok(hr
== S_OK
, "Failed to start document, hr %#lx.\n", hr
);
1629 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"e", NULL
);
1630 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1632 hr
= IXmlWriter_WriteAttributeString(writer
, attribute_tests
[i
].prefix
, attribute_tests
[i
].local
,
1633 attribute_tests
[i
].uri
, attribute_tests
[i
].value
);
1634 todo_wine_if(attribute_tests
[i
].todo_hr
)
1635 ok(hr
== attribute_tests
[i
].hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, attribute_tests
[i
].hr
);
1637 hr
= IXmlWriter_Flush(writer
);
1638 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1640 check_output(stream
, attribute_tests
[i
].output_partial
, attribute_tests
[i
].todo_partial
, __LINE__
);
1642 hr
= IXmlWriter_WriteEndDocument(writer
);
1643 ok(hr
== S_OK
, "Failed to end document, hr %#lx.\n", hr
);
1645 hr
= IXmlWriter_Flush(writer
);
1646 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1648 check_output(stream
, attribute_tests
[i
].output
, attribute_tests
[i
].todo
, __LINE__
);
1649 IStream_Release(stream
);
1651 winetest_pop_context();
1654 /* With namespaces */
1655 stream
= writer_set_output(writer
);
1657 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1658 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1660 hr
= IXmlWriter_WriteStartElement(writer
, L
"p", L
"a", L
"outeruri");
1661 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1663 hr
= IXmlWriter_WriteAttributeString(writer
, L
"prefix", L
"local", L
"uri", L
"b");
1664 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1666 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"a", NULL
, L
"b");
1667 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1669 hr
= IXmlWriter_WriteAttributeString(writer
, L
"xmlns", L
"prefix", NULL
, L
"uri");
1670 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1672 hr
= IXmlWriter_WriteAttributeString(writer
, L
"p", L
"attr", NULL
, L
"value");
1673 ok(hr
== S_OK
, "Failed to write attribute string, hr %#lx.\n", hr
);
1675 hr
= IXmlWriter_WriteAttributeString(writer
, L
"prefix", L
"local", NULL
, L
"b");
1677 ok(hr
== WR_E_DUPLICATEATTRIBUTE
, "Unexpected hr %#lx.\n", hr
);
1679 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1680 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1682 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"attr2", L
"outeruri", L
"value");
1683 ok(hr
== S_OK
, "Failed to write attribute string, hr %#lx.\n", hr
);
1685 hr
= IXmlWriter_WriteAttributeString(writer
, L
"pr", L
"attr3", L
"outeruri", L
"value");
1686 ok(hr
== S_OK
, "Failed to write attribute string, hr %#lx.\n", hr
);
1688 hr
= IXmlWriter_WriteEndDocument(writer
);
1689 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1691 hr
= IXmlWriter_Flush(writer
);
1692 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1694 CHECK_OUTPUT_TODO(stream
,
1695 "<p:a prefix:local=\"b\" a=\"b\" xmlns:prefix=\"uri\" p:attr=\"value\" xmlns:p=\"outeruri\">"
1696 "<b p:attr2=\"value\" pr:attr3=\"value\" xmlns:pr=\"outeruri\" />"
1699 IStream_Release(stream
);
1701 /* Define prefix, write attribute with it. */
1702 stream
= writer_set_output(writer
);
1704 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1705 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1707 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"e", NULL
);
1708 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1710 hr
= IXmlWriter_WriteAttributeString(writer
, L
"xmlns", L
"prefix", NULL
, L
"uri");
1711 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1713 hr
= IXmlWriter_WriteAttributeString(writer
, L
"prefix", L
"attr", NULL
, L
"value");
1714 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1716 hr
= IXmlWriter_WriteEndDocument(writer
);
1717 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1719 hr
= IXmlWriter_Flush(writer
);
1720 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1722 CHECK_OUTPUT(stream
,
1723 "<e xmlns:prefix=\"uri\" prefix:attr=\"value\" />");
1725 IStream_Release(stream
);
1727 IXmlWriter_Release(writer
);
1730 static void test_WriteFullEndElement(void)
1736 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1737 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1739 /* standalone element */
1740 stream
= writer_set_output(writer
);
1742 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1743 writer_set_property(writer
, XmlWriterProperty_Indent
);
1745 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1746 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1748 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1749 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1751 hr
= IXmlWriter_WriteFullEndElement(writer
);
1752 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1754 hr
= IXmlWriter_WriteEndDocument(writer
);
1755 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1757 hr
= IXmlWriter_Flush(writer
);
1758 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1760 CHECK_OUTPUT(stream
,
1762 IStream_Release(stream
);
1764 /* nested elements */
1765 stream
= writer_set_output(writer
);
1767 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1768 writer_set_property(writer
, XmlWriterProperty_Indent
);
1770 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1771 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1773 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1774 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1776 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1777 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1779 hr
= IXmlWriter_WriteFullEndElement(writer
);
1780 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1782 hr
= IXmlWriter_WriteEndDocument(writer
);
1783 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1785 hr
= IXmlWriter_Flush(writer
);
1786 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1788 CHECK_OUTPUT(stream
,
1792 IStream_Release(stream
);
1794 /* Empty strings for prefix and uri. */
1795 stream
= writer_set_output(writer
);
1797 hr
= IXmlWriter_SetProperty(writer
, XmlWriterProperty_Indent
, FALSE
);
1798 ok(hr
== S_OK
, "Failed to set property, hr %#lx.\n", hr
);
1800 hr
= IXmlWriter_WriteStartElement(writer
, L
"", L
"a", NULL
);
1801 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1802 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", L
"");
1803 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1804 hr
= IXmlWriter_WriteStartElement(writer
, L
"", L
"c", L
"");
1805 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1806 hr
= IXmlWriter_WriteFullEndElement(writer
);
1807 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1808 hr
= IXmlWriter_WriteFullEndElement(writer
);
1809 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1810 hr
= IXmlWriter_WriteFullEndElement(writer
);
1811 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1813 hr
= IXmlWriter_Flush(writer
);
1814 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1815 CHECK_OUTPUT(stream
, "<a><b><c></c></b></a>");
1816 IStream_Release(stream
);
1818 IXmlWriter_Release(writer
);
1821 static void test_WriteCharEntity(void)
1827 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1828 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1830 /* without indentation */
1831 stream
= writer_set_output(writer
);
1833 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1835 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1836 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1838 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1839 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1841 hr
= IXmlWriter_WriteCharEntity(writer
, 0x100);
1842 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1844 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1845 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1847 hr
= IXmlWriter_WriteEndDocument(writer
);
1848 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1850 hr
= IXmlWriter_Flush(writer
);
1851 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1853 CHECK_OUTPUT(stream
,
1854 "<a>Ā<a /></a>");
1856 IXmlWriter_Release(writer
);
1857 IStream_Release(stream
);
1860 static void test_WriteString(void)
1866 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1867 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1869 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1871 hr
= IXmlWriter_WriteString(writer
, L
"a");
1872 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1874 hr
= IXmlWriter_WriteString(writer
, NULL
);
1875 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1877 hr
= IXmlWriter_WriteString(writer
, L
"");
1878 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1880 stream
= writer_set_output(writer
);
1882 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1883 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1885 hr
= IXmlWriter_WriteString(writer
, NULL
);
1886 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1888 hr
= IXmlWriter_WriteString(writer
, L
"");
1889 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1891 hr
= IXmlWriter_WriteString(writer
, L
"a");
1892 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1894 /* WriteString automatically escapes markup characters */
1895 hr
= IXmlWriter_WriteString(writer
, L
"<&\">=");
1896 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1898 hr
= IXmlWriter_Flush(writer
);
1899 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1901 CHECK_OUTPUT(stream
,
1902 "<b>a<&\">=");
1903 IStream_Release(stream
);
1905 stream
= writer_set_output(writer
);
1907 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1908 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1910 hr
= IXmlWriter_WriteString(writer
, NULL
);
1911 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1913 hr
= IXmlWriter_Flush(writer
);
1914 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1916 CHECK_OUTPUT(stream
,
1919 hr
= IXmlWriter_WriteString(writer
, L
"");
1920 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1922 hr
= IXmlWriter_Flush(writer
);
1923 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1925 CHECK_OUTPUT(stream
,
1928 IStream_Release(stream
);
1929 IXmlWriter_Release(writer
);
1931 /* With indentation */
1932 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
1933 ok(hr
== S_OK
, "Failed to create a writer, hr %#lx.\n", hr
);
1935 stream
= writer_set_output(writer
);
1937 writer_set_property(writer
, XmlWriterProperty_Indent
);
1939 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1940 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1942 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1943 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1945 hr
= IXmlWriter_WriteString(writer
, L
"text");
1946 ok(hr
== S_OK
, "Failed to write a string, hr %#lx.\n", hr
);
1948 hr
= IXmlWriter_Flush(writer
);
1949 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1951 CHECK_OUTPUT(stream
,
1955 hr
= IXmlWriter_WriteFullEndElement(writer
);
1956 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
1958 hr
= IXmlWriter_Flush(writer
);
1959 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1961 CHECK_OUTPUT(stream
,
1965 hr
= IXmlWriter_WriteFullEndElement(writer
);
1966 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
1968 hr
= IXmlWriter_Flush(writer
);
1969 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1971 CHECK_OUTPUT(stream
,
1976 IStream_Release(stream
);
1978 stream
= writer_set_output(writer
);
1980 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1981 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1983 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1984 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1986 hr
= IXmlWriter_WriteEndElement(writer
);
1987 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
1989 hr
= IXmlWriter_Flush(writer
);
1990 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1992 CHECK_OUTPUT(stream
,
1996 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"c", NULL
);
1997 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1999 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"attr", NULL
, L
"value");
2000 ok(hr
== S_OK
, "Failed to write attribute string, hr %#lx.\n", hr
);
2002 hr
= IXmlWriter_Flush(writer
);
2003 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2005 CHECK_OUTPUT(stream
,
2008 " <c attr=\"value\"");
2010 hr
= IXmlWriter_WriteString(writer
, L
"text");
2011 ok(hr
== S_OK
, "Failed to write a string, hr %#lx.\n", hr
);
2013 hr
= IXmlWriter_Flush(writer
);
2014 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2016 CHECK_OUTPUT(stream
,
2019 " <c attr=\"value\">text");
2021 hr
= IXmlWriter_WriteEndElement(writer
);
2022 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
2024 hr
= IXmlWriter_Flush(writer
);
2025 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2027 CHECK_OUTPUT(stream
,
2030 " <c attr=\"value\">text</c>");
2032 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"d", NULL
);
2033 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
2035 hr
= IXmlWriter_WriteString(writer
, L
"");
2036 ok(hr
== S_OK
, "Failed to write a string, hr %#lx.\n", hr
);
2038 hr
= IXmlWriter_WriteEndElement(writer
);
2039 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
2041 hr
= IXmlWriter_Flush(writer
);
2042 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2044 CHECK_OUTPUT(stream
,
2047 " <c attr=\"value\">text</c>\r\n"
2050 hr
= IXmlWriter_WriteEndElement(writer
);
2051 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
2053 hr
= IXmlWriter_Flush(writer
);
2054 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2056 CHECK_OUTPUT(stream
,
2059 " <c attr=\"value\">text</c>\r\n"
2063 IXmlWriter_Release(writer
);
2064 IStream_Release(stream
);
2067 static void test_WriteDocType(void)
2074 const WCHAR
*subset
;
2079 { L
"a", L
"", NULL
, NULL
, "<!DOCTYPE a PUBLIC \"\" \"\">" },
2080 { L
"a", NULL
, NULL
, NULL
, "<!DOCTYPE a>" },
2081 { L
"a", NULL
, L
"", NULL
, "<!DOCTYPE a SYSTEM \"\">" },
2082 { L
"a", L
"", L
"", NULL
, "<!DOCTYPE a PUBLIC \"\" \"\">" },
2083 { L
"a", L
"pubid", L
"", NULL
, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" },
2084 { L
"a", L
"pubid", NULL
, NULL
, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" },
2085 { L
"a", L
"", L
"sysid", NULL
, "<!DOCTYPE a PUBLIC \"\" \"sysid\">" },
2086 { L
"a", NULL
, NULL
, L
"", "<!DOCTYPE a []>" },
2087 { L
"a", NULL
, NULL
, L
"subset", "<!DOCTYPE a [subset]>" },
2088 { L
"a", L
"", NULL
, L
"subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" },
2089 { L
"a", NULL
, L
"", L
"subset", "<!DOCTYPE a SYSTEM \"\" [subset]>" },
2090 { L
"a", L
"", L
"", L
"subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" },
2091 { L
"a", L
"pubid", NULL
, L
"subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" },
2092 { L
"a", L
"pubid", L
"", L
"subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" },
2093 { L
"a", NULL
, L
"sysid", L
"subset", "<!DOCTYPE a SYSTEM \"sysid\" [subset]>" },
2094 { L
"a", L
"", L
"sysid", L
"subset", "<!DOCTYPE a PUBLIC \"\" \"sysid\" [subset]>" },
2095 { L
"a", L
"pubid", L
"sysid", L
"subset", "<!DOCTYPE a PUBLIC \"pubid\" \"sysid\" [subset]>" },
2097 static const WCHAR pubidW
[] = {'p',0x100,'i','d',0};
2103 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2104 ok(hr
== S_OK
, "Failed to create writer instance, hr %#lx.\n", hr
);
2106 stream
= writer_set_output(writer
);
2108 hr
= IXmlWriter_WriteDocType(writer
, NULL
, NULL
, NULL
, NULL
);
2109 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2111 hr
= IXmlWriter_WriteDocType(writer
, L
"", NULL
, NULL
, NULL
);
2112 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2114 /* Name validation. */
2115 hr
= IXmlWriter_WriteDocType(writer
, L
"-a", NULL
, NULL
, NULL
);
2116 ok(hr
== WC_E_NAMECHARACTER
, "Unexpected hr %#lx.\n", hr
);
2118 /* Pubid validation. */
2119 hr
= IXmlWriter_WriteDocType(writer
, L
"a", pubidW
, NULL
, NULL
);
2120 ok(hr
== WC_E_PUBLICID
, "Unexpected hr %#lx.\n", hr
);
2122 IStream_Release(stream
);
2124 for (i
= 0; i
< ARRAY_SIZE(doctype_tests
); i
++)
2126 stream
= writer_set_output(writer
);
2128 hr
= IXmlWriter_WriteDocType(writer
, doctype_tests
[i
].name
, doctype_tests
[i
].pubid
, doctype_tests
[i
].sysid
,
2129 doctype_tests
[i
].subset
);
2130 ok(hr
== S_OK
, "%u: failed to write doctype, hr %#lx.\n", i
, hr
);
2132 hr
= IXmlWriter_Flush(writer
);
2133 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2135 CHECK_OUTPUT(stream
, doctype_tests
[i
].output
);
2137 hr
= IXmlWriter_WriteDocType(writer
, doctype_tests
[i
].name
, doctype_tests
[i
].pubid
, doctype_tests
[i
].sysid
,
2138 doctype_tests
[i
].subset
);
2139 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
2141 IStream_Release(stream
);
2144 IXmlWriter_Release(writer
);
2147 static void test_WriteWhitespace(void)
2153 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2154 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2156 stream
= writer_set_output(writer
);
2158 hr
= IXmlWriter_WriteWhitespace(writer
, L
" ");
2159 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2160 hr
= IXmlWriter_WriteWhitespace(writer
, L
"ab");
2161 ok(hr
== WR_E_NONWHITESPACE
, "Unexpected hr %#lx.\n", hr
);
2162 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2163 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2164 hr
= IXmlWriter_WriteWhitespace(writer
, L
"\t");
2165 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2167 hr
= IXmlWriter_Flush(writer
);
2168 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2169 CHECK_OUTPUT(stream
, " <w>\t");
2170 IStream_Release(stream
);
2172 IXmlWriter_Release(writer
);
2175 static void test_WriteProcessingInstruction(void)
2181 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2182 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2184 stream
= writer_set_output(writer
);
2186 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2187 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2188 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"pi", L
"content");
2189 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2191 hr
= IXmlWriter_Flush(writer
);
2192 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2193 CHECK_OUTPUT(stream
, "<w><?pi content?>");
2194 IStream_Release(stream
);
2196 IXmlWriter_Release(writer
);
2199 static void test_WriteAttributes(void)
2201 XmlNodeType node_type
;
2208 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2209 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2211 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2212 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2214 /* No attributes. */
2215 reader_set_input(reader
, "<a/>");
2216 stream
= writer_set_output(writer
);
2217 hr
= IXmlWriter_WriteAttributes(writer
, reader
, FALSE
);
2218 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
2219 hr
= IXmlReader_Read(reader
, NULL
);
2220 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2221 hr
= IXmlWriter_WriteAttributes(writer
, reader
, FALSE
);
2222 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2223 hr
= IXmlWriter_Flush(writer
);
2224 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2225 CHECK_OUTPUT(stream
, "");
2226 IStream_Release(stream
);
2228 /* Position on element with attributes. */
2229 reader_set_input(reader
, "<a attr1=\'b\' attr2=\'c\' attr3=\'d\' />");
2230 stream
= writer_set_output(writer
);
2231 hr
= IXmlReader_Read(reader
, NULL
);
2232 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2233 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2234 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2235 hr
= IXmlWriter_WriteAttributes(writer
, reader
, FALSE
);
2236 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2237 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2238 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2239 ok(node_type
== XmlNodeType_Element
, "Unexpected node type %d.\n", node_type
);
2240 hr
= IXmlWriter_Flush(writer
);
2241 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2242 CHECK_OUTPUT(stream
, "<w attr1=\"b\" attr2=\"c\" attr3=\"d\"");
2243 IStream_Release(stream
);
2245 /* Position on second attribute. */
2246 hr
= IXmlReader_MoveToAttributeByName(reader
, L
"attr2", NULL
);
2247 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2248 stream
= writer_set_output(writer
);
2249 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2250 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2251 hr
= IXmlWriter_WriteAttributes(writer
, reader
, FALSE
);
2252 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2253 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2254 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2255 ok(node_type
== XmlNodeType_Attribute
, "Unexpected node type %d.\n", node_type
);
2256 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2257 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2258 ok(!wcscmp(name
, L
"attr3"), "Unexpected node %s.\n", debugstr_w(name
));
2259 hr
= IXmlWriter_Flush(writer
);
2260 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2261 CHECK_OUTPUT(stream
, "<w attr2=\"c\" attr3=\"d\"");
2262 IStream_Release(stream
);
2264 IXmlWriter_Release(writer
);
2265 IXmlReader_Release(reader
);
2268 static void test_WriteNode(void)
2274 XmlNodeType node_type
;
2276 write_node_tests
[] =
2278 { "<r><!-- comment --></r>", "<w><!-- comment -->", XmlNodeType_Comment
},
2279 { "<r>text</r>", "<w>text", XmlNodeType_Text
},
2280 { "<r> </r>", "<w> ", XmlNodeType_Whitespace
},
2281 { "<r><![CDATA[ cdata ]]></r>", "<w><![CDATA[ cdata ]]>", XmlNodeType_CDATA
},
2282 { "<r><?pi pidata ?></r>", "<w><?pi pidata ?>", XmlNodeType_ProcessingInstruction
},
2283 { "<r><e1><e2 attr1=\'a\'/></e1></r>", "<w><e1><e2 attr1=\"a\" /></e1>", XmlNodeType_Element
},
2284 { "<r><e1/></r>", "<w><e1 />", XmlNodeType_Element
},
2285 { "<r></r>", "<w></w>", XmlNodeType_EndElement
},
2287 XmlNodeType node_type
;
2295 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2296 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2298 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2299 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2301 for (i
= 0; i
< ARRAY_SIZE(write_node_tests
); ++i
)
2303 winetest_push_context("Test %s", debugstr_a(write_node_tests
[i
].input
));
2305 stream
= writer_set_output(writer
);
2306 reader_set_input(reader
, write_node_tests
[i
].input
);
2308 /* Skip top level element. */
2309 hr
= IXmlReader_Read(reader
, &node_type
);
2310 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2312 hr
= IXmlReader_Read(reader
, &node_type
);
2313 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2314 ok(node_type
== write_node_tests
[i
].node_type
, "Unexpected node type %d.\n", node_type
);
2316 /* Always write a root node to give a valid context for following nodes. */
2317 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2318 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2319 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2320 ok(SUCCEEDED(hr
), "Failed to write a node, hr %#lx.\n", hr
);
2324 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2325 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2326 ok(node_type
== XmlNodeType_EndElement
, "Unexpected node type on return %d.\n", node_type
);
2327 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2328 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2329 ok(!wcscmp(name
, L
"r"), "Unexpected node name %s.\n", debugstr_w(name
));
2332 hr
= IXmlWriter_Flush(writer
);
2333 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2335 CHECK_OUTPUT(stream
, write_node_tests
[i
].output
);
2337 IStream_Release(stream
);
2339 winetest_pop_context();
2342 /* Current node is an attribute. */
2343 reader_set_input(reader
, "<a attr=\'b\' ></a>");
2344 hr
= IXmlReader_Read(reader
, &node_type
);
2345 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2346 ok(node_type
== XmlNodeType_Element
, "Unexpected node type on return %d.\n", node_type
);
2347 hr
= IXmlReader_MoveToFirstAttribute(reader
);
2348 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2350 stream
= writer_set_output(writer
);
2351 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2352 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2353 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2354 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2355 ok(node_type
== XmlNodeType_EndElement
, "Unexpected node type on return %d.\n", node_type
);
2356 hr
= IXmlWriter_Flush(writer
);
2357 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2358 CHECK_OUTPUT(stream
, "");
2359 IStream_Release(stream
);
2361 /* Xml declaration node. */
2362 reader_set_input(reader
, "<?xml version=\"1.0\" ?><a/>");
2363 hr
= IXmlReader_Read(reader
, &node_type
);
2364 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2365 ok(node_type
== XmlNodeType_XmlDeclaration
, "Unexpected node type on return %d.\n", node_type
);
2367 stream
= writer_set_output(writer
);
2368 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2369 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2370 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2371 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2372 ok(node_type
== XmlNodeType_Element
, "Unexpected node type on return %d.\n", node_type
);
2373 hr
= IXmlWriter_Flush(writer
);
2374 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2375 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
2376 IStream_Release(stream
);
2378 /* With standalone attribute. */
2379 reader_set_input(reader
, "<?xml version=\"1.0\" standalone=\'yes\'?><a/>");
2380 hr
= IXmlReader_Read(reader
, &node_type
);
2381 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2382 ok(node_type
== XmlNodeType_XmlDeclaration
, "Unexpected node type on return %d.\n", node_type
);
2384 stream
= writer_set_output(writer
);
2385 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2386 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2387 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2388 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2389 ok(node_type
== XmlNodeType_Element
, "Unexpected node type on return %d.\n", node_type
);
2390 hr
= IXmlWriter_Flush(writer
);
2391 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2392 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
2393 IStream_Release(stream
);
2395 /* Initial state. */
2396 reader_set_input(reader
, "<?xml version=\"1.0\" ?><a><b/></a>");
2397 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2398 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2399 ok(node_type
== XmlNodeType_None
, "Unexpected node type on return %d.\n", node_type
);
2400 stream
= writer_set_output(writer
);
2401 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2402 ok(hr
== S_FALSE
, "Failed to write a node, hr %#lx.\n", hr
);
2403 node_type
= XmlNodeType_Element
;
2404 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2406 ok(hr
== S_FALSE
, "Unexpected hr %#lx.\n", hr
);
2407 ok(node_type
== XmlNodeType_None
, "Unexpected node type on return %d.\n", node_type
);
2408 hr
= IXmlWriter_Flush(writer
);
2409 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2410 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a><b /></a>");
2411 IStream_Release(stream
);
2413 IXmlReader_Release(reader
);
2414 IXmlWriter_Release(writer
);
2417 static void test_WriteNodeShallow(void)
2423 XmlNodeType node_type
;
2425 write_node_tests
[] =
2427 { "<r><!-- comment --></r>", "<w><!-- comment -->", XmlNodeType_Comment
},
2428 { "<r>text</r>", "<w>text", XmlNodeType_Text
},
2429 { "<r> </r>", "<w> ", XmlNodeType_Whitespace
},
2430 { "<r><![CDATA[ cdata ]]></r>", "<w><![CDATA[ cdata ]]>", XmlNodeType_CDATA
},
2431 { "<r><?pi pidata ?></r>", "<w><?pi pidata ?>", XmlNodeType_ProcessingInstruction
},
2432 { "<r><e1><e2 attr1=\'a\'/></e1></r>", "<w><e1", XmlNodeType_Element
},
2433 { "<r><e1/></r>", "<w><e1 />", XmlNodeType_Element
},
2434 { "<r><e1 attr1=\'a\'/></r>", "<w><e1 attr1=\"a\" />", XmlNodeType_Element
},
2435 { "<r><e1 attr1=\'a\'></e1></r>", "<w><e1 attr1=\"a\"", XmlNodeType_Element
},
2436 { "<r></r>", "<w></w>", XmlNodeType_EndElement
},
2438 XmlNodeType node_type
;
2445 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2446 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2448 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2449 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2451 for (i
= 0; i
< ARRAY_SIZE(write_node_tests
); ++i
)
2453 winetest_push_context("Test %s", debugstr_a(write_node_tests
[i
].input
));
2455 stream
= writer_set_output(writer
);
2456 reader_set_input(reader
, write_node_tests
[i
].input
);
2458 /* Skip top level element. */
2459 hr
= IXmlReader_Read(reader
, &node_type
);
2460 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2462 hr
= IXmlReader_Read(reader
, &node_type
);
2463 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2464 ok(node_type
== write_node_tests
[i
].node_type
, "Unexpected node type %d.\n", node_type
);
2466 /* Always write a root node to give a valid context for following nodes. */
2467 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2468 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2469 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2470 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2472 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2473 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2474 ok(node_type
== write_node_tests
[i
].node_type
, "Unexpected node type on return %d.\n", node_type
);
2476 hr
= IXmlWriter_Flush(writer
);
2477 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2479 CHECK_OUTPUT(stream
, write_node_tests
[i
].output
);
2481 IStream_Release(stream
);
2483 winetest_pop_context();
2486 /* Current node is an attribute. */
2487 reader_set_input(reader
, "<a attr=\'b\' ></a>");
2488 hr
= IXmlReader_Read(reader
, &node_type
);
2489 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2490 ok(node_type
== XmlNodeType_Element
, "Unexpected node type on return %d.\n", node_type
);
2491 hr
= IXmlReader_MoveToFirstAttribute(reader
);
2492 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2494 stream
= writer_set_output(writer
);
2495 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2496 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2497 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2498 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2499 ok(node_type
== XmlNodeType_Attribute
, "Unexpected node type on return %d.\n", node_type
);
2500 hr
= IXmlWriter_Flush(writer
);
2501 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2502 CHECK_OUTPUT(stream
, "");
2503 IStream_Release(stream
);
2505 /* Xml declaration node. */
2506 reader_set_input(reader
, "<?xml version=\"1.0\" ?><a/>");
2507 hr
= IXmlReader_Read(reader
, &node_type
);
2508 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2509 ok(node_type
== XmlNodeType_XmlDeclaration
, "Unexpected node type on return %d.\n", node_type
);
2511 stream
= writer_set_output(writer
);
2512 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2513 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2514 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2515 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2516 ok(node_type
== XmlNodeType_Attribute
, "Unexpected node type on return %d.\n", node_type
);
2517 hr
= IXmlWriter_Flush(writer
);
2518 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2519 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
2520 IStream_Release(stream
);
2522 /* With standalone attribute. */
2523 reader_set_input(reader
, "<?xml version=\"1.0\" standalone=\'yes\'?><a/>");
2524 hr
= IXmlReader_Read(reader
, &node_type
);
2525 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2526 ok(node_type
== XmlNodeType_XmlDeclaration
, "Unexpected node type on return %d.\n", node_type
);
2528 stream
= writer_set_output(writer
);
2529 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2530 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2531 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2532 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2533 ok(node_type
== XmlNodeType_Attribute
, "Unexpected node type on return %d.\n", node_type
);
2534 hr
= IXmlWriter_Flush(writer
);
2535 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2536 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
2537 IStream_Release(stream
);
2539 /* Initial state. */
2540 reader_set_input(reader
, "<?xml version=\"1.0\" ?><a><b/></a>");
2541 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2542 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2543 ok(node_type
== XmlNodeType_None
, "Unexpected node type on return %d.\n", node_type
);
2544 stream
= writer_set_output(writer
);
2545 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2546 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2547 node_type
= XmlNodeType_Element
;
2548 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2549 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2550 ok(node_type
== XmlNodeType_None
, "Unexpected node type on return %d.\n", node_type
);
2551 hr
= IXmlWriter_Flush(writer
);
2552 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2553 CHECK_OUTPUT(stream
, "");
2554 IStream_Release(stream
);
2556 IXmlReader_Release(reader
);
2557 IXmlWriter_Release(writer
);
2562 test_writer_create();
2563 test_writer_state();
2564 test_writeroutput();
2565 test_writestartdocument();
2566 test_WriteStartElement();
2567 test_WriteElementString();
2568 test_WriteEndElement();
2570 test_omitxmldeclaration();
2572 test_writeenddocument();
2573 test_WriteComment();
2577 test_WriteAttributeString();
2578 test_WriteFullEndElement();
2579 test_WriteCharEntity();
2581 test_WriteDocType();
2582 test_WriteWhitespace();
2583 test_WriteProcessingInstruction();
2584 test_WriteAttributes();
2586 test_WriteNodeShallow();